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

Unified 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: fix selected folder name Created 6 years, 11 months 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
===================================================================
--- chrome/browser/extensions/api/media_galleries/media_galleries_api.cc (revision 243958)
+++ chrome/browser/extensions/api/media_galleries/media_galleries_api.cc (working copy)
@@ -18,11 +18,14 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/api/file_system/file_system_api.h"
#include "chrome/browser/extensions/blob_reader.h"
+#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/media_galleries/media_file_system_registry.h"
#include "chrome/browser/media_galleries/media_galleries_dialog_controller.h"
#include "chrome/browser/media_galleries/media_galleries_histograms.h"
#include "chrome/browser/media_galleries/media_galleries_preferences.h"
+#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
@@ -35,10 +38,13 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
#include "extensions/common/extension.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permissions_data.h"
+#include "grit/generated_resources.h"
#include "net/base/mime_sniffer.h"
+#include "ui/base/l10n/l10n_util.h"
using content::WebContents;
using web_modal::WebContentsModalDialogManager;
@@ -76,6 +82,146 @@
return g_browser_process->media_file_system_registry();
}
+WebContents* GetWebContents(content::RenderViewHost* rvh,
+ Profile* profile,
+ const std::string& app_id) {
+ WebContents* contents = WebContents::FromRenderViewHost(rvh);
+ WebContentsModalDialogManager* web_contents_modal_dialog_manager =
+ WebContentsModalDialogManager::FromWebContents(contents);
+ if (!web_contents_modal_dialog_manager) {
+ // If there is no WebContentsModalDialogManager, then this contents is
+ // probably the background page for an app. Try to find a shell window to
+ // host the dialog.
+ apps::ShellWindow* window = apps::ShellWindowRegistry::Get(
+ profile)->GetCurrentShellWindowForApp(app_id);
+ contents = window ? window->web_contents() : NULL;
+ }
+ return contents;
+}
+
+base::ListValue* ConstructFileSystemList(
+ content::RenderViewHost* rvh,
+ const Extension* extension,
+ const std::vector<MediaFileSystemInfo>& filesystems) {
+ if (!rvh)
+ return NULL;
+
+ MediaGalleriesPermission::CheckParam read_param(
+ MediaGalleriesPermission::kReadPermission);
+ bool has_read_permission = PermissionsData::CheckAPIPermissionWithParam(
+ extension, APIPermission::kMediaGalleries, &read_param);
+ MediaGalleriesPermission::CheckParam copy_to_param(
+ MediaGalleriesPermission::kCopyToPermission);
+ bool has_copy_to_permission = PermissionsData::CheckAPIPermissionWithParam(
+ extension, APIPermission::kMediaGalleries, &copy_to_param);
+ MediaGalleriesPermission::CheckParam delete_param(
+ MediaGalleriesPermission::kDeletePermission);
+ bool has_delete_permission = PermissionsData::CheckAPIPermissionWithParam(
+ extension, APIPermission::kMediaGalleries, &delete_param);
+
+ const int child_id = rvh->GetProcess()->GetID();
+ scoped_ptr<base::ListValue> list(new base::ListValue());
+ for (size_t i = 0; i < filesystems.size(); ++i) {
+ scoped_ptr<base::DictionaryValue> file_system_dict_value(
+ new base::DictionaryValue());
+
+ // Send the file system id so the renderer can create a valid FileSystem
+ // object.
+ file_system_dict_value->SetStringWithoutPathExpansion(
+ "fsid", filesystems[i].fsid);
+
+ file_system_dict_value->SetStringWithoutPathExpansion(
+ kNameKey, filesystems[i].name);
+ file_system_dict_value->SetStringWithoutPathExpansion(
+ kGalleryIdKey,
+ base::Uint64ToString(filesystems[i].pref_id));
+ if (!filesystems[i].transient_device_id.empty()) {
+ file_system_dict_value->SetStringWithoutPathExpansion(
+ kDeviceIdKey, filesystems[i].transient_device_id);
+ }
+ file_system_dict_value->SetBooleanWithoutPathExpansion(
+ kIsRemovableKey, filesystems[i].removable);
+ file_system_dict_value->SetBooleanWithoutPathExpansion(
+ kIsMediaDeviceKey, filesystems[i].media_device);
+ file_system_dict_value->SetBooleanWithoutPathExpansion(
+ kIsAvailableKey, true);
+
+ list->Append(file_system_dict_value.release());
+
+ if (filesystems[i].path.empty())
+ continue;
+
+ if (has_read_permission) {
+ content::ChildProcessSecurityPolicy* policy =
+ content::ChildProcessSecurityPolicy::GetInstance();
+ policy->GrantReadFileSystem(child_id, filesystems[i].fsid);
+ if (has_delete_permission) {
+ policy->GrantDeleteFromFileSystem(child_id, filesystems[i].fsid);
+ if (has_copy_to_permission) {
+ policy->GrantCopyIntoFileSystem(child_id, filesystems[i].fsid);
+ }
+ }
+ }
+ }
+
+ return list.release();
+}
+
+class SelectDirectoryDialog : public ui::SelectFileDialog::Listener,
+ public base::RefCounted<SelectDirectoryDialog> {
+ public:
+ // Selected file path, or an empty path if the user canceled.
+ typedef base::Callback<void(const base::FilePath&)> Callback;
+
+ SelectDirectoryDialog(WebContents* web_contents, const Callback& callback)
+ : web_contents_(web_contents),
+ callback_(callback) {
+ select_file_dialog_ = ui::SelectFileDialog::Create(
+ this, new ChromeSelectFilePolicy(web_contents));
+ }
+
+ void Show(const base::FilePath& default_path) {
+ AddRef(); // Balanced in the two reachable listener outcomes.
+ select_file_dialog_->SelectFile(
+ ui::SelectFileDialog::SELECT_FOLDER,
+ l10n_util::GetStringUTF16(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY_TITLE),
+ default_path,
+ NULL,
+ 0,
+ base::FilePath::StringType(),
+ platform_util::GetTopLevel(web_contents_->GetView()->GetNativeView()),
+ NULL);
+ }
+
+ // ui::SelectFileDialog::Listener implementation.
+ virtual void FileSelected(const base::FilePath& path,
+ int index,
+ void* params) OVERRIDE {
+ callback_.Run(path);
+ Release(); // Balanced in Show().
+ }
+
+ virtual void MultiFilesSelected(const std::vector<base::FilePath>& files,
+ void* params) OVERRIDE {
+ NOTREACHED() << "Should not be able to select multiple files";
+ }
+
+ virtual void FileSelectionCanceled(void* params) OVERRIDE {
+ callback_.Run(base::FilePath());
+ Release(); // Balanced in Show().
+ }
+
+ private:
+ friend class base::RefCounted<SelectDirectoryDialog>;
+ virtual ~SelectDirectoryDialog() {}
+
+ scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+ WebContents* web_contents_;
+ Callback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(SelectDirectoryDialog);
+};
+
} // namespace
MediaGalleriesGetMediaFileSystemsFunction::
@@ -153,96 +299,28 @@
void MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries(
const std::vector<MediaFileSystemInfo>& filesystems) {
- content::RenderViewHost* rvh = render_view_host();
- if (!rvh) {
+ scoped_ptr<base::ListValue> list(
+ ConstructFileSystemList(render_view_host(), GetExtension(), filesystems));
+ if (!list.get()) {
SendResponse(false);
return;
}
- MediaGalleriesPermission::CheckParam read_param(
- MediaGalleriesPermission::kReadPermission);
- bool has_read_permission = PermissionsData::CheckAPIPermissionWithParam(
- GetExtension(), APIPermission::kMediaGalleries, &read_param);
- MediaGalleriesPermission::CheckParam copy_to_param(
- MediaGalleriesPermission::kCopyToPermission);
- bool has_copy_to_permission = PermissionsData::CheckAPIPermissionWithParam(
- GetExtension(), APIPermission::kMediaGalleries, &copy_to_param);
- MediaGalleriesPermission::CheckParam delete_param(
- MediaGalleriesPermission::kDeletePermission);
- bool has_delete_permission = PermissionsData::CheckAPIPermissionWithParam(
- GetExtension(), APIPermission::kMediaGalleries, &delete_param);
- const int child_id = rvh->GetProcess()->GetID();
- base::ListValue* list = new base::ListValue();
- for (size_t i = 0; i < filesystems.size(); i++) {
- scoped_ptr<base::DictionaryValue> file_system_dict_value(
- new base::DictionaryValue());
-
- // Send the file system id so the renderer can create a valid FileSystem
- // object.
- file_system_dict_value->SetStringWithoutPathExpansion(
- "fsid", filesystems[i].fsid);
-
- file_system_dict_value->SetStringWithoutPathExpansion(
- kNameKey, filesystems[i].name);
- file_system_dict_value->SetStringWithoutPathExpansion(
- kGalleryIdKey,
- base::Uint64ToString(filesystems[i].pref_id));
- if (!filesystems[i].transient_device_id.empty()) {
- file_system_dict_value->SetStringWithoutPathExpansion(
- kDeviceIdKey, filesystems[i].transient_device_id);
- }
- file_system_dict_value->SetBooleanWithoutPathExpansion(
- kIsRemovableKey, filesystems[i].removable);
- file_system_dict_value->SetBooleanWithoutPathExpansion(
- kIsMediaDeviceKey, filesystems[i].media_device);
- file_system_dict_value->SetBooleanWithoutPathExpansion(
- kIsAvailableKey, true);
-
- list->Append(file_system_dict_value.release());
-
- if (filesystems[i].path.empty())
- continue;
-
- if (has_read_permission) {
- content::ChildProcessSecurityPolicy* policy =
- content::ChildProcessSecurityPolicy::GetInstance();
- policy->GrantReadFileSystem(child_id, filesystems[i].fsid);
- if (has_delete_permission) {
- policy->GrantDeleteFromFileSystem(child_id, filesystems[i].fsid);
- if (has_copy_to_permission) {
- policy->GrantCopyIntoFileSystem(child_id, filesystems[i].fsid);
- }
- }
- }
- }
-
// The custom JS binding will use this list to create DOMFileSystem objects.
- SetResult(list);
+ SetResult(list.release());
SendResponse(true);
}
void MediaGalleriesGetMediaFileSystemsFunction::ShowDialog() {
media_galleries::UsageCount(media_galleries::SHOW_DIALOG);
- WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
- WebContentsModalDialogManager* web_contents_modal_dialog_manager =
- WebContentsModalDialogManager::FromWebContents(contents);
- if (!web_contents_modal_dialog_manager) {
- // If there is no WebContentsModalDialogManager, then this contents is
- // probably the background page for an app. Try to find a shell window to
- // host the dialog.
- apps::ShellWindow* window = apps::ShellWindowRegistry::Get(
- GetProfile())->GetCurrentShellWindowForApp(GetExtension()->id());
- if (!window) {
- SendResponse(false);
- return;
- }
- contents = window->web_contents();
- }
+ const Extension* extension = GetExtension();
+ WebContents* contents =
+ GetWebContents(render_view_host(), GetProfile(), extension->id());
// Controller will delete itself.
base::Closure cb = base::Bind(
&MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries, this);
- new MediaGalleriesDialogController(contents, *GetExtension(), cb);
+ new MediaGalleriesDialogController(contents, *extension, cb);
}
void MediaGalleriesGetMediaFileSystemsFunction::GetMediaFileSystemsForExtension(
@@ -325,6 +403,103 @@
SendResponse(true);
}
+MediaGalleriesAddUserSelectedFolderFunction::
+ ~MediaGalleriesAddUserSelectedFolderFunction() {}
+
+bool MediaGalleriesAddUserSelectedFolderFunction::RunImpl() {
+ if (!ApiIsAccessible(&error_))
+ return false;
+
+ media_galleries::UsageCount(media_galleries::ADD_USER_SELECTED_FOLDER);
+ MediaGalleriesPreferences* preferences =
+ media_file_system_registry()->GetPreferences(GetProfile());
+ preferences->EnsureInitialized(base::Bind(
+ &MediaGalleriesAddUserSelectedFolderFunction::OnPreferencesInit,
+ this));
+ return true;
+}
+
+void MediaGalleriesAddUserSelectedFolderFunction::OnPreferencesInit() {
+ Profile* profile = GetProfile();
+ const std::string& app_id = GetExtension()->id();
+ WebContents* contents = GetWebContents(render_view_host(), profile, app_id);
+ base::FilePath last_used_path =
+ extensions::file_system_api::GetLastChooseEntryDirectory(
+ extensions::ExtensionPrefs::Get(profile), app_id);
+ SelectDirectoryDialog::Callback callback = base::Bind(
+ &MediaGalleriesAddUserSelectedFolderFunction::OnDirectorySelected, this);
+ scoped_refptr<SelectDirectoryDialog> select_directory_dialog =
+ new SelectDirectoryDialog(contents, callback);
+ select_directory_dialog->Show(last_used_path);
+}
+
+void MediaGalleriesAddUserSelectedFolderFunction::OnDirectorySelected(
+ const base::FilePath& selected_directory) {
+ if (selected_directory.empty()) {
+ // User cancelled case.
+ GetMediaFileSystemsForExtension(base::Bind(
+ &MediaGalleriesAddUserSelectedFolderFunction::ReturnGalleriesAndId,
+ this,
+ kInvalidMediaGalleryPrefId));
+ return;
+ }
+
+ extensions::file_system_api::SetLastChooseEntryDirectory(
+ extensions::ExtensionPrefs::Get(GetProfile()),
+ GetExtension()->id(),
+ selected_directory);
+
+ MediaGalleriesPreferences* preferences =
+ media_file_system_registry()->GetPreferences(GetProfile());
+ MediaGalleryPrefId pref_id =
+ preferences->AddGalleryByPath(selected_directory);
+ preferences->SetGalleryPermissionForExtension(*GetExtension(), pref_id, true);
+
+ GetMediaFileSystemsForExtension(base::Bind(
+ &MediaGalleriesAddUserSelectedFolderFunction::ReturnGalleriesAndId,
+ this,
+ pref_id));
+}
+
+void MediaGalleriesAddUserSelectedFolderFunction::ReturnGalleriesAndId(
+ MediaGalleryPrefId pref_id,
+ const std::vector<MediaFileSystemInfo>& filesystems) {
+ scoped_ptr<base::ListValue> list(
+ ConstructFileSystemList(render_view_host(), GetExtension(), filesystems));
+ if (!list.get()) {
+ SendResponse(false);
+ return;
+ }
+
+ int index = -1;
+ if (pref_id != kInvalidMediaGalleryPrefId) {
+ for (size_t i = 0; i < filesystems.size(); ++i) {
+ if (filesystems[i].pref_id == pref_id) {
+ index = i;
+ break;
+ }
+ }
+ }
+ base::DictionaryValue* results = new base::DictionaryValue;
+ results->SetWithoutPathExpansion("mediaFileSystems", list.release());
+ results->SetIntegerWithoutPathExpansion("selectedFileSystemIndex", index);
+ SetResult(results);
+ SendResponse(true);
+}
+
+void
+MediaGalleriesAddUserSelectedFolderFunction::GetMediaFileSystemsForExtension(
+ const MediaFileSystemsCallback& cb) {
+ if (!render_view_host()) {
+ cb.Run(std::vector<MediaFileSystemInfo>());
+ return;
+ }
+ MediaFileSystemRegistry* registry = media_file_system_registry();
+ DCHECK(registry->GetPreferences(GetProfile())->IsInitialized());
+ registry->GetMediaFileSystemsForExtension(
+ render_view_host(), GetExtension(), cb);
+}
+
MediaGalleriesGetMetadataFunction::~MediaGalleriesGetMetadataFunction() {}
bool MediaGalleriesGetMetadataFunction::RunImpl() {

Powered by Google App Engine
This is Rietveld 408576698