Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / downloads / downloads_api.h
blob6d514a716826fd43574ed44e1e6ec1423209be6e
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_
8 #include <set>
9 #include <string>
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;
25 class DownloadQuery;
27 namespace content {
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 {
75 public:
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_; }
85 private:
86 static const char kKey[];
88 std::string id_;
89 std::string name_;
91 DISALLOW_COPY_AND_ASSIGN(DownloadedByExtension);
94 class DownloadsDownloadFunction : public ChromeAsyncExtensionFunction {
95 public:
96 DECLARE_EXTENSION_FUNCTION("downloads.download", DOWNLOADS_DOWNLOAD)
97 DownloadsDownloadFunction();
98 bool RunAsync() override;
100 protected:
101 ~DownloadsDownloadFunction() override;
103 private:
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 {
114 public:
115 DECLARE_EXTENSION_FUNCTION("downloads.search", DOWNLOADS_SEARCH)
116 DownloadsSearchFunction();
117 bool RunSync() override;
119 protected:
120 ~DownloadsSearchFunction() override;
122 private:
123 DISALLOW_COPY_AND_ASSIGN(DownloadsSearchFunction);
126 class DownloadsPauseFunction : public ChromeSyncExtensionFunction {
127 public:
128 DECLARE_EXTENSION_FUNCTION("downloads.pause", DOWNLOADS_PAUSE)
129 DownloadsPauseFunction();
130 bool RunSync() override;
132 protected:
133 ~DownloadsPauseFunction() override;
135 private:
136 DISALLOW_COPY_AND_ASSIGN(DownloadsPauseFunction);
139 class DownloadsResumeFunction : public ChromeSyncExtensionFunction {
140 public:
141 DECLARE_EXTENSION_FUNCTION("downloads.resume", DOWNLOADS_RESUME)
142 DownloadsResumeFunction();
143 bool RunSync() override;
145 protected:
146 ~DownloadsResumeFunction() override;
148 private:
149 DISALLOW_COPY_AND_ASSIGN(DownloadsResumeFunction);
152 class DownloadsCancelFunction : public ChromeSyncExtensionFunction {
153 public:
154 DECLARE_EXTENSION_FUNCTION("downloads.cancel", DOWNLOADS_CANCEL)
155 DownloadsCancelFunction();
156 bool RunSync() override;
158 protected:
159 ~DownloadsCancelFunction() override;
161 private:
162 DISALLOW_COPY_AND_ASSIGN(DownloadsCancelFunction);
165 class DownloadsEraseFunction : public ChromeSyncExtensionFunction {
166 public:
167 DECLARE_EXTENSION_FUNCTION("downloads.erase", DOWNLOADS_ERASE)
168 DownloadsEraseFunction();
169 bool RunSync() override;
171 protected:
172 ~DownloadsEraseFunction() override;
174 private:
175 DISALLOW_COPY_AND_ASSIGN(DownloadsEraseFunction);
178 class DownloadsRemoveFileFunction : public ChromeAsyncExtensionFunction {
179 public:
180 DECLARE_EXTENSION_FUNCTION("downloads.removeFile", DOWNLOADS_REMOVEFILE)
181 DownloadsRemoveFileFunction();
182 bool RunAsync() override;
184 protected:
185 ~DownloadsRemoveFileFunction() override;
187 private:
188 void Done(bool success);
190 DISALLOW_COPY_AND_ASSIGN(DownloadsRemoveFileFunction);
193 class DownloadsAcceptDangerFunction : public ChromeAsyncExtensionFunction {
194 public:
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;
205 protected:
206 ~DownloadsAcceptDangerFunction() override;
207 void DangerPromptCallback(int download_id,
208 DownloadDangerPrompt::Action action);
210 private:
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 {
218 public:
219 DECLARE_EXTENSION_FUNCTION("downloads.show", DOWNLOADS_SHOW)
220 DownloadsShowFunction();
221 bool RunAsync() override;
223 protected:
224 ~DownloadsShowFunction() override;
226 private:
227 DISALLOW_COPY_AND_ASSIGN(DownloadsShowFunction);
230 class DownloadsShowDefaultFolderFunction : public ChromeAsyncExtensionFunction {
231 public:
232 DECLARE_EXTENSION_FUNCTION(
233 "downloads.showDefaultFolder", DOWNLOADS_SHOWDEFAULTFOLDER)
234 DownloadsShowDefaultFolderFunction();
235 bool RunAsync() override;
237 protected:
238 ~DownloadsShowDefaultFolderFunction() override;
240 private:
241 DISALLOW_COPY_AND_ASSIGN(DownloadsShowDefaultFolderFunction);
244 class DownloadsOpenFunction : public ChromeSyncExtensionFunction {
245 public:
246 DECLARE_EXTENSION_FUNCTION("downloads.open", DOWNLOADS_OPEN)
247 DownloadsOpenFunction();
248 bool RunSync() override;
250 protected:
251 ~DownloadsOpenFunction() override;
253 private:
254 DISALLOW_COPY_AND_ASSIGN(DownloadsOpenFunction);
257 class DownloadsSetShelfEnabledFunction : public ChromeSyncExtensionFunction {
258 public:
259 DECLARE_EXTENSION_FUNCTION("downloads.setShelfEnabled",
260 DOWNLOADS_SETSHELFENABLED)
261 DownloadsSetShelfEnabledFunction();
262 bool RunSync() override;
264 protected:
265 ~DownloadsSetShelfEnabledFunction() override;
267 private:
268 DISALLOW_COPY_AND_ASSIGN(DownloadsSetShelfEnabledFunction);
271 class DownloadsDragFunction : public ChromeAsyncExtensionFunction {
272 public:
273 DECLARE_EXTENSION_FUNCTION("downloads.drag", DOWNLOADS_DRAG)
274 DownloadsDragFunction();
275 bool RunAsync() override;
277 protected:
278 ~DownloadsDragFunction() override;
280 private:
281 DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction);
284 class DownloadsGetFileIconFunction : public ChromeAsyncExtensionFunction {
285 public:
286 DECLARE_EXTENSION_FUNCTION("downloads.getFileIcon", DOWNLOADS_GETFILEICON)
287 DownloadsGetFileIconFunction();
288 bool RunAsync() override;
289 void SetIconExtractorForTesting(DownloadFileIconExtractor* extractor);
291 protected:
292 ~DownloadsGetFileIconFunction() override;
294 private:
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 {
307 public:
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,
335 // false otherwise.
336 static bool DetermineFilename(
337 Profile* profile,
338 bool include_incognito,
339 const std::string& ext_id,
340 int download_id,
341 const base::FilePath& filename,
342 extensions::api::downloads::FilenameConflictAction conflict_action,
343 std::string* error);
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;
376 // Used for testing.
377 struct DownloadsNotificationSource {
378 std::string event_name;
379 Profile* profile;
382 void CheckForHistoryFilesRemoval();
384 private:
385 void DispatchEvent(
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;
398 Profile* profile_;
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_