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.
4
5// Defines the Chrome Extensions Media Galleries API functions for accessing
6// user's media files, as specified in the extension API IDL.
7
8#ifndef CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_MEDIA_GALLERIES_API_H_
9#define CHROME_BROWSER_EXTENSIONS_API_MEDIA_GALLERIES_MEDIA_GALLERIES_API_H_
10
11#include <string>
12#include <vector>
13
14#include "base/callback_forward.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/weak_ptr.h"
17#include "chrome/browser/extensions/chrome_extension_function.h"
18#include "chrome/browser/media_galleries/gallery_watch_manager_observer.h"
19#include "chrome/browser/media_galleries/media_file_system_registry.h"
20#include "chrome/browser/media_galleries/media_scan_manager_observer.h"
21#include "chrome/common/extensions/api/media_galleries.h"
22#include "chrome/common/media_galleries/metadata_types.h"
23#include "components/storage_monitor/media_storage_util.h"
24#include "extensions/browser/browser_context_keyed_api_factory.h"
25#include "extensions/browser/event_router.h"
26
27namespace MediaGalleries = extensions::api::media_galleries;
28
29class MediaGalleriesScanResultController;
30
31namespace content {
32class BlobHandle;
33class WebContents;
34}
35
36namespace metadata {
37class SafeMediaMetadataParser;
38}
39
40namespace extensions {
41
42class Extension;
43
44// The profile-keyed service that manages the media galleries extension API.
45// Created at the same time as the Profile. This is also the event router.
46class MediaGalleriesEventRouter : public BrowserContextKeyedAPI,
47                                  public GalleryWatchManagerObserver,
48                                  public MediaScanManagerObserver,
49                                  public extensions::EventRouter::Observer {
50 public:
51  // KeyedService implementation.
52  virtual void Shutdown() OVERRIDE;
53
54  // BrowserContextKeyedAPI implementation.
55  static BrowserContextKeyedAPIFactory<MediaGalleriesEventRouter>*
56      GetFactoryInstance();
57
58  // Convenience method to get the MediaGalleriesAPI for a profile.
59  static MediaGalleriesEventRouter* Get(content::BrowserContext* context);
60
61  bool ExtensionHasGalleryChangeListener(const std::string& extension_id) const;
62  bool ExtensionHasScanProgressListener(const std::string& extension_id) const;
63
64  // MediaScanManagerObserver implementation.
65  virtual void OnScanStarted(const std::string& extension_id) OVERRIDE;
66  virtual void OnScanCancelled(const std::string& extension_id) OVERRIDE;
67  virtual void OnScanFinished(
68      const std::string& extension_id,
69      int gallery_count,
70      const MediaGalleryScanResult& file_counts) OVERRIDE;
71  virtual void OnScanError(const std::string& extension_id) OVERRIDE;
72
73 private:
74  friend class BrowserContextKeyedAPIFactory<MediaGalleriesEventRouter>;
75
76  void DispatchEventToExtension(const std::string& extension_id,
77                                const std::string& event_name,
78                                scoped_ptr<base::ListValue> event_args);
79
80  explicit MediaGalleriesEventRouter(content::BrowserContext* context);
81  virtual ~MediaGalleriesEventRouter();
82
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