Chromium Code Reviews| OLD | NEW |
|---|---|
| 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, ©_to_param); | 200 GetExtension(), APIPermission::kMediaGalleries, ©_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 Loading... | |
| 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 |
| OLD | NEW |