1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_DOWNLOADS_DOWNLOADS_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_DOWNLOADS_DOWNLOADS_API_H_
11 #include "base/files/file_path.h"
12 #include "base/scoped_observer.h"
13 #include "chrome/browser/download/all_download_item_notifier.h"
14 #include "chrome/browser/download/download_danger_prompt.h"
15 #include "chrome/browser/download/download_path_reservation_tracker.h"
16 #include "chrome/browser/extensions/chrome_extension_function.h"
17 #include "chrome/browser/extensions/extension_warning_set.h"
18 #include "chrome/common/extensions/api/downloads.h"
19 #include "content/public/browser/download_manager.h"
20 #include "extensions/browser/event_router.h"
21 #include "extensions/browser/extension_registry_observer.h"
23 class DownloadFileIconExtractor;
27 class ResourceContext;
28 class ResourceDispatcherHost;
31 namespace extensions {
32 class ExtensionRegistry;
35 // Functions in the chrome.downloads namespace facilitate
36 // controlling downloads from extensions. See the full API doc at
37 // http://goo.gl/6hO1n
39 namespace download_extension_errors {
41 // Errors that can be returned through chrome.runtime.lastError.message.
42 extern const char kEmptyFile[];
43 extern const char kFileAlreadyDeleted[];
44 extern const char kFileNotRemoved[];
45 extern const char kIconNotFound[];
46 extern const char kInvalidDangerType[];
47 extern const char kInvalidFilename[];
48 extern const char kInvalidFilter[];
49 extern const char kInvalidHeader[];
50 extern const char kInvalidId[];
51 extern const char kInvalidOrderBy[];
52 extern const char kInvalidQueryLimit[];
53 extern const char kInvalidState[];
54 extern const char kInvalidURL[];
55 extern const char kInvisibleContext[];
56 extern const char kNotComplete[];
57 extern const char kNotDangerous[];
58 extern const char kNotInProgress[];
59 extern const char kNotResumable[];
60 extern const char kOpenPermission[];
61 extern const char kShelfDisabled[];
62 extern const char kShelfPermission[];
63 extern const char kTooManyListeners[];
64 extern const char kUnexpectedDeterminer[];
65 extern const char kUserGesture[];
67 } // namespace download_extension_errors
69 namespace extensions {
71 class DownloadedByExtension : public base::SupportsUserData::Data {
73 static DownloadedByExtension* Get(content::DownloadItem* item);
75 DownloadedByExtension(content::DownloadItem* item,
76 const std::string& id,
77 const std::string& name);
79 const std::string& id() const { return id_; }
80 const std::string& name() const { return name_; }
83 static const char kKey[];
88 DISALLOW_COPY_AND_ASSIGN(DownloadedByExtension);
91 class DownloadsDownloadFunction : public ChromeAsyncExtensionFunction {
93 DECLARE_EXTENSION_FUNCTION("downloads.download", DOWNLOADS_DOWNLOAD)
94 DownloadsDownloadFunction();
95 virtual bool RunAsync() OVERRIDE;
98 virtual ~DownloadsDownloadFunction();
101 void OnStarted(const base::FilePath& creator_suggested_filename,
102 extensions::api::downloads::FilenameConflictAction
103 creator_conflict_action,
104 content::DownloadItem* item,
105 content::DownloadInterruptReason interrupt_reason);
107 DISALLOW_COPY_AND_ASSIGN(DownloadsDownloadFunction);
110 class DownloadsSearchFunction : public ChromeSyncExtensionFunction {
112 DECLARE_EXTENSION_FUNCTION("downloads.search", DOWNLOADS_SEARCH)
113 DownloadsSearchFunction();
114 virtual bool RunSync() OVERRIDE;
117 virtual ~DownloadsSearchFunction();
120 DISALLOW_COPY_AND_ASSIGN(DownloadsSearchFunction);
123 class DownloadsPauseFunction : public ChromeSyncExtensionFunction {
125 DECLARE_EXTENSION_FUNCTION("downloads.pause", DOWNLOADS_PAUSE)
126 DownloadsPauseFunction();
127 virtual bool RunSync() OVERRIDE;
130 virtual ~DownloadsPauseFunction();
133 DISALLOW_COPY_AND_ASSIGN(DownloadsPauseFunction);
136 class DownloadsResumeFunction : public ChromeSyncExtensionFunction {
138 DECLARE_EXTENSION_FUNCTION("downloads.resume", DOWNLOADS_RESUME)
139 DownloadsResumeFunction();
140 virtual bool RunSync() OVERRIDE;
143 virtual ~DownloadsResumeFunction();
146 DISALLOW_COPY_AND_ASSIGN(DownloadsResumeFunction);
149 class DownloadsCancelFunction : public ChromeSyncExtensionFunction {
151 DECLARE_EXTENSION_FUNCTION("downloads.cancel", DOWNLOADS_CANCEL)
152 DownloadsCancelFunction();
153 virtual bool RunSync() OVERRIDE;
156 virtual ~DownloadsCancelFunction();
159 DISALLOW_COPY_AND_ASSIGN(DownloadsCancelFunction);
162 class DownloadsEraseFunction : public ChromeSyncExtensionFunction {
164 DECLARE_EXTENSION_FUNCTION("downloads.erase", DOWNLOADS_ERASE)
165 DownloadsEraseFunction();
166 virtual bool RunSync() OVERRIDE;
169 virtual ~DownloadsEraseFunction();
172 DISALLOW_COPY_AND_ASSIGN(DownloadsEraseFunction);
175 class DownloadsRemoveFileFunction : public ChromeAsyncExtensionFunction {
177 DECLARE_EXTENSION_FUNCTION("downloads.removeFile", DOWNLOADS_REMOVEFILE)
178 DownloadsRemoveFileFunction();
179 virtual bool RunAsync() OVERRIDE;
182 virtual ~DownloadsRemoveFileFunction();
185 void Done(bool success);
187 DISALLOW_COPY_AND_ASSIGN(DownloadsRemoveFileFunction);
190 class DownloadsAcceptDangerFunction : public ChromeAsyncExtensionFunction {
192 typedef base::Callback<void(DownloadDangerPrompt*)> OnPromptCreatedCallback;
193 static void OnPromptCreatedForTesting(
194 OnPromptCreatedCallback* callback) {
195 on_prompt_created_ = callback;
198 DECLARE_EXTENSION_FUNCTION("downloads.acceptDanger", DOWNLOADS_ACCEPTDANGER)
199 DownloadsAcceptDangerFunction();
200 virtual bool RunAsync() OVERRIDE;
203 virtual ~DownloadsAcceptDangerFunction();
204 void DangerPromptCallback(int download_id,
205 DownloadDangerPrompt::Action action);
208 void PromptOrWait(int download_id, int retries);
210 static OnPromptCreatedCallback* on_prompt_created_;
211 DISALLOW_COPY_AND_ASSIGN(DownloadsAcceptDangerFunction);
214 class DownloadsShowFunction : public ChromeAsyncExtensionFunction {
216 DECLARE_EXTENSION_FUNCTION("downloads.show", DOWNLOADS_SHOW)
217 DownloadsShowFunction();
218 virtual bool RunAsync() OVERRIDE;
221 virtual ~DownloadsShowFunction();
224 DISALLOW_COPY_AND_ASSIGN(DownloadsShowFunction);
227 class DownloadsShowDefaultFolderFunction : public ChromeAsyncExtensionFunction {
229 DECLARE_EXTENSION_FUNCTION(
230 "downloads.showDefaultFolder", DOWNLOADS_SHOWDEFAULTFOLDER)
231 DownloadsShowDefaultFolderFunction();
232 virtual bool RunAsync() OVERRIDE;
235 virtual ~DownloadsShowDefaultFolderFunction();
238 DISALLOW_COPY_AND_ASSIGN(DownloadsShowDefaultFolderFunction);
241 class DownloadsOpenFunction : public ChromeSyncExtensionFunction {
243 DECLARE_EXTENSION_FUNCTION("downloads.open", DOWNLOADS_OPEN)
244 DownloadsOpenFunction();
245 virtual bool RunSync() OVERRIDE;
248 virtual ~DownloadsOpenFunction();
251 DISALLOW_COPY_AND_ASSIGN(DownloadsOpenFunction);
254 class DownloadsSetShelfEnabledFunction : public ChromeSyncExtensionFunction {
256 DECLARE_EXTENSION_FUNCTION("downloads.setShelfEnabled",
257 DOWNLOADS_SETSHELFENABLED)
258 DownloadsSetShelfEnabledFunction();
259 virtual bool RunSync() OVERRIDE;
262 virtual ~DownloadsSetShelfEnabledFunction();
265 DISALLOW_COPY_AND_ASSIGN(DownloadsSetShelfEnabledFunction);
268 class DownloadsDragFunction : public ChromeAsyncExtensionFunction {
270 DECLARE_EXTENSION_FUNCTION("downloads.drag", DOWNLOADS_DRAG)
271 DownloadsDragFunction();
272 virtual bool RunAsync() OVERRIDE;
275 virtual ~DownloadsDragFunction();
278 DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction);
281 class DownloadsGetFileIconFunction : public ChromeAsyncExtensionFunction {
283 DECLARE_EXTENSION_FUNCTION("downloads.getFileIcon", DOWNLOADS_GETFILEICON)
284 DownloadsGetFileIconFunction();
285 virtual bool RunAsync() OVERRIDE;
286 void SetIconExtractorForTesting(DownloadFileIconExtractor* extractor);
289 virtual ~DownloadsGetFileIconFunction();
292 void OnIconURLExtracted(const std::string& url);
293 base::FilePath path_;
294 scoped_ptr<DownloadFileIconExtractor> icon_extractor_;
295 DISALLOW_COPY_AND_ASSIGN(DownloadsGetFileIconFunction);
298 // Observes a single DownloadManager and many DownloadItems and dispatches
299 // onCreated and onErased events.
300 class ExtensionDownloadsEventRouter
301 : public extensions::EventRouter::Observer,
302 public extensions::ExtensionRegistryObserver,
303 public AllDownloadItemNotifier::Observer {
305 typedef base::Callback<void(
306 const base::FilePath& changed_filename,
307 DownloadPathReservationTracker::FilenameConflictAction)>
308 FilenameChangedCallback;
310 static void SetDetermineFilenameTimeoutSecondsForTesting(int s);
312 // The logic for how to handle conflicting filename suggestions from multiple
313 // extensions is split out here for testing.
314 static void DetermineFilenameInternal(
315 const base::FilePath& filename,
316 extensions::api::downloads::FilenameConflictAction conflict_action,
317 const std::string& suggesting_extension_id,
318 const base::Time& suggesting_install_time,
319 const std::string& incumbent_extension_id,
320 const base::Time& incumbent_install_time,
321 std::string* winner_extension_id,
322 base::FilePath* determined_filename,
323 extensions::api::downloads::FilenameConflictAction*
324 determined_conflict_action,
325 extensions::ExtensionWarningSet* warnings);
327 // A downloads.onDeterminingFilename listener has returned. If the extension
328 // wishes to override the download's filename, then |filename| will be
329 // non-empty. |filename| will be interpreted as a relative path, appended to
330 // the default downloads directory. If the extension wishes to overwrite any
331 // existing files, then |overwrite| will be true. Returns true on success,
333 static bool DetermineFilename(
335 bool include_incognito,
336 const std::string& ext_id,
338 const base::FilePath& filename,
339 extensions::api::downloads::FilenameConflictAction conflict_action,
342 explicit ExtensionDownloadsEventRouter(
343 Profile* profile, content::DownloadManager* manager);
344 virtual ~ExtensionDownloadsEventRouter();
346 void SetShelfEnabled(const extensions::Extension* extension, bool enabled);
347 bool IsShelfEnabled() const;
349 // Called by ChromeDownloadManagerDelegate during the filename determination
350 // process, allows extensions to change the item's target filename. If no
351 // extension wants to change the target filename, then |no_change| will be
352 // called and the filename determination process will continue as normal. If
353 // an extension wants to change the target filename, then |change| will be
354 // called with the new filename and a flag indicating whether the new file
355 // should overwrite any old files of the same name.
356 void OnDeterminingFilename(
357 content::DownloadItem* item,
358 const base::FilePath& suggested_path,
359 const base::Closure& no_change,
360 const FilenameChangedCallback& change);
362 // AllDownloadItemNotifier::Observer.
363 virtual void OnDownloadCreated(
364 content::DownloadManager* manager,
365 content::DownloadItem* download_item) OVERRIDE;
366 virtual void OnDownloadUpdated(
367 content::DownloadManager* manager,
368 content::DownloadItem* download_item) OVERRIDE;
369 virtual void OnDownloadRemoved(
370 content::DownloadManager* manager,
371 content::DownloadItem* download_item) OVERRIDE;
373 // extensions::EventRouter::Observer.
374 virtual void OnListenerRemoved(
375 const extensions::EventListenerInfo& details) OVERRIDE;
378 struct DownloadsNotificationSource {
379 std::string event_name;
385 const std::string& event_name,
386 bool include_incognito,
387 const extensions::Event::WillDispatchCallback& will_dispatch_callback,
388 base::Value* json_arg);
390 // extensions::ExtensionRegistryObserver.
391 virtual void OnExtensionUnloaded(
392 content::BrowserContext* browser_context,
393 const extensions::Extension* extension,
394 extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
397 AllDownloadItemNotifier notifier_;
398 std::set<const extensions::Extension*> shelf_disabling_extensions_;
400 // Listen to extension unloaded notifications.
401 ScopedObserver<extensions::ExtensionRegistry,
402 extensions::ExtensionRegistryObserver>
403 extension_registry_observer_;
405 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouter);
408 } // namespace extensions
410 #endif // CHROME_BROWSER_EXTENSIONS_API_DOWNLOADS_DOWNLOADS_API_H_