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

Unified Diff: chrome/browser/devtools/devtools_file_system_helper.cc

Issue 11570081: Support file system access in DevTools with isolated file system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/devtools/devtools_file_system_helper.cc
diff --git a/chrome/browser/devtools/devtools_file_system_helper.cc b/chrome/browser/devtools/devtools_file_system_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1d6214c27c0e3109fed0f2d684f820ca29bfcf5f
--- /dev/null
+++ b/chrome/browser/devtools/devtools_file_system_helper.cc
@@ -0,0 +1,273 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/devtools/devtools_file_system_helper.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/chrome_select_file_policy.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "grit/generated_resources.h"
+#include "ui/base/dialogs/select_file_dialog.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "webkit/fileapi/isolated_context.h"
+
+using content::BrowserThread;
+using content::RenderViewHost;
+using content::WebContents;
+
+namespace {
+ const char kSecurityFileName[] = ".allow-devtools-edit";
+}
+
+class DevToolsFileSystemHelper::SelectFolderDialog
pfeldman 2012/12/24 19:01:03 This class is almost exactly the same as the one i
+ : public ui::SelectFileDialog::Listener,
+ public base::RefCounted<SelectFolderDialog> {
+ public:
+ explicit SelectFolderDialog(DevToolsFileSystemHelper* helper)
+ : helper_(helper) {
+ select_file_dialog_ = ui::SelectFileDialog::Create(
+ this, new ChromeSelectFilePolicy(NULL));
+ }
+
+ void ResetHelper() {
+ helper_ = NULL;
+ }
+
+ void Show() {
+ AddRef(); // Balanced in the three listener outcomes.
+ select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_FOLDER,
+ string16(),
+ FilePath(),
+ NULL,
+ 0,
+ FILE_PATH_LITERAL(""),
+ NULL,
+ NULL);
+ }
+
+ // ui::SelectFileDialog::Listener implementation.
+ virtual void FileSelected(const FilePath& path,
+ int index, void* params) {
+ if (helper_)
+ helper_->FolderSelected(path);
+ Release(); // Balanced in ::Show.
+ }
+
+ virtual void MultiFilesSelected(
+ const std::vector<FilePath>& files, void* params) {
+ Release(); // Balanced in ::Show.
+ NOTREACHED() << "Should not be able to select multiple files";
+ }
+
+ virtual void FileSelectionCanceled(void* params) {
+ if (helper_)
+ helper_->FolderSelectionCanceled();
+ Release(); // Balanced in ::Show.
+ }
+
+ private:
+ friend class base::RefCounted<SelectFolderDialog>;
+ virtual ~SelectFolderDialog() {}
+
+ scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+ DevToolsFileSystemHelper* helper_;
+};
+
+DevToolsFileSystemHelper::FileSystem::FileSystem(
+ const std::string& filesystem_id,
+ const std::string& registered_name,
+ const std::string& file_system_path)
+ : filesystem_id(filesystem_id),
+ registered_name(registered_name),
+ file_system_path(file_system_path) {
+}
+
+DevToolsFileSystemHelper::DevToolsFileSystemHelper(
+ WebContents* web_contents,
+ Profile* profile,
+ Delegate* delegate)
+ : web_contents_(web_contents),
+ profile_(profile),
+ delegate_(delegate) {
+}
+
+DevToolsFileSystemHelper::~DevToolsFileSystemHelper() {
+ if (select_folder_dialog_)
+ select_folder_dialog_->ResetHelper();
+}
+
+namespace {
+
+fileapi::IsolatedContext* isolated_context() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ fileapi::IsolatedContext* isolated_context =
+ fileapi::IsolatedContext::GetInstance();
+ DCHECK(isolated_context);
+ return isolated_context;
+}
+
+std::string RegisterFileSystem(WebContents* web_contents,
+ const FilePath& path,
+ std::string* registered_name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ std::string file_system_id = isolated_context()->RegisterFileSystemForPath(
+ fileapi::kFileSystemTypeNativeLocal, path, registered_name);
+
+ content::ChildProcessSecurityPolicy* policy =
+ content::ChildProcessSecurityPolicy::GetInstance();
+ RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
+ int renderer_id = render_view_host->GetProcess()->GetID();
+ policy->GrantReadWriteFileSystem(renderer_id, file_system_id);
+
+ // We only need file level access for reading FileEntries. Saving FileEntries
+ // just needs the file system to have read/write access, which is granted
+ // above if required.
+ if (!policy->CanReadFile(renderer_id, path))
+ policy->GrantReadFile(renderer_id, path);
+
+ return file_system_id;
+}
+
+bool CheckSecurityFileExistsInFolder(const FilePath& path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ FilePath security_file_path = path.Append(
+ FILE_PATH_LITERAL(kSecurityFileName));
+ return file_util::PathExists(security_file_path);
+}
+
+} // namespace
+
+void DevToolsFileSystemHelper::SelectFolderAndGrantPermission() {
+ if (select_folder_dialog_)
+ select_folder_dialog_->ResetHelper();
+ select_folder_dialog_ = new SelectFolderDialog(this);
+ select_folder_dialog_->Show();
+}
+
+void DevToolsFileSystemHelper::FolderSelected(const FilePath& path) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&DevToolsFileSystemHelper::CheckSelectedPath, this, path));
+}
+
+void DevToolsFileSystemHelper::FolderSelectionCanceled() {
+ delegate_->FileSystemFolderSelectionCanceled();
+}
+
+void DevToolsFileSystemHelper::CheckSelectedPath(const FilePath& path) {
+ if (!CheckSecurityFileExistsInFolder(path)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DevToolsFileSystemHelper::SelectedFileSystemForbidden,
+ this));
+ return;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DevToolsFileSystemHelper::SelectedFileSystemPermitted,
+ this,
+ path));
+}
+
+void DevToolsFileSystemHelper::SelectedFileSystemPermitted(
+ const FilePath& path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ std::string registered_name;
+ std::string file_system_id = RegisterFileSystem(web_contents_,
+ path,
+ &registered_name);
+ std::string file_system_path = path.AsUTF8Unsafe();
+
+ DictionaryPrefUpdate update(profile_->GetPrefs(),
+ prefs::kDevToolsSavedFileSystemPathes);
+ DictionaryValue* file_systems_pathes_value = update.Get();
+ file_systems_pathes_value->Set(file_system_path, Value::CreateNullValue());
+
+ FileSystem file_system(file_system_id, registered_name, file_system_path);
+ delegate_->FileSystemFolderSelected(file_system);
+}
+
+void DevToolsFileSystemHelper::SelectedFileSystemForbidden() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ std::string error_string = l10n_util::GetStringFUTF8(
+ IDS_DEV_TOOLS_FILE_SYSTEM_SECURITY_FILE_NOT_EXISTS_MESSAGE,
+ UTF8ToUTF16(kSecurityFileName));
+ delegate_->FileSystemFolderSelectionError(error_string);
+}
+
+void DevToolsFileSystemHelper::RequestPermissions() {
+ const DictionaryValue* file_systems_pathes_value =
+ profile_->GetPrefs()->GetDictionary(
+ prefs::kDevToolsSavedFileSystemPathes);
+ std::vector<FilePath> saved_pathes;
+ DictionaryValue::key_iterator it = file_systems_pathes_value->begin_keys();
+ for (; it != file_systems_pathes_value->end_keys(); ++it) {
+ std::string file_system_path = *it;
+ FilePath path = FilePath::FromUTF8Unsafe(file_system_path);
+ saved_pathes.push_back(path);
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&DevToolsFileSystemHelper::CheckSavedPathes,
+ this,
+ saved_pathes));
+}
+
+void DevToolsFileSystemHelper::CheckSavedPathes(
+ const std::vector<FilePath>& file_pathes) {
+ std::vector<FilePath> permitted_pathes;
+ std::vector<FilePath>::const_iterator it;
+ for (it = file_pathes.begin(); it != file_pathes.end(); ++it) {
+ if (CheckSecurityFileExistsInFolder(*it))
+ permitted_pathes.push_back(*it);
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&DevToolsFileSystemHelper::RegisterSavedFileSystems,
+ this,
+ permitted_pathes));
+}
+
+void DevToolsFileSystemHelper::RegisterSavedFileSystems(
+ const std::vector<FilePath>& file_pathes) {
+ std::vector<FileSystem> file_systems;
+ std::vector<FilePath>::const_iterator it;
+ for (it = file_pathes.begin(); it != file_pathes.end(); ++it) {
+ std::string registered_name;
+ std::string file_system_id = RegisterFileSystem(web_contents_,
+ *it,
+ &registered_name);
+ std::string file_system_path = it->AsUTF8Unsafe();
+ FileSystem file_system(file_system_id, registered_name, file_system_path);
+ file_systems.push_back(file_system);
+ }
+ delegate_->FileSystemPermissionsLoaded(file_systems);
+}
+
+void DevToolsFileSystemHelper::RevokePermission(
+ const std::string& file_system_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ FilePath path = FilePath::FromUTF8Unsafe(file_system_path);
+ isolated_context()->RevokeFileSystemByPath(path);
+
+ DictionaryPrefUpdate update(profile_->GetPrefs(),
+ prefs::kDevToolsSavedFileSystemPathes);
+ DictionaryValue* file_systems_pathes_value = update.Get();
+ file_systems_pathes_value->RemoveWithoutPathExpansion(file_system_path, NULL);
+}

Powered by Google App Engine
This is Rietveld 408576698