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 "base/time/time.h"
14 #include "chrome/browser/download/all_download_item_notifier.h"
15 #include "chrome/browser/download/download_danger_prompt.h"
16 #include "chrome/browser/download/download_path_reservation_tracker.h"
17 #include "chrome/browser/extensions/chrome_extension_function.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"
22 #include "extensions/browser/warning_set.h"
24 class DownloadFileIconExtractor
;
28 class ResourceContext
;
29 class ResourceDispatcherHost
;
32 namespace extensions
{
33 class ExtensionRegistry
;
36 // Functions in the chrome.downloads namespace facilitate
37 // controlling downloads from extensions. See the full API doc at
38 // http://goo.gl/6hO1n
40 namespace download_extension_errors
{
42 // Errors that can be returned through chrome.runtime.lastError.message.
43 extern const char kEmptyFile
[];
44 extern const char kFileAlreadyDeleted
[];
45 extern const char kFileNotRemoved
[];
46 extern const char kIconNotFound
[];
47 extern const char kInvalidDangerType
[];
48 extern const char kInvalidFilename
[];
49 extern const char kInvalidFilter
[];
50 extern const char kInvalidHeaderName
[];
51 extern const char kInvalidHeaderValue
[];
52 extern const char kInvalidHeaderUnsafe
[];
53 extern const char kInvalidId
[];
54 extern const char kInvalidOrderBy
[];
55 extern const char kInvalidQueryLimit
[];
56 extern const char kInvalidState
[];
57 extern const char kInvalidURL
[];
58 extern const char kInvisibleContext
[];
59 extern const char kNotComplete
[];
60 extern const char kNotDangerous
[];
61 extern const char kNotInProgress
[];
62 extern const char kNotResumable
[];
63 extern const char kOpenPermission
[];
64 extern const char kShelfDisabled
[];
65 extern const char kShelfPermission
[];
66 extern const char kTooManyListeners
[];
67 extern const char kUnexpectedDeterminer
[];
68 extern const char kUserGesture
[];
70 } // namespace download_extension_errors
72 namespace extensions
{
74 class DownloadedByExtension
: public base::SupportsUserData::Data
{
76 static DownloadedByExtension
* Get(content::DownloadItem
* item
);
78 DownloadedByExtension(content::DownloadItem
* item
,
79 const std::string
& id
,
80 const std::string
& name
);
82 const std::string
& id() const { return id_
; }
83 const std::string
& name() const { return name_
; }
86 static const char kKey
[];
91 DISALLOW_COPY_AND_ASSIGN(DownloadedByExtension
);
94 class DownloadsDownloadFunction
: public ChromeAsyncExtensionFunction
{
96 DECLARE_EXTENSION_FUNCTION("downloads.download", DOWNLOADS_DOWNLOAD
)
97 DownloadsDownloadFunction();
98 bool RunAsync() override
;
101 ~DownloadsDownloadFunction() override
;
104 void OnStarted(const base::FilePath
& creator_suggested_filename
,
105 extensions::api::downloads::FilenameConflictAction
106 creator_conflict_action
,
107 content::DownloadItem
* item
,
108 content::DownloadInterruptReason interrupt_reason
);
110 DISALLOW_COPY_AND_ASSIGN(DownloadsDownloadFunction
);
113 class DownloadsSearchFunction
: public ChromeSyncExtensionFunction
{
115 DECLARE_EXTENSION_FUNCTION("downloads.search", DOWNLOADS_SEARCH
)
116 DownloadsSearchFunction();
117 bool RunSync() override
;
120 ~DownloadsSearchFunction() override
;
123 DISALLOW_COPY_AND_ASSIGN(DownloadsSearchFunction
);
126 class DownloadsPauseFunction
: public ChromeSyncExtensionFunction
{
128 DECLARE_EXTENSION_FUNCTION("downloads.pause", DOWNLOADS_PAUSE
)
129 DownloadsPauseFunction();
130 bool RunSync() override
;
133 ~DownloadsPauseFunction() override
;
136 DISALLOW_COPY_AND_ASSIGN(DownloadsPauseFunction
);
139 class DownloadsResumeFunction
: public ChromeSyncExtensionFunction
{
141 DECLARE_EXTENSION_FUNCTION("downloads.resume", DOWNLOADS_RESUME
)
142 DownloadsResumeFunction();
143 bool RunSync() override
;
146 ~DownloadsResumeFunction() override
;
149 DISALLOW_COPY_AND_ASSIGN(DownloadsResumeFunction
);
152 class DownloadsCancelFunction
: public ChromeSyncExtensionFunction
{
154 DECLARE_EXTENSION_FUNCTION("downloads.cancel", DOWNLOADS_CANCEL
)
155 DownloadsCancelFunction();
156 bool RunSync() override
;
159 ~DownloadsCancelFunction() override
;
162 DISALLOW_COPY_AND_ASSIGN(DownloadsCancelFunction
);
165 class DownloadsEraseFunction
: public ChromeSyncExtensionFunction
{
167 DECLARE_EXTENSION_FUNCTION("downloads.erase", DOWNLOADS_ERASE
)
168 DownloadsEraseFunction();
169 bool RunSync() override
;
172 ~DownloadsEraseFunction() override
;
175 DISALLOW_COPY_AND_ASSIGN(DownloadsEraseFunction
);
178 class DownloadsRemoveFileFunction
: public ChromeAsyncExtensionFunction
{
180 DECLARE_EXTENSION_FUNCTION("downloads.removeFile", DOWNLOADS_REMOVEFILE
)
181 DownloadsRemoveFileFunction();
182 bool RunAsync() override
;
185 ~DownloadsRemoveFileFunction() override
;
188 void Done(bool success
);
190 DISALLOW_COPY_AND_ASSIGN(DownloadsRemoveFileFunction
);
193 class DownloadsAcceptDangerFunction
: public ChromeAsyncExtensionFunction
{
195 typedef base::Callback
<void(DownloadDangerPrompt
*)> OnPromptCreatedCallback
;
196 static void OnPromptCreatedForTesting(
197 OnPromptCreatedCallback
* callback
) {
198 on_prompt_created_
= callback
;
201 DECLARE_EXTENSION_FUNCTION("downloads.acceptDanger", DOWNLOADS_ACCEPTDANGER
)
202 DownloadsAcceptDangerFunction();
203 bool RunAsync() override
;
206 ~DownloadsAcceptDangerFunction() override
;
207 void DangerPromptCallback(int download_id
,
208 DownloadDangerPrompt::Action action
);
211 void PromptOrWait(int download_id
, int retries
);
213 static OnPromptCreatedCallback
* on_prompt_created_
;
214 DISALLOW_COPY_AND_ASSIGN(DownloadsAcceptDangerFunction
);
217 class DownloadsShowFunction
: public ChromeAsyncExtensionFunction
{
219 DECLARE_EXTENSION_FUNCTION("downloads.show", DOWNLOADS_SHOW
)
220 DownloadsShowFunction();
221 bool RunAsync() override
;
224 ~DownloadsShowFunction() override
;
227 DISALLOW_COPY_AND_ASSIGN(DownloadsShowFunction
);
230 class DownloadsShowDefaultFolderFunction
: public ChromeAsyncExtensionFunction
{
232 DECLARE_EXTENSION_FUNCTION(
233 "downloads.showDefaultFolder", DOWNLOADS_SHOWDEFAULTFOLDER
)
234 DownloadsShowDefaultFolderFunction();
235 bool RunAsync() override
;
238 ~DownloadsShowDefaultFolderFunction() override
;
241 DISALLOW_COPY_AND_ASSIGN(DownloadsShowDefaultFolderFunction
);
244 class DownloadsOpenFunction
: public ChromeSyncExtensionFunction
{
246 DECLARE_EXTENSION_FUNCTION("downloads.open", DOWNLOADS_OPEN
)
247 DownloadsOpenFunction();
248 bool RunSync() override
;
251 ~DownloadsOpenFunction() override
;
254 DISALLOW_COPY_AND_ASSIGN(DownloadsOpenFunction
);
257 class DownloadsSetShelfEnabledFunction
: public ChromeSyncExtensionFunction
{
259 DECLARE_EXTENSION_FUNCTION("downloads.setShelfEnabled",
260 DOWNLOADS_SETSHELFENABLED
)
261 DownloadsSetShelfEnabledFunction();
262 bool RunSync() override
;
265 ~DownloadsSetShelfEnabledFunction() override
;
268 DISALLOW_COPY_AND_ASSIGN(DownloadsSetShelfEnabledFunction
);
271 class DownloadsDragFunction
: public ChromeAsyncExtensionFunction
{
273 DECLARE_EXTENSION_FUNCTION("downloads.drag", DOWNLOADS_DRAG
)
274 DownloadsDragFunction();
275 bool RunAsync() override
;
278 ~DownloadsDragFunction() override
;
281 DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction
);
284 class DownloadsGetFileIconFunction
: public ChromeAsyncExtensionFunction
{
286 DECLARE_EXTENSION_FUNCTION("downloads.getFileIcon", DOWNLOADS_GETFILEICON
)
287 DownloadsGetFileIconFunction();
288 bool RunAsync() override
;
289 void SetIconExtractorForTesting(DownloadFileIconExtractor
* extractor
);
292 ~DownloadsGetFileIconFunction() override
;
295 void OnIconURLExtracted(const std::string
& url
);
296 base::FilePath path_
;
297 scoped_ptr
<DownloadFileIconExtractor
> icon_extractor_
;
298 DISALLOW_COPY_AND_ASSIGN(DownloadsGetFileIconFunction
);
301 // Observes a single DownloadManager and many DownloadItems and dispatches
302 // onCreated and onErased events.
303 class ExtensionDownloadsEventRouter
304 : public extensions::EventRouter::Observer
,
305 public extensions::ExtensionRegistryObserver
,
306 public AllDownloadItemNotifier::Observer
{
308 typedef base::Callback
<void(
309 const base::FilePath
& changed_filename
,
310 DownloadPathReservationTracker::FilenameConflictAction
)>
311 FilenameChangedCallback
;
313 static void SetDetermineFilenameTimeoutSecondsForTesting(int s
);
315 // The logic for how to handle conflicting filename suggestions from multiple
316 // extensions is split out here for testing.
317 static void DetermineFilenameInternal(
318 const base::FilePath
& filename
,
319 extensions::api::downloads::FilenameConflictAction conflict_action
,
320 const std::string
& suggesting_extension_id
,
321 const base::Time
& suggesting_install_time
,
322 const std::string
& incumbent_extension_id
,
323 const base::Time
& incumbent_install_time
,
324 std::string
* winner_extension_id
,
325 base::FilePath
* determined_filename
,
326 extensions::api::downloads::FilenameConflictAction
*
327 determined_conflict_action
,
328 extensions::WarningSet
* warnings
);
330 // A downloads.onDeterminingFilename listener has returned. If the extension
331 // wishes to override the download's filename, then |filename| will be
332 // non-empty. |filename| will be interpreted as a relative path, appended to
333 // the default downloads directory. If the extension wishes to overwrite any
334 // existing files, then |overwrite| will be true. Returns true on success,
336 static bool DetermineFilename(
338 bool include_incognito
,
339 const std::string
& ext_id
,
341 const base::FilePath
& filename
,
342 extensions::api::downloads::FilenameConflictAction conflict_action
,
345 explicit ExtensionDownloadsEventRouter(
346 Profile
* profile
, content::DownloadManager
* manager
);
347 ~ExtensionDownloadsEventRouter() override
;
349 void SetShelfEnabled(const extensions::Extension
* extension
, bool enabled
);
350 bool IsShelfEnabled() const;
352 // Called by ChromeDownloadManagerDelegate during the filename determination
353 // process, allows extensions to change the item's target filename. If no
354 // extension wants to change the target filename, then |no_change| will be
355 // called and the filename determination process will continue as normal. If
356 // an extension wants to change the target filename, then |change| will be
357 // called with the new filename and a flag indicating whether the new file
358 // should overwrite any old files of the same name.
359 void OnDeterminingFilename(
360 content::DownloadItem
* item
,
361 const base::FilePath
& suggested_path
,
362 const base::Closure
& no_change
,
363 const FilenameChangedCallback
& change
);
365 // AllDownloadItemNotifier::Observer.
366 void OnDownloadCreated(content::DownloadManager
* manager
,
367 content::DownloadItem
* download_item
) override
;
368 void OnDownloadUpdated(content::DownloadManager
* manager
,
369 content::DownloadItem
* download_item
) override
;
370 void OnDownloadRemoved(content::DownloadManager
* manager
,
371 content::DownloadItem
* download_item
) override
;
373 // extensions::EventRouter::Observer.
374 void OnListenerRemoved(const extensions::EventListenerInfo
& details
) override
;
377 struct DownloadsNotificationSource
{
378 std::string event_name
;
382 void CheckForHistoryFilesRemoval();
386 events::HistogramValue histogram_value
,
387 const std::string
& event_name
,
388 bool include_incognito
,
389 const extensions::Event::WillDispatchCallback
& will_dispatch_callback
,
390 base::Value
* json_arg
);
392 // extensions::ExtensionRegistryObserver.
393 void OnExtensionUnloaded(
394 content::BrowserContext
* browser_context
,
395 const extensions::Extension
* extension
,
396 extensions::UnloadedExtensionInfo::Reason reason
) override
;
399 AllDownloadItemNotifier notifier_
;
400 std::set
<const extensions::Extension
*> shelf_disabling_extensions_
;
402 base::Time last_checked_removal_
;
404 // Listen to extension unloaded notifications.
405 ScopedObserver
<extensions::ExtensionRegistry
,
406 extensions::ExtensionRegistryObserver
>
407 extension_registry_observer_
;
409 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouter
);
412 } // namespace extensions
414 #endif // CHROME_BROWSER_EXTENSIONS_API_DOWNLOADS_DOWNLOADS_API_H_