15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defines the Chrome Extensions Media Galleries API functions for accessing
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// user's media files, as specified in the extension API IDL.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_MEDIA_GALLERIES_API_H_
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_MEDIA_GALLERIES_API_H_
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/weak_ptr.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_function.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/media_galleries/gallery_watch_manager_observer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/media_galleries/media_file_system_registry.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/media_galleries/media_scan_manager_observer.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/media_galleries.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/media_galleries/metadata_types.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/storage_monitor/media_storage_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "extensions/browser/browser_context_keyed_api_factory.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "extensions/browser/event_router.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace MediaGalleries = extensions::api::media_galleries;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MediaGalleriesScanResultController;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BlobHandle;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebContents;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace metadata {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SafeMediaMetadataParser;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Extension;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The profile-keyed service that manages the media galleries extension API.
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Created at the same time as the Profile. This is also the event router.
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MediaGalleriesEventRouter : public BrowserContextKeyedAPI,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  public GalleryWatchManagerObserver,
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  public MediaScanManagerObserver,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  public extensions::EventRouter::Observer {
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // KeyedService implementation.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Shutdown() OVERRIDE;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BrowserContextKeyedAPI implementation.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static BrowserContextKeyedAPIFactory<MediaGalleriesEventRouter>*
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetFactoryInstance();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convenience method to get the MediaGalleriesAPI for a profile.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static MediaGalleriesEventRouter* Get(content::BrowserContext* context);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExtensionHasGalleryChangeListener(const std::string& extension_id) const;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExtensionHasScanProgressListener(const std::string& extension_id) const;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MediaScanManagerObserver implementation.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnScanStarted(const std::string& extension_id) OVERRIDE;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnScanCancelled(const std::string& extension_id) OVERRIDE;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnScanFinished(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& extension_id,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int gallery_count,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const MediaGalleryScanResult& file_counts) OVERRIDE;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnScanError(const std::string& extension_id) OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class BrowserContextKeyedAPIFactory<MediaGalleriesEventRouter>;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DispatchEventToExtension(const std::string& extension_id,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& event_name,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                scoped_ptr<base::ListValue> event_args);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MediaGalleriesEventRouter(content::BrowserContext* context);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MediaGalleriesEventRouter();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83  // BrowserContextKeyedAPI implementation.
84  static const char* service_name() {
85    return "MediaGalleriesAPI";
86  }
87  static const bool kServiceIsNULLWhileTesting = true;
88
89  // GalleryWatchManagerObserver
90  virtual void OnGalleryChanged(const std::string& extension_id,
91                                MediaGalleryPrefId gallery_id) OVERRIDE;
92  virtual void OnGalleryWatchDropped(const std::string& extension_id,
93                                     MediaGalleryPrefId gallery_id) OVERRIDE;
94
95  // extensions::EventRouter::Observer implementation.
96  virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
97
98  // Current profile.
99  Profile* profile_;
100
101  base::WeakPtrFactory<MediaGalleriesEventRouter> weak_ptr_factory_;
102
103  DISALLOW_COPY_AND_ASSIGN(MediaGalleriesEventRouter);
104};
105
106class MediaGalleriesGetMediaFileSystemsFunction
107    : public ChromeAsyncExtensionFunction {
108 public:
109  DECLARE_EXTENSION_FUNCTION("mediaGalleries.getMediaFileSystems",
110                             MEDIAGALLERIES_GETMEDIAFILESYSTEMS)
111
112 protected:
113  virtual ~MediaGalleriesGetMediaFileSystemsFunction();
114  virtual bool RunAsync() OVERRIDE;
115
116 private:
117  // Bottom half for RunAsync, invoked after the preferences is initialized.
118  void OnPreferencesInit(
119      MediaGalleries::GetMediaFileSystemsInteractivity interactive);
120
121  // Always show the dialog.
122  void AlwaysShowDialog(const std::vector<MediaFileSystemInfo>& filesystems);
123
124  // If no galleries are found, show the dialog, otherwise return them.
125  void ShowDialogIfNoGalleries(
126      const std::vector<MediaFileSystemInfo>& filesystems);
127
128  // Grabs galleries from the media file system registry and passes them to
129  // |ReturnGalleries|.
130  void GetAndReturnGalleries();
131
132  // Returns galleries to the caller.
133  void ReturnGalleries(const std::vector<MediaFileSystemInfo>& filesystems);
134
135  // Shows the configuration dialog to edit gallery preferences.
136  void ShowDialog();
137
138  // A helper method that calls
139  // MediaFileSystemRegistry::GetMediaFileSystemsForExtension().
140  void GetMediaFileSystemsForExtension(const MediaFileSystemsCallback& cb);
141};
142
143class MediaGalleriesGetAllMediaFileSystemMetadataFunction
144    : public ChromeAsyncExtensionFunction {
145 public:
146  DECLARE_EXTENSION_FUNCTION("mediaGalleries.getAllMediaFileSystemMetadata",
147                             MEDIAGALLERIES_GETALLMEDIAFILESYSTEMMETADATA)
148
149 protected:
150  virtual ~MediaGalleriesGetAllMediaFileSystemMetadataFunction();
151  virtual bool RunAsync() OVERRIDE;
152
153 private:
154  // Bottom half for RunAsync, invoked after the preferences is initialized.
155  // Gets the list of permitted galleries and checks if they are available.
156  void OnPreferencesInit();
157
158  // Callback to run upon getting the list of available devices.
159  // Sends the list of media filesystem metadata back to the extension.
160  void OnGetGalleries(
161      const MediaGalleryPrefIdSet& permitted_gallery_ids,
162      const storage_monitor::MediaStorageUtil::DeviceIdSet* available_devices);
163};
164
165class MediaGalleriesAddUserSelectedFolderFunction
166    : public ChromeAsyncExtensionFunction {
167 public:
168  DECLARE_EXTENSION_FUNCTION("mediaGalleries.addUserSelectedFolder",
169                             MEDIAGALLERIES_ADDUSERSELECTEDFOLDER)
170
171 protected:
172  virtual ~MediaGalleriesAddUserSelectedFolderFunction();
173  virtual bool RunAsync() OVERRIDE;
174
175 private:
176  // Bottom half for RunAsync, invoked after the preferences is initialized.
177  void OnPreferencesInit();
178
179  // Callback for the directory prompt request, with the input from the user.
180  // If |selected_directory| is empty, then the user canceled.
181  // Either handle the user canceled case or add the selected gallery.
182  void OnDirectorySelected(const base::FilePath& selected_directory);
183
184  // Callback for the directory prompt request. |pref_id| is for the gallery
185  // the user just added. |filesystems| is the entire list of file systems.
186  // The fsid for the file system that corresponds to |pref_id| will be
187  // appended to the list of file systems returned to the caller. The
188  // Javascript binding for this API will interpret the list appropriately.
189  void ReturnGalleriesAndId(
190      MediaGalleryPrefId pref_id,
191      const std::vector<MediaFileSystemInfo>& filesystems);
192
193  // A helper method that calls
194  // MediaFileSystemRegistry::GetMediaFileSystemsForExtension().
195  void GetMediaFileSystemsForExtension(const MediaFileSystemsCallback& cb);
196};
197
198class MediaGalleriesDropPermissionForMediaFileSystemFunction
199    : public ChromeAsyncExtensionFunction {
200 public:
201  DECLARE_EXTENSION_FUNCTION("mediaGalleries.dropPermissionForMediaFileSystem",
202                             MEDIAGALLERIES_DROPPERMISSIONFORMEDIAFILESYSTEM)
203
204 protected:
205  virtual ~MediaGalleriesDropPermissionForMediaFileSystemFunction();
206  virtual bool RunAsync() OVERRIDE;
207
208 private:
209  // Bottom half for RunAsync, invoked after the preferences is initialized.
210  void OnPreferencesInit(MediaGalleryPrefId pref_id);
211};
212
213class MediaGalleriesStartMediaScanFunction
214    : public ChromeAsyncExtensionFunction {
215 public:
216  DECLARE_EXTENSION_FUNCTION("mediaGalleries.startMediaScan",
217                             MEDIAGALLERIES_STARTMEDIASCAN)
218
219 protected:
220  virtual ~MediaGalleriesStartMediaScanFunction();
221  virtual bool RunAsync() OVERRIDE;
222
223 private:
224  // Bottom half for RunAsync, invoked after the preferences is initialized.
225  void OnPreferencesInit();
226};
227
228class MediaGalleriesCancelMediaScanFunction
229    : public ChromeAsyncExtensionFunction {
230 public:
231  DECLARE_EXTENSION_FUNCTION("mediaGalleries.cancelMediaScan",
232                             MEDIAGALLERIES_CANCELMEDIASCAN)
233
234 protected:
235  virtual ~MediaGalleriesCancelMediaScanFunction();
236  virtual bool RunAsync() OVERRIDE;
237
238 private:
239  // Bottom half for RunAsync, invoked after the preferences is initialized.
240  void OnPreferencesInit();
241};
242
243class MediaGalleriesAddScanResultsFunction
244    : public ChromeAsyncExtensionFunction {
245 public:
246  DECLARE_EXTENSION_FUNCTION("mediaGalleries.addScanResults",
247                             MEDIAGALLERIES_ADDSCANRESULTS)
248
249 protected:
250  virtual ~MediaGalleriesAddScanResultsFunction();
251  virtual bool RunAsync() OVERRIDE;
252
253  // Pulled out for testing.
254  virtual MediaGalleriesScanResultController* MakeDialog(
255      content::WebContents* web_contents,
256      const extensions::Extension& extension,
257      const base::Closure& on_finish);
258
259 private:
260  // Bottom half for RunAsync, invoked after the preferences is initialized.
261  void OnPreferencesInit();
262
263  // Grabs galleries from the media file system registry and passes them to
264  // ReturnGalleries().
265  void GetAndReturnGalleries();
266
267  // Returns galleries to the caller.
268  void ReturnGalleries(const std::vector<MediaFileSystemInfo>& filesystems);
269};
270
271class MediaGalleriesGetMetadataFunction : public ChromeAsyncExtensionFunction {
272 public:
273  DECLARE_EXTENSION_FUNCTION("mediaGalleries.getMetadata",
274                             MEDIAGALLERIES_GETMETADATA)
275
276 protected:
277  virtual ~MediaGalleriesGetMetadataFunction();
278  virtual bool RunAsync() OVERRIDE;
279
280 private:
281  // Bottom half for RunAsync, invoked after the preferences is initialized.
282  void OnPreferencesInit(MediaGalleries::GetMetadataType metadata_type,
283                         const std::string& blob_uuid);
284
285  void GetMetadata(MediaGalleries::GetMetadataType metadata_type,
286                   const std::string& blob_uuid,
287                   scoped_ptr<std::string> blob_header,
288                   int64 total_blob_length);
289
290  void OnSafeMediaMetadataParserDone(
291      bool parse_success, scoped_ptr<base::DictionaryValue> result_dictionary,
292      scoped_ptr<std::vector<metadata::AttachedImage> > attached_images);
293
294  void ConstructNextBlob(
295      scoped_ptr<base::DictionaryValue> result_dictionary,
296      scoped_ptr<std::vector<metadata::AttachedImage> > attached_images,
297      scoped_ptr<std::vector<std::string> > blob_uuids,
298      scoped_ptr<content::BlobHandle> current_blob);
299};
300
301class MediaGalleriesAddGalleryWatchFunction
302    : public ChromeAsyncExtensionFunction {
303 public:
304  DECLARE_EXTENSION_FUNCTION("mediaGalleries.addGalleryWatch",
305                             MEDIAGALLERIES_ADDGALLERYWATCH);
306
307 protected:
308  virtual ~MediaGalleriesAddGalleryWatchFunction();
309  virtual bool RunAsync() OVERRIDE;
310
311 private:
312  void OnPreferencesInit(const std::string& pref_id);
313
314  // Gallery watch request handler.
315  void HandleResponse(MediaGalleryPrefId gallery_id, const std::string& error);
316};
317
318class MediaGalleriesRemoveGalleryWatchFunction
319    : public ChromeAsyncExtensionFunction {
320 public:
321  DECLARE_EXTENSION_FUNCTION("mediaGalleries.removeGalleryWatch",
322                             MEDIAGALLERIES_REMOVEGALLERYWATCH);
323
324 protected:
325  virtual ~MediaGalleriesRemoveGalleryWatchFunction();
326  virtual bool RunAsync() OVERRIDE;
327
328 private:
329  void OnPreferencesInit(const std::string& pref_id);
330};
331
332class MediaGalleriesGetAllGalleryWatchFunction
333    : public ChromeAsyncExtensionFunction {
334 public:
335  DECLARE_EXTENSION_FUNCTION("mediaGalleries.getAllGalleryWatch",
336                             MEDIAGALLERIES_GETALLGALLERYWATCH);
337
338 protected:
339  virtual ~MediaGalleriesGetAllGalleryWatchFunction();
340  virtual bool RunAsync() OVERRIDE;
341
342 private:
343  void OnPreferencesInit();
344};
345
346class MediaGalleriesRemoveAllGalleryWatchFunction
347    : public ChromeAsyncExtensionFunction {
348 public:
349  DECLARE_EXTENSION_FUNCTION("mediaGalleries.removeAllGalleryWatch",
350                             MEDIAGALLERIES_REMOVEALLGALLERYWATCH);
351
352 protected:
353  virtual ~MediaGalleriesRemoveAllGalleryWatchFunction();
354  virtual bool RunAsync() OVERRIDE;
355
356 private:
357  void OnPreferencesInit();
358};
359
360}  // namespace extensions
361
362#endif  // CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_MEDIA_GALLERIES_API_H_
363