Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: chrome/browser/extensions/api/media_galleries/media_galleries_api.cc

Issue 93643002: Media Galleries: Add chrome.mediaGalleries.addUserSelectedFolder(). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Implements the Chrome Extensions Media Galleries API. 5 // Implements the Chrome Extensions Media Galleries API.
6 6
7 #include "chrome/browser/extensions/api/media_galleries/media_galleries_api.h" 7 #include "chrome/browser/extensions/api/media_galleries/media_galleries_api.h"
8 8
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "apps/shell_window.h" 13 #include "apps/shell_window.h"
14 #include "apps/shell_window_registry.h" 14 #include "apps/shell_window_registry.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/platform_file.h" 16 #include "base/platform_file.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/task_runner_util.h"
20 #include "base/values.h" 21 #include "base/values.h"
21 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/media_galleries/media_file_system_registry.h" 23 #include "chrome/browser/media_galleries/media_file_system_registry.h"
23 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h" 24 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h"
24 #include "chrome/browser/media_galleries/media_galleries_histograms.h" 25 #include "chrome/browser/media_galleries/media_galleries_histograms.h"
25 #include "chrome/browser/media_galleries/media_galleries_preferences.h" 26 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
27 #include "chrome/browser/platform_util.h"
26 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/storage_monitor/storage_info.h" 29 #include "chrome/browser/storage_monitor/storage_info.h"
28 #include "chrome/browser/ui/chrome_select_file_policy.h" 30 #include "chrome/browser/ui/chrome_select_file_policy.h"
29 #include "chrome/common/extensions/api/media_galleries.h" 31 #include "chrome/common/extensions/api/media_galleries.h"
30 #include "chrome/common/extensions/permissions/media_galleries_permission.h" 32 #include "chrome/common/extensions/permissions/media_galleries_permission.h"
31 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
32 #include "components/web_modal/web_contents_modal_dialog_manager.h" 34 #include "components/web_modal/web_contents_modal_dialog_manager.h"
35 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/child_process_security_policy.h" 36 #include "content/public/browser/child_process_security_policy.h"
34 #include "content/public/browser/render_process_host.h" 37 #include "content/public/browser/render_process_host.h"
35 #include "content/public/browser/render_view_host.h" 38 #include "content/public/browser/render_view_host.h"
36 #include "content/public/browser/web_contents.h" 39 #include "content/public/browser/web_contents.h"
40 #include "content/public/browser/web_contents_view.h"
37 #include "extensions/common/extension.h" 41 #include "extensions/common/extension.h"
38 #include "extensions/common/permissions/api_permission.h" 42 #include "extensions/common/permissions/api_permission.h"
39 #include "extensions/common/permissions/permissions_data.h" 43 #include "extensions/common/permissions/permissions_data.h"
40 44
41 using content::WebContents; 45 using content::WebContents;
42 using web_modal::WebContentsModalDialogManager; 46 using web_modal::WebContentsModalDialogManager;
43 47
44 namespace extensions { 48 namespace extensions {
45 49
46 namespace MediaGalleries = api::media_galleries; 50 namespace MediaGalleries = api::media_galleries;
47 namespace GetMediaFileSystems = MediaGalleries::GetMediaFileSystems; 51 namespace GetMediaFileSystems = MediaGalleries::GetMediaFileSystems;
52 namespace ManageMediaLocations = MediaGalleries::ManageMediaLocations;
48 53
49 namespace { 54 namespace {
50 55
51 const char kDisallowedByPolicy[] = 56 const char kDisallowedByPolicy[] =
52 "Media Galleries API is disallowed by policy: "; 57 "Media Galleries API is disallowed by policy: ";
58 const char kInvalidManageRequestType[] =
59 "Invalid manageMediaLocations request type";
53 60
54 const char kDeviceIdKey[] = "deviceId"; 61 const char kDeviceIdKey[] = "deviceId";
55 const char kGalleryIdKey[] = "galleryId"; 62 const char kGalleryIdKey[] = "galleryId";
56 const char kIsAvailableKey[] = "isAvailable"; 63 const char kIsAvailableKey[] = "isAvailable";
57 const char kIsMediaDeviceKey[] = "isMediaDevice"; 64 const char kIsMediaDeviceKey[] = "isMediaDevice";
58 const char kIsRemovableKey[] = "isRemovable"; 65 const char kIsRemovableKey[] = "isRemovable";
59 const char kNameKey[] = "name"; 66 const char kNameKey[] = "name";
60 67
61 // Checks whether the MediaGalleries API is currently accessible (it may be 68 // Checks whether the MediaGalleries API is currently accessible (it may be
62 // disallowed even if an extension has the requisite permission). 69 // disallowed even if an extension has the requisite permission).
63 bool ApiIsAccessible(std::string* error) { 70 bool ApiIsAccessible(std::string* error) {
64 if (!ChromeSelectFilePolicy::FileSelectDialogsAllowed()) { 71 if (!ChromeSelectFilePolicy::FileSelectDialogsAllowed()) {
65 *error = std::string(kDisallowedByPolicy) + 72 *error = std::string(kDisallowedByPolicy) +
66 prefs::kAllowFileSelectionDialogs; 73 prefs::kAllowFileSelectionDialogs;
67 return false; 74 return false;
68 } 75 }
69 76
70 return true; 77 return true;
71 } 78 }
72 79
73 MediaFileSystemRegistry* media_file_system_registry() { 80 MediaFileSystemRegistry* media_file_system_registry() {
74 return g_browser_process->media_file_system_registry(); 81 return g_browser_process->media_file_system_registry();
75 } 82 }
76 83
84 class SelectDirectoryDialog : public ui::SelectFileDialog::Listener,
vandebo (ex-Chrome) 2013/12/02 18:01:30 Should this live in c/b/media_galleries? Should it
Lei Zhang 2013/12/03 03:33:23 Probably not? The two workflows are different and
vandebo (ex-Chrome) 2013/12/03 21:08:02 They both have a directory picker which results in
85 public base::RefCounted<SelectDirectoryDialog> {
86 public:
87 // Selected file path, or an empty path if the user canceled.
88 typedef base::Callback<void(const base::FilePath&)> Callback;
89
90 SelectDirectoryDialog(WebContents* web_contents, const Callback& callback)
91 : web_contents_(web_contents),
92 callback_(callback) {
93 select_file_dialog_ = ui::SelectFileDialog::Create(
94 this, new ChromeSelectFilePolicy(web_contents));
95 }
96
97 void Show() {
98 AddRef(); // Balanced in the three listener outcomes.
99 select_file_dialog_->SelectFile(
100 ui::SelectFileDialog::SELECT_FOLDER,
101 base::string16(),
102 base::FilePath(),
103 NULL,
104 0,
105 base::FilePath::StringType(),
106 platform_util::GetTopLevel(web_contents_->GetView()->GetNativeView()),
107 NULL);
108 }
109
110 // ui::SelectFileDialog::Listener implementation.
111 virtual void FileSelected(const base::FilePath& path,
112 int index,
113 void* params) OVERRIDE {
114 callback_.Run(path);
115 Release(); // Balanced in Show().
116 }
117
118 virtual void MultiFilesSelected(const std::vector<base::FilePath>& files,
119 void* params) OVERRIDE {
120 Release(); // Balanced in Show().
vandebo (ex-Chrome) 2013/12/02 18:01:30 Should the callback be called with an empty path i
Lei Zhang 2013/12/03 03:33:23 No, we should never handle a NOTREACHED() per the
121 NOTREACHED() << "Should not be able to select multiple files";
122 }
123
124 virtual void FileSelectionCanceled(void* params) OVERRIDE {
125 callback_.Run(base::FilePath());
126 Release(); // Balanced in Show().
127 }
128
129 private:
130 friend class base::RefCounted<SelectDirectoryDialog>;
131 virtual ~SelectDirectoryDialog() {}
132
133 scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
134 WebContents* web_contents_;
135 Callback callback_;
136
137 DISALLOW_COPY_AND_ASSIGN(SelectDirectoryDialog);
138 };
139
77 } // namespace 140 } // namespace
78 141
79 MediaGalleriesGetMediaFileSystemsFunction:: 142 MediaGalleriesGetMediaFileSystemsBase::
80 ~MediaGalleriesGetMediaFileSystemsFunction() {} 143 ~MediaGalleriesGetMediaFileSystemsBase() {}
81 144
82 bool MediaGalleriesGetMediaFileSystemsFunction::RunImpl() { 145 void MediaGalleriesGetMediaFileSystemsBase::ReadPrefsAndShowDialog() {
83 if (!ApiIsAccessible(&error_)) 146 // The MediaFileSystemRegistry only updates preferences for extensions
84 return false; 147 // that it knows are in use. Since this may be the first call to
85 148 // chrome.{getMediaFileSystems, manageMediaLocations} for this extension,
86 media_galleries::UsageCount(media_galleries::GET_MEDIA_FILE_SYSTEMS); 149 // call GetMediaFileSystemsForExtension() here solely so that
87 scoped_ptr<GetMediaFileSystems::Params> params( 150 // MediaFileSystemRegistry will send preference changes.
88 GetMediaFileSystems::Params::Create(*args_)); 151 GetMediaFileSystemsForExtension(base::Bind(
89 EXTENSION_FUNCTION_VALIDATE(params.get()); 152 &MediaGalleriesGetMediaFileSystemsBase::AlwaysShowDialog, this));
90 MediaGalleries::GetMediaFileSystemsInteractivity interactive =
91 MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO;
92 if (params->details.get() && params->details->interactive != MediaGalleries::
93 GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE) {
94 interactive = params->details->interactive;
95 }
96
97 MediaGalleriesPreferences* preferences =
98 media_file_system_registry()->GetPreferences(GetProfile());
99 preferences->EnsureInitialized(base::Bind(
100 &MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit,
101 this,
102 interactive));
103 return true;
104 } 153 }
105 154
106 void MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit( 155 void MediaGalleriesGetMediaFileSystemsBase::ShowDialog() {
107 MediaGalleries::GetMediaFileSystemsInteractivity interactive) { 156 media_galleries::UsageCount(media_galleries::SHOW_DIALOG);
108 switch (interactive) {
109 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_YES: {
110 // The MediaFileSystemRegistry only updates preferences for extensions
111 // that it knows are in use. Since this may be the first call to
112 // chrome.getMediaFileSystems for this extension, call
113 // GetMediaFileSystemsForExtension() here solely so that
114 // MediaFileSystemRegistry will send preference changes.
115 GetMediaFileSystemsForExtension(base::Bind(
116 &MediaGalleriesGetMediaFileSystemsFunction::AlwaysShowDialog, this));
117 return;
118 }
119 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_IF_NEEDED: {
120 GetMediaFileSystemsForExtension(base::Bind(
121 &MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries,
122 this));
123 return;
124 }
125 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO:
126 GetAndReturnGalleries();
127 return;
128 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE:
129 NOTREACHED();
130 }
131 SendResponse(false);
132 }
133 157
134 void MediaGalleriesGetMediaFileSystemsFunction::AlwaysShowDialog( 158 WebContents* contents = GetWebContents();
135 const std::vector<MediaFileSystemInfo>& /*filesystems*/) { 159 if (!contents) {
136 ShowDialog();
137 }
138
139 void MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries(
140 const std::vector<MediaFileSystemInfo>& filesystems) {
141 if (filesystems.empty())
142 ShowDialog();
143 else
144 ReturnGalleries(filesystems);
145 }
146
147 void MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries() {
148 GetMediaFileSystemsForExtension(base::Bind(
149 &MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries, this));
150 }
151
152 void MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries(
153 const std::vector<MediaFileSystemInfo>& filesystems) {
154 content::RenderViewHost* rvh = render_view_host();
155 if (!rvh) {
156 SendResponse(false); 160 SendResponse(false);
157 return; 161 return;
158 } 162 }
163
164 // Controller will delete itself.
vandebo (ex-Chrome) 2013/12/02 18:01:30 nit: move to line 166
Lei Zhang 2013/12/03 03:33:23 Done.
165 base::Closure cb = base::Bind(
vandebo (ex-Chrome) 2013/12/02 18:01:30 nit: cb -> callback. Would it be more consistent
Lei Zhang 2013/12/03 03:33:23 I inlined it, but now it's 5 lines. Meh.
vandebo (ex-Chrome) 2013/12/03 21:08:02 How about: new MediaGalleriesDialogController(
Lei Zhang 2013/12/05 05:52:15 Done.
166 &MediaGalleriesGetMediaFileSystemsBase::GetAndReturnGalleries, this);
167 new MediaGalleriesDialogController(contents, *GetExtension(), cb);
168 }
169
170 void MediaGalleriesGetMediaFileSystemsBase::GetAndReturnGalleries() {
171 GetMediaFileSystemsForExtension(base::Bind(
172 &MediaGalleriesGetMediaFileSystemsBase::ReturnGalleries, this));
173 }
174
175 void MediaGalleriesGetMediaFileSystemsBase::ReturnGalleries(
176 const std::vector<MediaFileSystemInfo>& filesystems) {
177 base::ListValue* list = ConstructFileSystemList(filesystems);
vandebo (ex-Chrome) 2013/12/02 18:01:30 Should this be scoped_ptr<base::ListValue> list ?
Lei Zhang 2013/12/03 03:33:23 Done. We haven't always used scoped_ptrs in all ca
178 if (!list) {
179 SendResponse(false);
vandebo (ex-Chrome) 2013/12/02 18:01:30 The API didn't necessarily fail if there's an empt
Lei Zhang 2013/12/03 03:33:23 This is not the empty list case. |list| is only NU
180 return;
181 }
182
183 SetResult(list);
184 SendResponse(true);
185 }
186
187 base::ListValue* MediaGalleriesGetMediaFileSystemsBase::ConstructFileSystemList(
188 const std::vector<MediaFileSystemInfo>& filesystems) {
189 content::RenderViewHost* rvh = render_view_host();
190 if (!rvh)
191 return NULL;
192
159 MediaGalleriesPermission::CheckParam read_param( 193 MediaGalleriesPermission::CheckParam read_param(
160 MediaGalleriesPermission::kReadPermission); 194 MediaGalleriesPermission::kReadPermission);
161 bool has_read_permission = PermissionsData::CheckAPIPermissionWithParam( 195 bool has_read_permission = PermissionsData::CheckAPIPermissionWithParam(
162 GetExtension(), APIPermission::kMediaGalleries, &read_param); 196 GetExtension(), APIPermission::kMediaGalleries, &read_param);
163 MediaGalleriesPermission::CheckParam copy_to_param( 197 MediaGalleriesPermission::CheckParam copy_to_param(
164 MediaGalleriesPermission::kCopyToPermission); 198 MediaGalleriesPermission::kCopyToPermission);
165 bool has_copy_to_permission = PermissionsData::CheckAPIPermissionWithParam( 199 bool has_copy_to_permission = PermissionsData::CheckAPIPermissionWithParam(
166 GetExtension(), APIPermission::kMediaGalleries, &copy_to_param); 200 GetExtension(), APIPermission::kMediaGalleries, &copy_to_param);
167 MediaGalleriesPermission::CheckParam delete_param( 201 MediaGalleriesPermission::CheckParam delete_param(
168 MediaGalleriesPermission::kDeletePermission); 202 MediaGalleriesPermission::kDeletePermission);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 policy->GrantReadFileSystem(child_id, filesystems[i].fsid); 241 policy->GrantReadFileSystem(child_id, filesystems[i].fsid);
208 if (has_delete_permission) { 242 if (has_delete_permission) {
209 policy->GrantDeleteFromFileSystem(child_id, filesystems[i].fsid); 243 policy->GrantDeleteFromFileSystem(child_id, filesystems[i].fsid);
210 if (has_copy_to_permission) { 244 if (has_copy_to_permission) {
211 policy->GrantCopyIntoFileSystem(child_id, filesystems[i].fsid); 245 policy->GrantCopyIntoFileSystem(child_id, filesystems[i].fsid);
212 } 246 }
213 } 247 }
214 } 248 }
215 } 249 }
216 250
217 // The custom JS binding will use this list to create DOMFileSystem objects. 251 return list;
218 SetResult(list);
219 SendResponse(true);
220 } 252 }
221 253
222 void MediaGalleriesGetMediaFileSystemsFunction::ShowDialog() { 254 void MediaGalleriesGetMediaFileSystemsBase::GetMediaFileSystemsForExtension(
223 media_galleries::UsageCount(media_galleries::SHOW_DIALOG);
224 WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
225 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
226 WebContentsModalDialogManager::FromWebContents(contents);
227 if (!web_contents_modal_dialog_manager) {
228 // If there is no WebContentsModalDialogManager, then this contents is
229 // probably the background page for an app. Try to find a shell window to
230 // host the dialog.
231 apps::ShellWindow* window = apps::ShellWindowRegistry::Get(
232 GetProfile())->GetCurrentShellWindowForApp(GetExtension()->id());
233 if (window) {
234 contents = window->web_contents();
235 } else {
236 // Abort showing the dialog. TODO(estade) Perhaps return an error instead.
237 GetAndReturnGalleries();
238 return;
239 }
240 }
241
242 // Controller will delete itself.
243 base::Closure cb = base::Bind(
244 &MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries, this);
245 new MediaGalleriesDialogController(contents, *GetExtension(), cb);
246 }
247
248 void MediaGalleriesGetMediaFileSystemsFunction::GetMediaFileSystemsForExtension(
249 const MediaFileSystemsCallback& cb) { 255 const MediaFileSystemsCallback& cb) {
250 if (!render_view_host()) { 256 if (!render_view_host()) {
251 cb.Run(std::vector<MediaFileSystemInfo>()); 257 cb.Run(std::vector<MediaFileSystemInfo>());
252 return; 258 return;
253 } 259 }
254 MediaFileSystemRegistry* registry = media_file_system_registry(); 260 DCHECK(GetMediaGalleriesPreferences()->IsInitialized());
255 DCHECK(registry->GetPreferences(GetProfile())->IsInitialized()); 261 media_file_system_registry()->GetMediaFileSystemsForExtension(
256 registry->GetMediaFileSystemsForExtension(
257 render_view_host(), GetExtension(), cb); 262 render_view_host(), GetExtension(), cb);
258 } 263 }
259 264
265 WebContents* MediaGalleriesGetMediaFileSystemsBase::GetWebContents() {
266 WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
267 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
268 WebContentsModalDialogManager::FromWebContents(contents);
269 if (web_contents_modal_dialog_manager)
270 return contents;
271
272 // If there is no WebContentsModalDialogManager, then this contents is
273 // probably the background page for an app. Try to find a shell window to
274 // host the dialog.
275 apps::ShellWindow* window = apps::ShellWindowRegistry::Get(
276 GetProfile())->GetCurrentShellWindowForApp(GetExtension()->id());
277 return window ? window->web_contents() : NULL;
278 }
279
280 MediaGalleriesPreferences*
281 MediaGalleriesGetMediaFileSystemsBase::GetMediaGalleriesPreferences() {
282 return media_file_system_registry()->GetPreferences(GetProfile());
283 }
284
285 void MediaGalleriesGetMediaFileSystemsBase::AlwaysShowDialog(
286 const std::vector<MediaFileSystemInfo>& /*filesystems*/) {
287 ShowDialog();
288 }
289
290
291 MediaGalleriesGetMediaFileSystemsFunction::
292 ~MediaGalleriesGetMediaFileSystemsFunction() {}
293
294 bool MediaGalleriesGetMediaFileSystemsFunction::RunImpl() {
295 if (!ApiIsAccessible(&error_))
296 return false;
297
298 media_galleries::UsageCount(media_galleries::GET_MEDIA_FILE_SYSTEMS);
299 scoped_ptr<GetMediaFileSystems::Params> params(
300 GetMediaFileSystems::Params::Create(*args_));
301 EXTENSION_FUNCTION_VALIDATE(params.get());
302 MediaGalleries::GetMediaFileSystemsInteractivity interactive =
303 MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO;
304 if (params->details.get() && params->details->interactive != MediaGalleries::
305 GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE) {
306 interactive = params->details->interactive;
307 }
308
309 MediaGalleriesPreferences* preferences = GetMediaGalleriesPreferences();
310 preferences->EnsureInitialized(base::Bind(
311 &MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit,
312 this,
313 interactive));
314 return true;
315 }
316
317 void MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit(
318 MediaGalleries::GetMediaFileSystemsInteractivity interactive) {
319 switch (interactive) {
320 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_YES: {
321 ReadPrefsAndShowDialog();
322 return;
323 }
324 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_IF_NEEDED: {
325 GetMediaFileSystemsForExtension(base::Bind(
326 &MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries,
327 this));
328 return;
329 }
330 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO:
331 GetAndReturnGalleries();
332 return;
333 case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE:
334 NOTREACHED();
335 }
336 SendResponse(false);
337 }
338
339 void MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries(
340 const std::vector<MediaFileSystemInfo>& filesystems) {
341 if (filesystems.empty())
342 ShowDialog();
343 else
344 ReturnGalleries(filesystems);
345 }
346
347
260 MediaGalleriesGetAllMediaFileSystemMetadataFunction:: 348 MediaGalleriesGetAllMediaFileSystemMetadataFunction::
261 ~MediaGalleriesGetAllMediaFileSystemMetadataFunction() {} 349 ~MediaGalleriesGetAllMediaFileSystemMetadataFunction() {}
262 350
263 bool MediaGalleriesGetAllMediaFileSystemMetadataFunction::RunImpl() { 351 bool MediaGalleriesGetAllMediaFileSystemMetadataFunction::RunImpl() {
264 if (!ApiIsAccessible(&error_)) 352 if (!ApiIsAccessible(&error_))
265 return false; 353 return false;
266 354
267 media_galleries::UsageCount( 355 media_galleries::UsageCount(
268 media_galleries::GET_ALL_MEDIA_FILE_SYSTEM_METADATA); 356 media_galleries::GET_ALL_MEDIA_FILE_SYSTEM_METADATA);
269 MediaGalleriesPreferences* preferences = 357 MediaGalleriesPreferences* preferences =
270 media_file_system_registry()->GetPreferences(GetProfile()); 358 media_file_system_registry()->GetPreferences(GetProfile());
271 preferences->EnsureInitialized(base::Bind( 359 preferences->EnsureInitialized(base::Bind(
272 &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit, 360 &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit,
273 this)); 361 this));
274 return true; 362 return true;
275 } 363 }
276 364
277 void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit() { 365 void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit() {
278 MediaFileSystemRegistry* registry = media_file_system_registry(); 366 MediaGalleriesPreferences* prefs =
279 MediaGalleriesPreferences* prefs = registry->GetPreferences(GetProfile()); 367 media_file_system_registry()->GetPreferences(GetProfile());
280 DCHECK(prefs->IsInitialized()); 368 DCHECK(prefs->IsInitialized());
281 MediaGalleryPrefIdSet permitted_gallery_ids = 369 MediaGalleryPrefIdSet permitted_gallery_ids =
282 prefs->GalleriesForExtension(*GetExtension()); 370 prefs->GalleriesForExtension(*GetExtension());
283 371
284 MediaStorageUtil::DeviceIdSet* device_ids = new MediaStorageUtil::DeviceIdSet; 372 MediaStorageUtil::DeviceIdSet* device_ids = new MediaStorageUtil::DeviceIdSet;
285 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries(); 373 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
286 for (MediaGalleryPrefIdSet::const_iterator it = permitted_gallery_ids.begin(); 374 for (MediaGalleryPrefIdSet::const_iterator it = permitted_gallery_ids.begin();
287 it != permitted_gallery_ids.end(); ++it) { 375 it != permitted_gallery_ids.end(); ++it) {
288 MediaGalleriesPrefInfoMap::const_iterator gallery_it = galleries.find(*it); 376 MediaGalleriesPrefInfoMap::const_iterator gallery_it = galleries.find(*it);
289 DCHECK(gallery_it != galleries.end()); 377 DCHECK(gallery_it != galleries.end());
290 device_ids->insert(gallery_it->second.device_id); 378 device_ids->insert(gallery_it->second.device_id);
291 } 379 }
292 380
293 MediaStorageUtil::FilterAttachedDevices( 381 MediaStorageUtil::FilterAttachedDevices(
294 device_ids, 382 device_ids,
295 base::Bind( 383 base::Bind(
296 &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries, 384 &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries,
297 this, 385 this,
298 permitted_gallery_ids, 386 permitted_gallery_ids,
299 base::Owned(device_ids))); 387 base::Owned(device_ids)));
300 } 388 }
301 389
302 void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries( 390 void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries(
303 const MediaGalleryPrefIdSet& permitted_gallery_ids, 391 const MediaGalleryPrefIdSet& permitted_gallery_ids,
304 const MediaStorageUtil::DeviceIdSet* available_devices) { 392 const MediaStorageUtil::DeviceIdSet* available_devices) {
305 MediaFileSystemRegistry* registry = media_file_system_registry(); 393 MediaGalleriesPreferences* prefs =
306 MediaGalleriesPreferences* prefs = registry->GetPreferences(GetProfile()); 394 media_file_system_registry()->GetPreferences(GetProfile());
307 395
308 base::ListValue* list = new base::ListValue(); 396 base::ListValue* list = new base::ListValue();
309 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries(); 397 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
310 for (MediaGalleryPrefIdSet::const_iterator it = permitted_gallery_ids.begin(); 398 for (MediaGalleryPrefIdSet::const_iterator it = permitted_gallery_ids.begin();
311 it != permitted_gallery_ids.end(); ++it) { 399 it != permitted_gallery_ids.end(); ++it) {
312 MediaGalleriesPrefInfoMap::const_iterator gallery_it = galleries.find(*it); 400 MediaGalleriesPrefInfoMap::const_iterator gallery_it = galleries.find(*it);
313 DCHECK(gallery_it != galleries.end()); 401 DCHECK(gallery_it != galleries.end());
314 const MediaGalleryPrefInfo& gallery = gallery_it->second; 402 const MediaGalleryPrefInfo& gallery = gallery_it->second;
315 MediaGalleries::MediaFileSystemMetadata metadata; 403 MediaGalleries::MediaFileSystemMetadata metadata;
316 metadata.name = base::UTF16ToUTF8(gallery.GetGalleryDisplayName()); 404 metadata.name = base::UTF16ToUTF8(gallery.GetGalleryDisplayName());
317 metadata.gallery_id = base::Uint64ToString(gallery.pref_id); 405 metadata.gallery_id = base::Uint64ToString(gallery.pref_id);
318 metadata.is_removable = StorageInfo::IsRemovableDevice(gallery.device_id); 406 metadata.is_removable = StorageInfo::IsRemovableDevice(gallery.device_id);
319 metadata.is_media_device = StorageInfo::IsMediaDevice(gallery.device_id); 407 metadata.is_media_device = StorageInfo::IsMediaDevice(gallery.device_id);
320 metadata.is_available = ContainsKey(*available_devices, gallery.device_id); 408 metadata.is_available = ContainsKey(*available_devices, gallery.device_id);
321 list->Append(metadata.ToValue().release()); 409 list->Append(metadata.ToValue().release());
322 } 410 }
323 411
324 SetResult(list); 412 SetResult(list);
325 SendResponse(true); 413 SendResponse(true);
326 } 414 }
327 415
416 MediaGalleriesManageMediaLocationsFunction::
417 ~MediaGalleriesManageMediaLocationsFunction() {}
418
419 bool MediaGalleriesManageMediaLocationsFunction::RunImpl() {
420 if (!ApiIsAccessible(&error_))
421 return false;
422
423 media_galleries::UsageCount(media_galleries::MANAGE_MEDIA_LOCATIONS);
424 scoped_ptr<ManageMediaLocations::Params> params(
425 ManageMediaLocations::Params::Create(*args_));
426 EXTENSION_FUNCTION_VALIDATE(params.get());
427 if (params->details.type == MediaGalleries::MANAGE_REQUEST_TYPE_NONE)
428 EXTENSION_FUNCTION_ERROR(kInvalidManageRequestType); // returns false
429
430 MediaGalleriesPreferences* preferences = GetMediaGalleriesPreferences();
431 preferences->EnsureInitialized(base::Bind(
432 &MediaGalleriesManageMediaLocationsFunction::OnPreferencesInit,
433 this,
434 params->details.type));
435 return true;
436 }
437
438 void MediaGalleriesManageMediaLocationsFunction::OnPreferencesInit(
439 MediaGalleries::ManageRequestType request_type) {
440 switch (request_type) {
441 case MediaGalleries::MANAGE_REQUEST_TYPE_MANAGE: {
442 ReadPrefsAndShowDialog();
443 return;
444 }
445 case MediaGalleries::MANAGE_REQUEST_TYPE_DIRECTORY_PROMPT: {
446 WebContents* contents = GetWebContents();
447 if (!contents) {
448 SendResponse(false);
449 return;
450 }
451 SelectDirectoryDialog::Callback cb = base::Bind(
452 &MediaGalleriesManageMediaLocationsFunction::OnDirectorySelected,
453 this);
454 scoped_refptr<SelectDirectoryDialog> select_directory_dialog =
455 new SelectDirectoryDialog(contents, cb);
456 select_directory_dialog->Show();
457 return;
458 }
459 case MediaGalleries::MANAGE_REQUEST_TYPE_NONE:
460 NOTREACHED();
461 }
462 SendResponse(false);
463 }
464
465 void MediaGalleriesManageMediaLocationsFunction::OnDirectorySelected(
466 const base::FilePath& selected_directory) {
467 if (selected_directory.empty()) {
468 base::ListValue* empty_list = new base::ListValue();
vandebo (ex-Chrome) 2013/12/02 18:01:30 nit: inline in next line
Lei Zhang 2013/12/03 03:33:23 Done.
469 SetResult(empty_list);
470 SendResponse(true);
471 return;
472 }
473
474 bool posted = base::PostTaskAndReplyWithResult(
vandebo (ex-Chrome) 2013/12/02 18:01:30 This appears to be different than MediaGalleriesDi
Lei Zhang 2013/12/03 03:33:23 MediaGalleriesDialogController::FileSelected has t
475 content::BrowserThread::GetBlockingPool(),
476 FROM_HERE,
477 base::Bind(&base::PathExists, selected_directory),
478 base::Bind(
479 &MediaGalleriesManageMediaLocationsFunction::OnDirectoryChecked,
480 this,
481 selected_directory));
482 if (posted)
483 return;
484 SendResponse(false);
485 }
486
487 void MediaGalleriesManageMediaLocationsFunction::OnDirectoryChecked(
488 const base::FilePath& selected_directory, bool exists) {
489 DCHECK(!selected_directory.empty());
490
491 if (!exists) {
492 SendResponse(false);
493 return;
494 }
495
496 MediaGalleryPrefInfo gallery;
497 MediaGalleriesPreferences* preferences = GetMediaGalleriesPreferences();
498 MediaGalleryPrefId pref_id =
499 preferences->AddGalleryByPath(selected_directory);
500 preferences->SetGalleryPermissionForExtension(*GetExtension(), pref_id, true);
501
502 GetMediaFileSystemsForExtension(base::Bind(
503 &MediaGalleriesManageMediaLocationsFunction::FindGalleryWithPrefId,
504 this,
505 pref_id));
506 }
507
508 void MediaGalleriesManageMediaLocationsFunction::FindGalleryWithPrefId(
509 MediaGalleryPrefId pref_id,
510 const std::vector<MediaFileSystemInfo>& filesystems) {
511 for (size_t i = 0; i < filesystems.size(); i++) {
512 if (filesystems[i].pref_id == pref_id) {
513 std::vector<MediaFileSystemInfo> found_filesystem;
514 found_filesystem.push_back(filesystems[i]);
515 base::ListValue* list = ConstructFileSystemList(found_filesystem);
vandebo (ex-Chrome) 2013/12/02 18:01:30 Ahh, I see - you're returning a set of zero or one
Lei Zhang 2013/12/03 03:33:23 Leaving this one open. I'll check tomorrow if file
516 if (!list)
517 break;
518
519 SetResult(list);
520 SendResponse(true);
521 return;
522 }
523 }
524 SendResponse(false);
525 }
526
328 } // namespace extensions 527 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698