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 // Implements the Chrome Extensions Media Galleries API.
7 #include "chrome/browser/extensions/api/media_galleries/media_galleries_api.h"
13 #include "base/callback.h"
14 #include "base/lazy_instance.h"
15 #include "base/numerics/safe_conversions.h"
16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
22 #include "chrome/browser/extensions/blob_reader.h"
23 #include "chrome/browser/extensions/chrome_extension_function_details.h"
24 #include "chrome/browser/extensions/extension_tab_util.h"
25 #include "chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h"
26 #include "chrome/browser/media_galleries/gallery_watch_manager.h"
27 #include "chrome/browser/media_galleries/media_file_system_registry.h"
28 #include "chrome/browser/media_galleries/media_galleries_histograms.h"
29 #include "chrome/browser/media_galleries/media_galleries_permission_controller.h"
30 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
31 #include "chrome/browser/media_galleries/media_galleries_scan_result_controller.h"
32 #include "chrome/browser/media_galleries/media_scan_manager.h"
33 #include "chrome/browser/platform_util.h"
34 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/ui/chrome_select_file_policy.h"
36 #include "chrome/common/extensions/api/media_galleries.h"
37 #include "chrome/common/pref_names.h"
38 #include "chrome/grit/generated_resources.h"
39 #include "components/storage_monitor/storage_info.h"
40 #include "content/public/browser/blob_handle.h"
41 #include "content/public/browser/browser_context.h"
42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/child_process_security_policy.h"
44 #include "content/public/browser/render_frame_host.h"
45 #include "content/public/browser/render_process_host.h"
46 #include "content/public/browser/render_view_host.h"
47 #include "content/public/browser/web_contents.h"
48 #include "extensions/browser/blob_holder.h"
49 #include "extensions/browser/extension_prefs.h"
50 #include "extensions/browser/extension_system.h"
51 #include "extensions/common/extension.h"
52 #include "extensions/common/permissions/api_permission.h"
53 #include "extensions/common/permissions/media_galleries_permission.h"
54 #include "extensions/common/permissions/permissions_data.h"
55 #include "net/base/mime_sniffer.h"
56 #include "storage/browser/blob/blob_data_handle.h"
57 #include "ui/base/l10n/l10n_util.h"
59 using content::WebContents
;
60 using storage_monitor::MediaStorageUtil
;
61 using storage_monitor::StorageInfo
;
63 namespace extensions
{
65 namespace MediaGalleries
= api::media_galleries
;
66 namespace DropPermissionForMediaFileSystem
=
67 MediaGalleries::DropPermissionForMediaFileSystem
;
68 namespace GetMediaFileSystems
= MediaGalleries::GetMediaFileSystems
;
69 namespace AddGalleryWatch
= MediaGalleries::AddGalleryWatch
;
70 namespace RemoveGalleryWatch
= MediaGalleries::RemoveGalleryWatch
;
71 namespace GetAllGalleryWatch
= MediaGalleries::GetAllGalleryWatch
;
75 const char kDisallowedByPolicy
[] =
76 "Media Galleries API is disallowed by policy: ";
77 const char kFailedToSetGalleryPermission
[] =
78 "Failed to set gallery permission.";
79 const char kInvalidGalleryIdMsg
[] = "Invalid gallery id.";
80 const char kMissingEventListener
[] = "Missing event listener registration.";
81 const char kNonExistentGalleryId
[] = "Non-existent gallery id.";
82 const char kNoScanPermission
[] = "No permission to scan.";
84 const char kDeviceIdKey
[] = "deviceId";
85 const char kGalleryIdKey
[] = "galleryId";
86 const char kIsAvailableKey
[] = "isAvailable";
87 const char kIsMediaDeviceKey
[] = "isMediaDevice";
88 const char kIsRemovableKey
[] = "isRemovable";
89 const char kNameKey
[] = "name";
91 const char kMetadataKey
[] = "metadata";
92 const char kAttachedImagesBlobInfoKey
[] = "attachedImagesBlobInfo";
93 const char kBlobUUIDKey
[] = "blobUUID";
94 const char kTypeKey
[] = "type";
95 const char kSizeKey
[] = "size";
97 const char kInvalidGalleryId
[] = "-1";
99 MediaFileSystemRegistry
* media_file_system_registry() {
100 return g_browser_process
->media_file_system_registry();
103 GalleryWatchManager
* gallery_watch_manager() {
104 return media_file_system_registry()->gallery_watch_manager();
107 MediaScanManager
* media_scan_manager() {
108 return media_file_system_registry()->media_scan_manager();
111 // Checks whether the MediaGalleries API is currently accessible (it may be
112 // disallowed even if an extension has the requisite permission). Then
113 // initializes the MediaGalleriesPreferences
114 bool Setup(Profile
* profile
, std::string
* error
, base::Closure callback
) {
115 if (!ChromeSelectFilePolicy::FileSelectDialogsAllowed()) {
116 *error
= std::string(kDisallowedByPolicy
) +
117 prefs::kAllowFileSelectionDialogs
;
121 MediaGalleriesPreferences
* preferences
=
122 media_file_system_registry()->GetPreferences(profile
);
123 preferences
->EnsureInitialized(callback
);
127 // Returns true and sets |gallery_file_path| and |gallery_pref_id| if the
128 // |gallery_id| is valid and returns false otherwise.
129 bool GetGalleryFilePathAndId(const std::string
& gallery_id
,
131 const Extension
* extension
,
132 base::FilePath
* gallery_file_path
,
133 MediaGalleryPrefId
* gallery_pref_id
) {
134 MediaGalleryPrefId pref_id
;
135 if (!base::StringToUint64(gallery_id
, &pref_id
))
137 MediaGalleriesPreferences
* preferences
=
138 g_browser_process
->media_file_system_registry()->GetPreferences(profile
);
139 base::FilePath
file_path(
140 preferences
->LookUpGalleryPathForExtension(pref_id
, extension
, false));
141 if (file_path
.empty())
143 *gallery_pref_id
= pref_id
;
144 *gallery_file_path
= file_path
;
148 base::ListValue
* ConstructFileSystemList(
149 content::RenderFrameHost
* rfh
,
150 const Extension
* extension
,
151 const std::vector
<MediaFileSystemInfo
>& filesystems
) {
155 MediaGalleriesPermission::CheckParam
read_param(
156 MediaGalleriesPermission::kReadPermission
);
157 const PermissionsData
* permissions_data
= extension
->permissions_data();
158 bool has_read_permission
= permissions_data
->CheckAPIPermissionWithParam(
159 APIPermission::kMediaGalleries
, &read_param
);
160 MediaGalleriesPermission::CheckParam
copy_to_param(
161 MediaGalleriesPermission::kCopyToPermission
);
162 bool has_copy_to_permission
= permissions_data
->CheckAPIPermissionWithParam(
163 APIPermission::kMediaGalleries
, ©_to_param
);
164 MediaGalleriesPermission::CheckParam
delete_param(
165 MediaGalleriesPermission::kDeletePermission
);
166 bool has_delete_permission
= permissions_data
->CheckAPIPermissionWithParam(
167 APIPermission::kMediaGalleries
, &delete_param
);
169 const int child_id
= rfh
->GetProcess()->GetID();
170 scoped_ptr
<base::ListValue
> list(new base::ListValue());
171 for (size_t i
= 0; i
< filesystems
.size(); ++i
) {
172 scoped_ptr
<base::DictionaryValue
> file_system_dict_value(
173 new base::DictionaryValue());
175 // Send the file system id so the renderer can create a valid FileSystem
177 file_system_dict_value
->SetStringWithoutPathExpansion(
178 "fsid", filesystems
[i
].fsid
);
180 file_system_dict_value
->SetStringWithoutPathExpansion(
181 kNameKey
, filesystems
[i
].name
);
182 file_system_dict_value
->SetStringWithoutPathExpansion(
184 base::Uint64ToString(filesystems
[i
].pref_id
));
185 if (!filesystems
[i
].transient_device_id
.empty()) {
186 file_system_dict_value
->SetStringWithoutPathExpansion(
187 kDeviceIdKey
, filesystems
[i
].transient_device_id
);
189 file_system_dict_value
->SetBooleanWithoutPathExpansion(
190 kIsRemovableKey
, filesystems
[i
].removable
);
191 file_system_dict_value
->SetBooleanWithoutPathExpansion(
192 kIsMediaDeviceKey
, filesystems
[i
].media_device
);
193 file_system_dict_value
->SetBooleanWithoutPathExpansion(
194 kIsAvailableKey
, true);
196 list
->Append(file_system_dict_value
.release());
198 if (filesystems
[i
].path
.empty())
201 if (has_read_permission
) {
202 content::ChildProcessSecurityPolicy
* policy
=
203 content::ChildProcessSecurityPolicy::GetInstance();
204 policy
->GrantReadFile(child_id
, filesystems
[i
].path
);
205 if (has_delete_permission
) {
206 policy
->GrantDeleteFrom(child_id
, filesystems
[i
].path
);
207 if (has_copy_to_permission
) {
208 policy
->GrantCopyInto(child_id
, filesystems
[i
].path
);
214 return list
.release();
217 bool CheckScanPermission(const extensions::Extension
* extension
,
218 std::string
* error
) {
221 MediaGalleriesPermission::CheckParam
scan_param(
222 MediaGalleriesPermission::kScanPermission
);
223 bool has_scan_permission
=
224 extension
->permissions_data()->CheckAPIPermissionWithParam(
225 APIPermission::kMediaGalleries
, &scan_param
);
226 if (!has_scan_permission
)
227 *error
= kNoScanPermission
;
228 return has_scan_permission
;
231 class SelectDirectoryDialog
: public ui::SelectFileDialog::Listener
,
232 public base::RefCounted
<SelectDirectoryDialog
> {
234 // Selected file path, or an empty path if the user canceled.
235 typedef base::Callback
<void(const base::FilePath
&)> Callback
;
237 SelectDirectoryDialog(WebContents
* web_contents
, const Callback
& callback
)
238 : web_contents_(web_contents
),
239 callback_(callback
) {
240 select_file_dialog_
= ui::SelectFileDialog::Create(
241 this, new ChromeSelectFilePolicy(web_contents
));
244 void Show(const base::FilePath
& default_path
) {
245 AddRef(); // Balanced in the two reachable listener outcomes.
246 select_file_dialog_
->SelectFile(
247 ui::SelectFileDialog::SELECT_FOLDER
,
248 l10n_util::GetStringUTF16(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY_TITLE
),
252 base::FilePath::StringType(),
253 platform_util::GetTopLevel(web_contents_
->GetNativeView()),
257 // ui::SelectFileDialog::Listener implementation.
258 void FileSelected(const base::FilePath
& path
,
260 void* params
) override
{
262 Release(); // Balanced in Show().
265 void MultiFilesSelected(const std::vector
<base::FilePath
>& files
,
266 void* params
) override
{
267 NOTREACHED() << "Should not be able to select multiple files";
270 void FileSelectionCanceled(void* params
) override
{
271 callback_
.Run(base::FilePath());
272 Release(); // Balanced in Show().
276 friend class base::RefCounted
<SelectDirectoryDialog
>;
277 ~SelectDirectoryDialog() override
{}
279 scoped_refptr
<ui::SelectFileDialog
> select_file_dialog_
;
280 WebContents
* web_contents_
;
283 DISALLOW_COPY_AND_ASSIGN(SelectDirectoryDialog
);
288 MediaGalleriesEventRouter::MediaGalleriesEventRouter(
289 content::BrowserContext
* context
)
290 : profile_(Profile::FromBrowserContext(context
)), weak_ptr_factory_(this) {
291 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
294 EventRouter::Get(profile_
)->RegisterObserver(
295 this, MediaGalleries::OnGalleryChanged::kEventName
);
297 gallery_watch_manager()->AddObserver(profile_
, this);
298 media_scan_manager()->AddObserver(profile_
, this);
301 MediaGalleriesEventRouter::~MediaGalleriesEventRouter() {
304 void MediaGalleriesEventRouter::Shutdown() {
305 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
306 weak_ptr_factory_
.InvalidateWeakPtrs();
308 EventRouter::Get(profile_
)->UnregisterObserver(this);
310 gallery_watch_manager()->RemoveObserver(profile_
);
311 media_scan_manager()->RemoveObserver(profile_
);
312 media_scan_manager()->CancelScansForProfile(profile_
);
315 static base::LazyInstance
<
316 BrowserContextKeyedAPIFactory
<MediaGalleriesEventRouter
> > g_factory
=
317 LAZY_INSTANCE_INITIALIZER
;
320 BrowserContextKeyedAPIFactory
<MediaGalleriesEventRouter
>*
321 MediaGalleriesEventRouter::GetFactoryInstance() {
322 return g_factory
.Pointer();
326 MediaGalleriesEventRouter
* MediaGalleriesEventRouter::Get(
327 content::BrowserContext
* context
) {
328 DCHECK(media_file_system_registry()
329 ->GetPreferences(Profile::FromBrowserContext(context
))
331 return BrowserContextKeyedAPIFactory
<MediaGalleriesEventRouter
>::Get(context
);
334 bool MediaGalleriesEventRouter::ExtensionHasGalleryChangeListener(
335 const std::string
& extension_id
) const {
336 return EventRouter::Get(profile_
)->ExtensionHasEventListener(
337 extension_id
, MediaGalleries::OnGalleryChanged::kEventName
);
340 bool MediaGalleriesEventRouter::ExtensionHasScanProgressListener(
341 const std::string
& extension_id
) const {
342 return EventRouter::Get(profile_
)->ExtensionHasEventListener(
343 extension_id
, MediaGalleries::OnScanProgress::kEventName
);
346 void MediaGalleriesEventRouter::OnScanStarted(const std::string
& extension_id
) {
347 MediaGalleries::ScanProgressDetails details
;
348 details
.type
= MediaGalleries::SCAN_PROGRESS_TYPE_START
;
349 DispatchEventToExtension(
350 extension_id
, events::MEDIA_GALLERIES_ON_SCAN_PROGRESS
,
351 MediaGalleries::OnScanProgress::kEventName
,
352 MediaGalleries::OnScanProgress::Create(details
).Pass());
355 void MediaGalleriesEventRouter::OnScanCancelled(
356 const std::string
& extension_id
) {
357 MediaGalleries::ScanProgressDetails details
;
358 details
.type
= MediaGalleries::SCAN_PROGRESS_TYPE_CANCEL
;
359 DispatchEventToExtension(
360 extension_id
, events::MEDIA_GALLERIES_ON_SCAN_PROGRESS
,
361 MediaGalleries::OnScanProgress::kEventName
,
362 MediaGalleries::OnScanProgress::Create(details
).Pass());
365 void MediaGalleriesEventRouter::OnScanFinished(
366 const std::string
& extension_id
, int gallery_count
,
367 const MediaGalleryScanResult
& file_counts
) {
368 media_galleries::UsageCount(media_galleries::SCAN_FINISHED
);
369 MediaGalleries::ScanProgressDetails details
;
370 details
.type
= MediaGalleries::SCAN_PROGRESS_TYPE_FINISH
;
371 details
.gallery_count
.reset(new int(gallery_count
));
372 details
.audio_count
.reset(new int(file_counts
.audio_count
));
373 details
.image_count
.reset(new int(file_counts
.image_count
));
374 details
.video_count
.reset(new int(file_counts
.video_count
));
375 DispatchEventToExtension(
376 extension_id
, events::MEDIA_GALLERIES_ON_SCAN_PROGRESS
,
377 MediaGalleries::OnScanProgress::kEventName
,
378 MediaGalleries::OnScanProgress::Create(details
).Pass());
381 void MediaGalleriesEventRouter::OnScanError(
382 const std::string
& extension_id
) {
383 MediaGalleries::ScanProgressDetails details
;
384 details
.type
= MediaGalleries::SCAN_PROGRESS_TYPE_ERROR
;
385 DispatchEventToExtension(
386 extension_id
, events::MEDIA_GALLERIES_ON_SCAN_PROGRESS
,
387 MediaGalleries::OnScanProgress::kEventName
,
388 MediaGalleries::OnScanProgress::Create(details
).Pass());
391 void MediaGalleriesEventRouter::DispatchEventToExtension(
392 const std::string
& extension_id
,
393 events::HistogramValue histogram_value
,
394 const std::string
& event_name
,
395 scoped_ptr
<base::ListValue
> event_args
) {
396 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
398 // TODO(tommycli): Remove these CHECKs after fixing https://crbug.com/467627.
400 EventRouter
* router
= EventRouter::Get(profile_
);
403 if (!router
->ExtensionHasEventListener(extension_id
, event_name
))
406 scoped_ptr
<extensions::Event
> event(
407 new extensions::Event(histogram_value
, event_name
, event_args
.Pass()));
408 router
->DispatchEventToExtension(extension_id
, event
.Pass());
411 void MediaGalleriesEventRouter::OnGalleryChanged(
412 const std::string
& extension_id
, MediaGalleryPrefId gallery_id
) {
413 MediaGalleries::GalleryChangeDetails details
;
414 details
.type
= MediaGalleries::GALLERY_CHANGE_TYPE_CONTENTS_CHANGED
;
415 details
.gallery_id
= base::Uint64ToString(gallery_id
);
416 DispatchEventToExtension(
417 extension_id
, events::MEDIA_GALLERIES_ON_GALLERY_CHANGED
,
418 MediaGalleries::OnGalleryChanged::kEventName
,
419 MediaGalleries::OnGalleryChanged::Create(details
).Pass());
422 void MediaGalleriesEventRouter::OnGalleryWatchDropped(
423 const std::string
& extension_id
, MediaGalleryPrefId gallery_id
) {
424 MediaGalleries::GalleryChangeDetails details
;
425 details
.type
= MediaGalleries::GALLERY_CHANGE_TYPE_WATCH_DROPPED
;
426 details
.gallery_id
= gallery_id
;
427 DispatchEventToExtension(
428 extension_id
, events::MEDIA_GALLERIES_ON_GALLERY_CHANGED
,
429 MediaGalleries::OnGalleryChanged::kEventName
,
430 MediaGalleries::OnGalleryChanged::Create(details
).Pass());
433 void MediaGalleriesEventRouter::OnListenerRemoved(
434 const EventListenerInfo
& details
) {
435 if (details
.event_name
== MediaGalleries::OnGalleryChanged::kEventName
&&
436 !ExtensionHasGalleryChangeListener(details
.extension_id
)) {
437 gallery_watch_manager()->RemoveAllWatches(profile_
, details
.extension_id
);
441 ///////////////////////////////////////////////////////////////////////////////
442 // MediaGalleriesGetMediaFileSystemsFunction //
443 ///////////////////////////////////////////////////////////////////////////////
444 MediaGalleriesGetMediaFileSystemsFunction::
445 ~MediaGalleriesGetMediaFileSystemsFunction() {}
447 bool MediaGalleriesGetMediaFileSystemsFunction::RunAsync() {
448 media_galleries::UsageCount(media_galleries::GET_MEDIA_FILE_SYSTEMS
);
449 scoped_ptr
<GetMediaFileSystems::Params
> params(
450 GetMediaFileSystems::Params::Create(*args_
));
451 EXTENSION_FUNCTION_VALIDATE(params
.get());
452 MediaGalleries::GetMediaFileSystemsInteractivity interactive
=
453 MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO
;
454 if (params
->details
.get() && params
->details
->interactive
!= MediaGalleries::
455 GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE
) {
456 interactive
= params
->details
->interactive
;
459 return Setup(GetProfile(), &error_
, base::Bind(
460 &MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit
, this,
464 void MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit(
465 MediaGalleries::GetMediaFileSystemsInteractivity interactive
) {
466 switch (interactive
) {
467 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_YES
: {
468 // The MediaFileSystemRegistry only updates preferences for extensions
469 // that it knows are in use. Since this may be the first call to
470 // chrome.getMediaFileSystems for this extension, call
471 // GetMediaFileSystemsForExtension() here solely so that
472 // MediaFileSystemRegistry will send preference changes.
473 GetMediaFileSystemsForExtension(base::Bind(
474 &MediaGalleriesGetMediaFileSystemsFunction::AlwaysShowDialog
, this));
477 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_IF_NEEDED
: {
478 GetMediaFileSystemsForExtension(base::Bind(
479 &MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries
,
483 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO
:
484 GetAndReturnGalleries();
486 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE
:
492 void MediaGalleriesGetMediaFileSystemsFunction::AlwaysShowDialog(
493 const std::vector
<MediaFileSystemInfo
>& /*filesystems*/) {
497 void MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries(
498 const std::vector
<MediaFileSystemInfo
>& filesystems
) {
499 if (filesystems
.empty())
502 ReturnGalleries(filesystems
);
505 void MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries() {
506 GetMediaFileSystemsForExtension(base::Bind(
507 &MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries
, this));
510 void MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries(
511 const std::vector
<MediaFileSystemInfo
>& filesystems
) {
512 scoped_ptr
<base::ListValue
> list(
513 ConstructFileSystemList(render_frame_host(), extension(), filesystems
));
519 // The custom JS binding will use this list to create DOMFileSystem objects.
520 SetResult(list
.release());
524 void MediaGalleriesGetMediaFileSystemsFunction::ShowDialog() {
525 media_galleries::UsageCount(media_galleries::SHOW_DIALOG
);
526 WebContents
* contents
=
527 ChromeExtensionFunctionDetails(this).GetOriginWebContents();
533 // Controller will delete itself.
534 base::Closure cb
= base::Bind(
535 &MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries
, this);
536 new MediaGalleriesPermissionController(contents
, *extension(), cb
);
539 void MediaGalleriesGetMediaFileSystemsFunction::GetMediaFileSystemsForExtension(
540 const MediaFileSystemsCallback
& cb
) {
541 if (!render_frame_host()) {
542 cb
.Run(std::vector
<MediaFileSystemInfo
>());
545 MediaFileSystemRegistry
* registry
= media_file_system_registry();
546 DCHECK(registry
->GetPreferences(GetProfile())->IsInitialized());
547 registry
->GetMediaFileSystemsForExtension(GetSenderWebContents(), extension(),
552 ///////////////////////////////////////////////////////////////////////////////
553 // MediaGalleriesGetAllMediaFileSystemMetadataFunction //
554 ///////////////////////////////////////////////////////////////////////////////
555 MediaGalleriesGetAllMediaFileSystemMetadataFunction::
556 ~MediaGalleriesGetAllMediaFileSystemMetadataFunction() {}
558 bool MediaGalleriesGetAllMediaFileSystemMetadataFunction::RunAsync() {
559 media_galleries::UsageCount(
560 media_galleries::GET_ALL_MEDIA_FILE_SYSTEM_METADATA
);
561 return Setup(GetProfile(), &error_
, base::Bind(
562 &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit
,
566 void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit() {
567 MediaFileSystemRegistry
* registry
= media_file_system_registry();
568 MediaGalleriesPreferences
* prefs
= registry
->GetPreferences(GetProfile());
569 DCHECK(prefs
->IsInitialized());
570 MediaGalleryPrefIdSet permitted_gallery_ids
=
571 prefs
->GalleriesForExtension(*extension());
573 MediaStorageUtil::DeviceIdSet
* device_ids
= new MediaStorageUtil::DeviceIdSet
;
574 const MediaGalleriesPrefInfoMap
& galleries
= prefs
->known_galleries();
575 for (MediaGalleryPrefIdSet::const_iterator it
= permitted_gallery_ids
.begin();
576 it
!= permitted_gallery_ids
.end(); ++it
) {
577 MediaGalleriesPrefInfoMap::const_iterator gallery_it
= galleries
.find(*it
);
578 DCHECK(gallery_it
!= galleries
.end());
579 device_ids
->insert(gallery_it
->second
.device_id
);
582 MediaStorageUtil::FilterAttachedDevices(
585 &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries
,
587 permitted_gallery_ids
,
588 base::Owned(device_ids
)));
591 void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries(
592 const MediaGalleryPrefIdSet
& permitted_gallery_ids
,
593 const MediaStorageUtil::DeviceIdSet
* available_devices
) {
594 MediaFileSystemRegistry
* registry
= media_file_system_registry();
595 MediaGalleriesPreferences
* prefs
= registry
->GetPreferences(GetProfile());
597 base::ListValue
* list
= new base::ListValue();
598 const MediaGalleriesPrefInfoMap
& galleries
= prefs
->known_galleries();
599 for (MediaGalleryPrefIdSet::const_iterator it
= permitted_gallery_ids
.begin();
600 it
!= permitted_gallery_ids
.end(); ++it
) {
601 MediaGalleriesPrefInfoMap::const_iterator gallery_it
= galleries
.find(*it
);
602 DCHECK(gallery_it
!= galleries
.end());
603 const MediaGalleryPrefInfo
& gallery
= gallery_it
->second
;
604 MediaGalleries::MediaFileSystemMetadata metadata
;
605 metadata
.name
= base::UTF16ToUTF8(gallery
.GetGalleryDisplayName());
606 metadata
.gallery_id
= base::Uint64ToString(gallery
.pref_id
);
607 metadata
.is_removable
= StorageInfo::IsRemovableDevice(gallery
.device_id
);
608 metadata
.is_media_device
= StorageInfo::IsMediaDevice(gallery
.device_id
);
609 metadata
.is_available
= ContainsKey(*available_devices
, gallery
.device_id
);
610 list
->Append(metadata
.ToValue().release());
617 ///////////////////////////////////////////////////////////////////////////////
618 // MediaGalleriesAddUserSelectedFolderFunction //
619 ///////////////////////////////////////////////////////////////////////////////
620 MediaGalleriesAddUserSelectedFolderFunction::
621 ~MediaGalleriesAddUserSelectedFolderFunction() {}
623 bool MediaGalleriesAddUserSelectedFolderFunction::RunAsync() {
624 media_galleries::UsageCount(media_galleries::ADD_USER_SELECTED_FOLDER
);
625 return Setup(GetProfile(), &error_
, base::Bind(
626 &MediaGalleriesAddUserSelectedFolderFunction::OnPreferencesInit
, this));
629 void MediaGalleriesAddUserSelectedFolderFunction::OnPreferencesInit() {
630 Profile
* profile
= GetProfile();
631 const std::string
& app_id
= extension()->id();
632 WebContents
* contents
=
633 ChromeExtensionFunctionDetails(this).GetOriginWebContents();
639 if (!user_gesture()) {
640 OnDirectorySelected(base::FilePath());
644 base::FilePath last_used_path
=
645 extensions::file_system_api::GetLastChooseEntryDirectory(
646 extensions::ExtensionPrefs::Get(profile
), app_id
);
647 SelectDirectoryDialog::Callback callback
= base::Bind(
648 &MediaGalleriesAddUserSelectedFolderFunction::OnDirectorySelected
, this);
649 scoped_refptr
<SelectDirectoryDialog
> select_directory_dialog
=
650 new SelectDirectoryDialog(contents
, callback
);
651 select_directory_dialog
->Show(last_used_path
);
654 void MediaGalleriesAddUserSelectedFolderFunction::OnDirectorySelected(
655 const base::FilePath
& selected_directory
) {
656 if (selected_directory
.empty()) {
657 // User cancelled case.
658 GetMediaFileSystemsForExtension(base::Bind(
659 &MediaGalleriesAddUserSelectedFolderFunction::ReturnGalleriesAndId
,
661 kInvalidMediaGalleryPrefId
));
665 extensions::file_system_api::SetLastChooseEntryDirectory(
666 extensions::ExtensionPrefs::Get(GetProfile()),
670 MediaGalleriesPreferences
* preferences
=
671 media_file_system_registry()->GetPreferences(GetProfile());
672 MediaGalleryPrefId pref_id
=
673 preferences
->AddGalleryByPath(selected_directory
,
674 MediaGalleryPrefInfo::kUserAdded
);
675 preferences
->SetGalleryPermissionForExtension(*extension(), pref_id
, true);
677 GetMediaFileSystemsForExtension(base::Bind(
678 &MediaGalleriesAddUserSelectedFolderFunction::ReturnGalleriesAndId
,
683 void MediaGalleriesAddUserSelectedFolderFunction::ReturnGalleriesAndId(
684 MediaGalleryPrefId pref_id
,
685 const std::vector
<MediaFileSystemInfo
>& filesystems
) {
686 scoped_ptr
<base::ListValue
> list(
687 ConstructFileSystemList(render_frame_host(), extension(), filesystems
));
694 if (pref_id
!= kInvalidMediaGalleryPrefId
) {
695 for (size_t i
= 0; i
< filesystems
.size(); ++i
) {
696 if (filesystems
[i
].pref_id
== pref_id
) {
702 base::DictionaryValue
* results
= new base::DictionaryValue
;
703 results
->SetWithoutPathExpansion("mediaFileSystems", list
.release());
704 results
->SetIntegerWithoutPathExpansion("selectedFileSystemIndex", index
);
710 MediaGalleriesAddUserSelectedFolderFunction::GetMediaFileSystemsForExtension(
711 const MediaFileSystemsCallback
& cb
) {
712 if (!render_frame_host()) {
713 cb
.Run(std::vector
<MediaFileSystemInfo
>());
716 MediaFileSystemRegistry
* registry
= media_file_system_registry();
717 DCHECK(registry
->GetPreferences(GetProfile())->IsInitialized());
718 registry
->GetMediaFileSystemsForExtension(GetSenderWebContents(), extension(),
722 ///////////////////////////////////////////////////////////////////////////////
723 // MediaGalleriesDropPermissionForMediaFileSystemFunction //
724 ///////////////////////////////////////////////////////////////////////////////
725 MediaGalleriesDropPermissionForMediaFileSystemFunction::
726 ~MediaGalleriesDropPermissionForMediaFileSystemFunction() {}
728 bool MediaGalleriesDropPermissionForMediaFileSystemFunction::RunAsync() {
729 media_galleries::UsageCount(
730 media_galleries::DROP_PERMISSION_FOR_MEDIA_FILE_SYSTEM
);
732 scoped_ptr
<DropPermissionForMediaFileSystem::Params
> params(
733 DropPermissionForMediaFileSystem::Params::Create(*args_
));
734 EXTENSION_FUNCTION_VALIDATE(params
.get());
735 MediaGalleryPrefId pref_id
;
736 if (!base::StringToUint64(params
->gallery_id
, &pref_id
)) {
737 error_
= kInvalidGalleryIdMsg
;
741 base::Closure callback
= base::Bind(
742 &MediaGalleriesDropPermissionForMediaFileSystemFunction::
746 return Setup(GetProfile(), &error_
, callback
);
749 void MediaGalleriesDropPermissionForMediaFileSystemFunction::OnPreferencesInit(
750 MediaGalleryPrefId pref_id
) {
751 MediaGalleriesPreferences
* preferences
=
752 media_file_system_registry()->GetPreferences(GetProfile());
753 if (!ContainsKey(preferences
->known_galleries(), pref_id
)) {
754 error_
= kNonExistentGalleryId
;
759 bool dropped
= preferences
->SetGalleryPermissionForExtension(
760 *extension(), pref_id
, false);
762 SetResult(new base::StringValue(base::Uint64ToString(pref_id
)));
764 error_
= kFailedToSetGalleryPermission
;
765 SendResponse(dropped
);
768 ///////////////////////////////////////////////////////////////////////////////
769 // MediaGalleriesStartMediaScanFunction //
770 ///////////////////////////////////////////////////////////////////////////////
771 MediaGalleriesStartMediaScanFunction::~MediaGalleriesStartMediaScanFunction() {}
773 bool MediaGalleriesStartMediaScanFunction::RunAsync() {
774 media_galleries::UsageCount(media_galleries::START_MEDIA_SCAN
);
775 if (!CheckScanPermission(extension(), &error_
)) {
776 MediaGalleriesEventRouter::Get(GetProfile())
777 ->OnScanError(extension()->id());
780 return Setup(GetProfile(), &error_
, base::Bind(
781 &MediaGalleriesStartMediaScanFunction::OnPreferencesInit
, this));
784 void MediaGalleriesStartMediaScanFunction::OnPreferencesInit() {
785 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
786 MediaGalleriesEventRouter
* api
= MediaGalleriesEventRouter::Get(GetProfile());
787 if (!api
->ExtensionHasScanProgressListener(extension()->id())) {
788 error_
= kMissingEventListener
;
793 media_scan_manager()->StartScan(GetProfile(), extension(), user_gesture());
797 ///////////////////////////////////////////////////////////////////////////////
798 // MediaGalleriesCancelMediaScanFunction //
799 ///////////////////////////////////////////////////////////////////////////////
800 MediaGalleriesCancelMediaScanFunction::
801 ~MediaGalleriesCancelMediaScanFunction() {
804 bool MediaGalleriesCancelMediaScanFunction::RunAsync() {
805 media_galleries::UsageCount(media_galleries::CANCEL_MEDIA_SCAN
);
806 if (!CheckScanPermission(extension(), &error_
)) {
807 MediaGalleriesEventRouter::Get(GetProfile())
808 ->OnScanError(extension()->id());
811 return Setup(GetProfile(), &error_
, base::Bind(
812 &MediaGalleriesCancelMediaScanFunction::OnPreferencesInit
, this));
815 void MediaGalleriesCancelMediaScanFunction::OnPreferencesInit() {
816 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
817 media_scan_manager()->CancelScan(GetProfile(), extension());
821 ///////////////////////////////////////////////////////////////////////////////
822 // MediaGalleriesAddScanResultsFunction //
823 ///////////////////////////////////////////////////////////////////////////////
824 MediaGalleriesAddScanResultsFunction::~MediaGalleriesAddScanResultsFunction() {}
826 bool MediaGalleriesAddScanResultsFunction::RunAsync() {
827 media_galleries::UsageCount(media_galleries::ADD_SCAN_RESULTS
);
828 if (!CheckScanPermission(extension(), &error_
)) {
829 // We don't fire a scan progress error here, as it would be unintuitive.
835 return Setup(GetProfile(), &error_
, base::Bind(
836 &MediaGalleriesAddScanResultsFunction::OnPreferencesInit
, this));
839 MediaGalleriesScanResultController
*
840 MediaGalleriesAddScanResultsFunction::MakeDialog(
841 content::WebContents
* web_contents
,
842 const extensions::Extension
& extension
,
843 const base::Closure
& on_finish
) {
844 // Controller will delete itself.
845 return new MediaGalleriesScanResultController(web_contents
, extension
,
849 void MediaGalleriesAddScanResultsFunction::OnPreferencesInit() {
850 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
851 MediaGalleriesPreferences
* preferences
=
852 media_file_system_registry()->GetPreferences(GetProfile());
853 if (MediaGalleriesScanResultController::ScanResultCountForExtension(
854 preferences
, extension()) == 0) {
855 GetAndReturnGalleries();
859 WebContents
* contents
=
860 ChromeExtensionFunctionDetails(this).GetOriginWebContents();
866 base::Closure cb
= base::Bind(
867 &MediaGalleriesAddScanResultsFunction::GetAndReturnGalleries
, this);
868 MakeDialog(contents
, *extension(), cb
);
871 void MediaGalleriesAddScanResultsFunction::GetAndReturnGalleries() {
872 if (!render_frame_host()) {
873 ReturnGalleries(std::vector
<MediaFileSystemInfo
>());
876 MediaFileSystemRegistry
* registry
= media_file_system_registry();
877 DCHECK(registry
->GetPreferences(GetProfile())->IsInitialized());
878 registry
->GetMediaFileSystemsForExtension(
879 GetSenderWebContents(), extension(),
880 base::Bind(&MediaGalleriesAddScanResultsFunction::ReturnGalleries
, this));
883 void MediaGalleriesAddScanResultsFunction::ReturnGalleries(
884 const std::vector
<MediaFileSystemInfo
>& filesystems
) {
885 scoped_ptr
<base::ListValue
> list(
886 ConstructFileSystemList(render_frame_host(), extension(), filesystems
));
892 // The custom JS binding will use this list to create DOMFileSystem objects.
893 SetResult(list
.release());
897 ///////////////////////////////////////////////////////////////////////////////
898 // MediaGalleriesGetMetadataFunction //
899 ///////////////////////////////////////////////////////////////////////////////
900 MediaGalleriesGetMetadataFunction::~MediaGalleriesGetMetadataFunction() {}
902 bool MediaGalleriesGetMetadataFunction::RunAsync() {
903 std::string blob_uuid
;
904 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(0, &blob_uuid
));
906 const base::Value
* options_value
= NULL
;
907 if (!args_
->Get(1, &options_value
))
909 scoped_ptr
<MediaGalleries::MediaMetadataOptions
> options
=
910 MediaGalleries::MediaMetadataOptions::FromValue(*options_value
);
914 return Setup(GetProfile(), &error_
, base::Bind(
915 &MediaGalleriesGetMetadataFunction::OnPreferencesInit
, this,
916 options
->metadata_type
, blob_uuid
));
919 void MediaGalleriesGetMetadataFunction::OnPreferencesInit(
920 MediaGalleries::GetMetadataType metadata_type
,
921 const std::string
& blob_uuid
) {
922 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
924 // BlobReader is self-deleting.
925 BlobReader
* reader
= new BlobReader(
928 base::Bind(&MediaGalleriesGetMetadataFunction::GetMetadata
, this,
929 metadata_type
, blob_uuid
));
930 reader
->SetByteRange(0, net::kMaxBytesToSniff
);
934 void MediaGalleriesGetMetadataFunction::GetMetadata(
935 MediaGalleries::GetMetadataType metadata_type
, const std::string
& blob_uuid
,
936 scoped_ptr
<std::string
> blob_header
, int64 total_blob_length
) {
937 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
939 std::string mime_type
;
940 bool mime_type_sniffed
= net::SniffMimeTypeFromLocalData(
941 blob_header
->c_str(), blob_header
->size(), &mime_type
);
943 if (!mime_type_sniffed
) {
948 if (metadata_type
== MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY
) {
949 MediaGalleries::MediaMetadata metadata
;
950 metadata
.mime_type
= mime_type
;
952 base::DictionaryValue
* result_dictionary
= new base::DictionaryValue
;
953 result_dictionary
->Set(kMetadataKey
, metadata
.ToValue().release());
954 SetResult(result_dictionary
);
959 // We get attached images by default. GET_METADATA_TYPE_NONE is the default
960 // value if the caller doesn't specify the metadata type.
961 bool get_attached_images
=
962 metadata_type
== MediaGalleries::GET_METADATA_TYPE_ALL
||
963 metadata_type
== MediaGalleries::GET_METADATA_TYPE_NONE
;
965 scoped_refptr
<metadata::SafeMediaMetadataParser
> parser(
966 new metadata::SafeMediaMetadataParser(GetProfile(), blob_uuid
,
967 total_blob_length
, mime_type
,
968 get_attached_images
));
969 parser
->Start(base::Bind(
970 &MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone
, this));
973 void MediaGalleriesGetMetadataFunction::OnSafeMediaMetadataParserDone(
974 bool parse_success
, scoped_ptr
<base::DictionaryValue
> metadata_dictionary
,
975 scoped_ptr
<std::vector
<metadata::AttachedImage
> > attached_images
) {
976 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
978 if (!parse_success
) {
983 DCHECK(metadata_dictionary
.get());
984 DCHECK(attached_images
.get());
986 scoped_ptr
<base::DictionaryValue
> result_dictionary(
987 new base::DictionaryValue
);
988 result_dictionary
->Set(kMetadataKey
, metadata_dictionary
.release());
990 if (attached_images
->empty()) {
991 SetResult(result_dictionary
.release());
996 result_dictionary
->Set(kAttachedImagesBlobInfoKey
, new base::ListValue
);
997 metadata::AttachedImage
* first_image
= &attached_images
->front();
998 content::BrowserContext::CreateMemoryBackedBlob(
1000 first_image
->data
.c_str(),
1001 first_image
->data
.size(),
1002 base::Bind(&MediaGalleriesGetMetadataFunction::ConstructNextBlob
,
1003 this, base::Passed(&result_dictionary
),
1004 base::Passed(&attached_images
),
1005 base::Passed(make_scoped_ptr(new std::vector
<std::string
>))));
1008 void MediaGalleriesGetMetadataFunction::ConstructNextBlob(
1009 scoped_ptr
<base::DictionaryValue
> result_dictionary
,
1010 scoped_ptr
<std::vector
<metadata::AttachedImage
> > attached_images
,
1011 scoped_ptr
<std::vector
<std::string
> > blob_uuids
,
1012 scoped_ptr
<content::BlobHandle
> current_blob
) {
1013 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
1015 DCHECK(result_dictionary
.get());
1016 DCHECK(attached_images
.get());
1017 DCHECK(blob_uuids
.get());
1018 DCHECK(current_blob
.get());
1020 DCHECK(!attached_images
->empty());
1021 DCHECK_LT(blob_uuids
->size(), attached_images
->size());
1023 // For the newly constructed Blob, store its image's metadata and Blob UUID.
1024 base::ListValue
* attached_images_list
= NULL
;
1025 result_dictionary
->GetList(kAttachedImagesBlobInfoKey
, &attached_images_list
);
1026 DCHECK(attached_images_list
);
1027 DCHECK_LT(attached_images_list
->GetSize(), attached_images
->size());
1029 metadata::AttachedImage
* current_image
=
1030 &(*attached_images
)[blob_uuids
->size()];
1031 base::DictionaryValue
* attached_image
= new base::DictionaryValue
;
1032 attached_image
->Set(kBlobUUIDKey
, new base::StringValue(
1033 current_blob
->GetUUID()));
1034 attached_image
->Set(kTypeKey
, new base::StringValue(
1035 current_image
->type
));
1036 attached_image
->Set(kSizeKey
, new base::FundamentalValue(
1037 base::checked_cast
<int>(current_image
->data
.size())));
1038 attached_images_list
->Append(attached_image
);
1040 blob_uuids
->push_back(current_blob
->GetUUID());
1041 extensions::BlobHolder
* holder
=
1042 extensions::BlobHolder::FromRenderProcessHost(
1043 render_frame_host()->GetProcess());
1044 holder
->HoldBlobReference(current_blob
.Pass());
1046 // Construct the next Blob if necessary.
1047 if (blob_uuids
->size() < attached_images
->size()) {
1048 metadata::AttachedImage
* next_image
=
1049 &(*attached_images
)[blob_uuids
->size()];
1050 content::BrowserContext::CreateMemoryBackedBlob(
1052 next_image
->data
.c_str(),
1053 next_image
->data
.size(),
1054 base::Bind(&MediaGalleriesGetMetadataFunction::ConstructNextBlob
,
1055 this, base::Passed(&result_dictionary
),
1056 base::Passed(&attached_images
), base::Passed(&blob_uuids
)));
1060 // All Blobs have been constructed. The renderer will take ownership.
1061 SetResult(result_dictionary
.release());
1062 SetTransferredBlobUUIDs(*blob_uuids
);
1066 ///////////////////////////////////////////////////////////////////////////////
1067 // MediaGalleriesAddGalleryWatchFunction //
1068 ///////////////////////////////////////////////////////////////////////////////
1069 MediaGalleriesAddGalleryWatchFunction::
1070 ~MediaGalleriesAddGalleryWatchFunction() {
1073 bool MediaGalleriesAddGalleryWatchFunction::RunAsync() {
1074 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
1075 DCHECK(GetProfile());
1076 if (!render_frame_host() || !render_frame_host()->GetProcess())
1079 scoped_ptr
<AddGalleryWatch::Params
> params(
1080 AddGalleryWatch::Params::Create(*args_
));
1081 EXTENSION_FUNCTION_VALIDATE(params
.get());
1083 MediaGalleriesPreferences
* preferences
=
1084 g_browser_process
->media_file_system_registry()->GetPreferences(
1086 preferences
->EnsureInitialized(
1087 base::Bind(&MediaGalleriesAddGalleryWatchFunction::OnPreferencesInit
,
1089 params
->gallery_id
));
1094 void MediaGalleriesAddGalleryWatchFunction::OnPreferencesInit(
1095 const std::string
& pref_id
) {
1096 base::FilePath gallery_file_path
;
1097 MediaGalleryPrefId gallery_pref_id
= kInvalidMediaGalleryPrefId
;
1098 if (!GetGalleryFilePathAndId(pref_id
,
1102 &gallery_pref_id
)) {
1103 api::media_galleries::AddGalleryWatchResult result
;
1104 error_
= kInvalidGalleryIdMsg
;
1105 result
.gallery_id
= kInvalidGalleryId
;
1106 result
.success
= false;
1107 SetResult(result
.ToValue().release());
1108 SendResponse(false);
1112 gallery_watch_manager()->AddWatch(
1116 base::Bind(&MediaGalleriesAddGalleryWatchFunction::HandleResponse
,
1121 void MediaGalleriesAddGalleryWatchFunction::HandleResponse(
1122 MediaGalleryPrefId gallery_id
,
1123 const std::string
& error
) {
1124 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
1126 // If an app added a file watch without any event listeners on the
1127 // onGalleryChanged event, that's an error.
1128 MediaGalleriesEventRouter
* api
= MediaGalleriesEventRouter::Get(GetProfile());
1129 api::media_galleries::AddGalleryWatchResult result
;
1130 result
.gallery_id
= base::Uint64ToString(gallery_id
);
1132 if (!api
->ExtensionHasGalleryChangeListener(extension()->id())) {
1133 result
.success
= false;
1134 SetResult(result
.ToValue().release());
1135 error_
= kMissingEventListener
;
1136 SendResponse(false);
1140 result
.success
= error
.empty();
1141 SetResult(result
.ToValue().release());
1142 if (error
.empty()) {
1145 error_
= error
.c_str();
1146 SendResponse(false);
1150 ///////////////////////////////////////////////////////////////////////////////
1151 // MediaGalleriesRemoveGalleryWatchFunction //
1152 ///////////////////////////////////////////////////////////////////////////////
1154 MediaGalleriesRemoveGalleryWatchFunction::
1155 ~MediaGalleriesRemoveGalleryWatchFunction() {
1158 bool MediaGalleriesRemoveGalleryWatchFunction::RunAsync() {
1159 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
1160 if (!render_frame_host() || !render_frame_host()->GetProcess())
1163 scoped_ptr
<RemoveGalleryWatch::Params
> params(
1164 RemoveGalleryWatch::Params::Create(*args_
));
1165 EXTENSION_FUNCTION_VALIDATE(params
.get());
1167 MediaGalleriesPreferences
* preferences
=
1168 g_browser_process
->media_file_system_registry()->GetPreferences(
1170 preferences
->EnsureInitialized(
1171 base::Bind(&MediaGalleriesRemoveGalleryWatchFunction::OnPreferencesInit
,
1173 params
->gallery_id
));
1177 void MediaGalleriesRemoveGalleryWatchFunction::OnPreferencesInit(
1178 const std::string
& pref_id
) {
1179 base::FilePath gallery_file_path
;
1180 MediaGalleryPrefId gallery_pref_id
= 0;
1181 if (!GetGalleryFilePathAndId(pref_id
,
1185 &gallery_pref_id
)) {
1186 error_
= kInvalidGalleryIdMsg
;
1187 SendResponse(false);
1191 gallery_watch_manager()->RemoveWatch(
1192 GetProfile(), extension_id(), gallery_pref_id
);
1196 ///////////////////////////////////////////////////////////////////////////////
1197 // MediaGalleriesGetAllGalleryWatchFunction //
1198 ///////////////////////////////////////////////////////////////////////////////
1200 MediaGalleriesGetAllGalleryWatchFunction::
1201 ~MediaGalleriesGetAllGalleryWatchFunction() {
1204 bool MediaGalleriesGetAllGalleryWatchFunction::RunAsync() {
1205 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
1206 if (!render_frame_host() || !render_frame_host()->GetProcess())
1209 MediaGalleriesPreferences
* preferences
=
1210 g_browser_process
->media_file_system_registry()->GetPreferences(
1212 preferences
->EnsureInitialized(base::Bind(
1213 &MediaGalleriesGetAllGalleryWatchFunction::OnPreferencesInit
, this));
1217 void MediaGalleriesGetAllGalleryWatchFunction::OnPreferencesInit() {
1218 std::vector
<std::string
> result
;
1219 MediaGalleryPrefIdSet gallery_ids
=
1220 gallery_watch_manager()->GetWatchSet(GetProfile(), extension_id());
1221 for (MediaGalleryPrefIdSet::const_iterator iter
= gallery_ids
.begin();
1222 iter
!= gallery_ids
.end();
1224 result
.push_back(base::Uint64ToString(*iter
));
1226 results_
= GetAllGalleryWatch::Results::Create(result
);
1230 ///////////////////////////////////////////////////////////////////////////////
1231 // MediaGalleriesRemoveAllGalleryWatchFunction //
1232 ///////////////////////////////////////////////////////////////////////////////
1234 MediaGalleriesRemoveAllGalleryWatchFunction::
1235 ~MediaGalleriesRemoveAllGalleryWatchFunction() {
1238 bool MediaGalleriesRemoveAllGalleryWatchFunction::RunAsync() {
1239 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
1240 if (!render_frame_host() || !render_frame_host()->GetProcess())
1243 MediaGalleriesPreferences
* preferences
=
1244 g_browser_process
->media_file_system_registry()->GetPreferences(
1246 preferences
->EnsureInitialized(base::Bind(
1247 &MediaGalleriesRemoveAllGalleryWatchFunction::OnPreferencesInit
, this));
1251 void MediaGalleriesRemoveAllGalleryWatchFunction::OnPreferencesInit() {
1252 gallery_watch_manager()->RemoveAllWatches(GetProfile(), extension_id());
1256 } // namespace extensions