summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvsevik@chromium.org <vsevik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-16 11:12:11 +0000
committervsevik@chromium.org <vsevik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-16 11:12:11 +0000
commite492a806bbabddec3a6ce3993a837c0abdf06fe3 (patch)
tree4d70b9aa3411ae1c3cef06065260c6959a9336e9
parent0b16743dbb749e5f7a6194d30810500a19d4edfc (diff)
downloadchromium_src-e492a806bbabddec3a6ce3993a837c0abdf06fe3.zip
chromium_src-e492a806bbabddec3a6ce3993a837c0abdf06fe3.tar.gz
chromium_src-e492a806bbabddec3a6ce3993a837c0abdf06fe3.tar.bz2
Support file system access in DevTools with isolated file system.
BUG=167511 TBR=jam@chromium.org Review URL: https://chromiumcodereview.appspot.com/11570081 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177130 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd5
-rw-r--r--chrome/browser/devtools/devtools_file_helper.cc210
-rw-r--r--chrome/browser/devtools/devtools_file_helper.h55
-rw-r--r--chrome/browser/devtools/devtools_window.cc84
-rw-r--r--chrome/browser/devtools/devtools_window.h10
-rw-r--r--chrome/common/pref_names.cc3
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--content/browser/devtools/devtools_frontend_host.cc17
-rw-r--r--content/browser/devtools/devtools_frontend_host.h3
-rw-r--r--content/common/devtools_messages.h10
-rw-r--r--content/public/browser/devtools_frontend_host_delegate.h9
-rw-r--r--content/renderer/devtools/devtools_client.cc14
-rw-r--r--content/renderer/devtools/devtools_client.h5
13 files changed, 408 insertions, 18 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 6054498..fdade63 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4184,6 +4184,11 @@ Public Exponent (<ph name="PUBLIC_EXPONENT_NUM_BITS">$3<ex>24</ex></ph> bits):
"<ph name="CLIENT_NAME">$1<ex>Extension Foo</ex></ph>" is debugging this tab.
</message>
+ <!-- DevTools file system access -->
+ <message name="IDS_DEV_TOOLS_MAGIC_FILE_NOT_EXISTS_MESSAGE" desc="Message that is shown in DevTools when user selects file system folder without security file while adding file system to DevTools.">
+ The selected folder should contain an empty file with the following name: "$1".
+ </message>
+
<!-- Advanced reload button menu -->
<message name="IDS_RELOAD_MENU_NORMAL_RELOAD_ITEM" desc="Menu item displayed in the Reload dropdown menu when in dev mode">
Normal Reload
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index 945de5f..5605008 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -11,6 +11,7 @@
#include "base/file_util.h"
#include "base/lazy_instance.h"
#include "base/md5.h"
+#include "base/utf_string_conversions.h"
#include "base/value_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_prefs.h"
@@ -21,14 +22,25 @@
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/download_manager.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 "content/public/common/content_client.h"
+#include "grit/generated_resources.h"
#include "ui/base/dialogs/select_file_dialog.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "webkit/fileapi/file_system_util.h"
+#include "webkit/fileapi/isolated_context.h"
using base::Bind;
using base::Callback;
using content::BrowserContext;
using content::BrowserThread;
using content::DownloadManager;
+using content::RenderViewHost;
+using content::WebContents;
namespace {
@@ -42,6 +54,9 @@ namespace {
typedef Callback<void(const FilePath&)> SelectedCallback;
typedef Callback<void(void)> CanceledCallback;
+const FilePath::CharType kMagicFileName[] =
+ FILE_PATH_LITERAL(".allow-devtools-edit");
+
class SelectFileDialog : public ui::SelectFileDialog::Listener,
public base::RefCounted<SelectFileDialog> {
public:
@@ -106,10 +121,89 @@ void AppendToFile(const FilePath& path, const std::string& content) {
file_util::AppendToFile(path, content.c_str(), content.length());
}
+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));
+ CHECK(content::GetContentClient()->HasWebUIScheme(web_contents->GetURL()));
+ 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;
+}
+
+typedef Callback<void(const std::vector<FilePath>&)> ValidateFoldersCallback;
+
+void ValidateFoldersOnFileThread(const std::vector<FilePath>& file_paths,
+ const ValidateFoldersCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ std::vector<FilePath> permitted_paths;
+ std::vector<FilePath>::const_iterator it;
+ for (it = file_paths.begin(); it != file_paths.end(); ++it) {
+ FilePath security_file_path = it->Append(kMagicFileName);
+ if (file_util::PathExists(security_file_path))
+ permitted_paths.push_back(*it);
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ Bind(callback, permitted_paths));
+}
+
+DevToolsFileHelper::FileSystem CreateFileSystemStruct(
+ WebContents* web_contents,
+ const std::string& file_system_id,
+ const std::string& registered_name,
+ const std::string& file_system_path) {
+ const GURL origin = web_contents->GetURL().GetOrigin();
+ std::string file_system_name = fileapi::GetIsolatedFileSystemName(
+ origin,
+ file_system_id);
+ std::string root_url = fileapi::GetIsolatedFileSystemRootURIString(
+ origin,
+ file_system_id,
+ registered_name);
+ return DevToolsFileHelper::FileSystem(file_system_name,
+ root_url,
+ file_system_path);
+}
+
} // namespace
-DevToolsFileHelper::DevToolsFileHelper(Profile* profile) : profile_(profile),
- weak_factory_(this) {
+DevToolsFileHelper::FileSystem::FileSystem() {
+}
+
+DevToolsFileHelper::FileSystem::FileSystem(const std::string& file_system_name,
+ const std::string& root_url,
+ const std::string& file_system_path)
+ : file_system_name(file_system_name),
+ root_url(root_url),
+ file_system_path(file_system_path) {
+}
+
+DevToolsFileHelper::DevToolsFileHelper(WebContents* web_contents,
+ Profile* profile)
+ : web_contents_(web_contents),
+ profile_(profile),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
}
DevToolsFileHelper::~DevToolsFileHelper() {
@@ -171,7 +265,7 @@ void DevToolsFileHelper::Append(const std::string& url,
return;
callback.Run();
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&AppendToFile, it->second, content));
+ Bind(&AppendToFile, it->second, content));
}
void DevToolsFileHelper::SaveAsFileSelected(const std::string& url,
@@ -188,8 +282,116 @@ void DevToolsFileHelper::SaveAsFileSelected(const std::string& url,
base::CreateFilePathValue(path));
callback.Run();
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&WriteToFile, path, content));
+ Bind(&WriteToFile, path, content));
}
void DevToolsFileHelper::SaveAsFileSelectionCanceled() {
}
+
+void DevToolsFileHelper::AddFileSystem(const AddFileSystemCallback& callback) {
+ scoped_refptr<SelectFileDialog> select_file_dialog = new SelectFileDialog(
+ Bind(&DevToolsFileHelper::InnerAddFileSystem,
+ weak_factory_.GetWeakPtr(),
+ callback),
+ Bind(callback, "", FileSystem()));
+ select_file_dialog->Show(ui::SelectFileDialog::SELECT_FOLDER, FilePath());
+}
+
+void DevToolsFileHelper::InnerAddFileSystem(
+ const AddFileSystemCallback& callback,
+ const FilePath& path) {
+ std::vector<FilePath> file_paths(1, path);
+ ValidateFoldersCallback validate_folders_callback = Bind(
+ &DevToolsFileHelper::AddValidatedFileSystem,
+ weak_factory_.GetWeakPtr(),
+ callback);
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ Bind(&ValidateFoldersOnFileThread,
+ file_paths,
+ validate_folders_callback));
+}
+
+void DevToolsFileHelper::AddValidatedFileSystem(
+ const AddFileSystemCallback& callback,
+ const std::vector<FilePath>& permitted_paths) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (permitted_paths.empty()) {
+ std::string magic_file_name = FilePath(kMagicFileName).AsUTF8Unsafe();
+ std::string error_string = l10n_util::GetStringFUTF8(
+ IDS_DEV_TOOLS_MAGIC_FILE_NOT_EXISTS_MESSAGE,
+ UTF8ToUTF16(magic_file_name));
+ callback.Run(error_string, FileSystem());
+ return;
+ }
+ FilePath path = permitted_paths.at(0);
+ 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::kDevToolsFileSystemPaths);
+ DictionaryValue* file_systems_paths_value = update.Get();
+ file_systems_paths_value->Set(file_system_path, Value::CreateNullValue());
+
+ FileSystem filesystem = CreateFileSystemStruct(web_contents_,
+ file_system_id,
+ registered_name,
+ file_system_path);
+ callback.Run("", filesystem);
+}
+
+void DevToolsFileHelper::RequestFileSystems(
+ const RequestFileSystemsCallback& callback) {
+ const DictionaryValue* file_systems_paths_value =
+ profile_->GetPrefs()->GetDictionary(prefs::kDevToolsFileSystemPaths);
+ std::vector<FilePath> saved_paths;
+ DictionaryValue::key_iterator it = file_systems_paths_value->begin_keys();
+ for (; it != file_systems_paths_value->end_keys(); ++it) {
+ std::string file_system_path = *it;
+ FilePath path = FilePath::FromUTF8Unsafe(file_system_path);
+ saved_paths.push_back(path);
+ }
+
+ ValidateFoldersCallback validate_folders_callback = Bind(
+ &DevToolsFileHelper::RestoreValidatedFileSystems,
+ weak_factory_.GetWeakPtr(),
+ callback);
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ Bind(&ValidateFoldersOnFileThread,
+ saved_paths,
+ validate_folders_callback));
+}
+
+void DevToolsFileHelper::RestoreValidatedFileSystems(
+ const RequestFileSystemsCallback& callback,
+ const std::vector<FilePath>& permitted_paths) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ std::vector<FileSystem> file_systems;
+ std::vector<FilePath>::const_iterator it;
+ for (it = permitted_paths.begin(); it != permitted_paths.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 filesystem = CreateFileSystemStruct(web_contents_,
+ file_system_id,
+ registered_name,
+ file_system_path);
+ file_systems.push_back(filesystem);
+ }
+ callback.Run(file_systems);
+}
+
+void DevToolsFileHelper::RemoveFileSystem(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::kDevToolsFileSystemPaths);
+ DictionaryValue* file_systems_paths_value = update.Get();
+ file_systems_paths_value->RemoveWithoutPathExpansion(file_system_path, NULL);
+}
diff --git a/chrome/browser/devtools/devtools_file_helper.h b/chrome/browser/devtools/devtools_file_helper.h
index b894a73..42fcb7d 100644
--- a/chrome/browser/devtools/devtools_file_helper.h
+++ b/chrome/browser/devtools/devtools_file_helper.h
@@ -7,6 +7,7 @@
#include <map>
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/callback.h"
@@ -16,13 +17,34 @@
class FilePath;
class Profile;
+namespace content {
+class WebContents;
+}
+
class DevToolsFileHelper {
public:
- explicit DevToolsFileHelper(Profile* profile);
+ struct FileSystem {
+ FileSystem();
+ FileSystem(const std::string& file_system_name,
+ const std::string& root_url,
+ const std::string& file_system_path);
+
+ std::string file_system_name;
+ std::string root_url;
+ std::string file_system_path;
+ };
+
+ DevToolsFileHelper(content::WebContents* web_contents, Profile* profile);
~DevToolsFileHelper();
typedef base::Callback<void(void)> SaveCallback;
typedef base::Callback<void(void)> AppendCallback;
+ typedef base::Callback<
+ void(const std::vector<DevToolsFileHelper::FileSystem>&)>
+ RequestFileSystemsCallback;
+ typedef base::Callback<
+ void(std::string, const DevToolsFileHelper::FileSystem&)>
+ AddFileSystemCallback;
// Saves |content| to the file and associates its path with given |url|.
// If client is calling this method with given |url| for the first time
@@ -40,13 +62,38 @@ class DevToolsFileHelper {
const std::string& content,
const AppendCallback& callback);
+ // Shows select folder dialog.
+ // If user cancels folder selection, passes empty FileSystem struct to
+ // |callback|.
+ // If selected folder contains magic file, grants renderer read/write
+ // permissions, registers isolated file system for it and passes FileSystem
+ // struct to |callback|. Saves file system path to prefs.
+ // If selected folder does not contain magic file, passes error string to
+ // |callback|.
+ void AddFileSystem(const AddFileSystemCallback& callback);
+
+ // Loads file system paths from prefs, grants permissions and registers
+ // isolated file system for those of them that contain magic file and passes
+ // FileSystem structs for registered file systems to |callback|.
+ void RequestFileSystems(const RequestFileSystemsCallback& callback);
+
+ // Removes isolated file system for given |file_system_path|.
+ void RemoveFileSystem(const std::string& file_system_path);
+
private:
void SaveAsFileSelected(const std::string& url,
- const std::string& content,
- const SaveCallback& callback,
- const FilePath& path);
+ const std::string& content,
+ const SaveCallback& callback,
+ const FilePath& path);
void SaveAsFileSelectionCanceled();
+ void InnerAddFileSystem(const AddFileSystemCallback& callback,
+ const FilePath& path);
+ void AddValidatedFileSystem(const AddFileSystemCallback& callback,
+ const std::vector<FilePath>& permitted_paths);
+ void RestoreValidatedFileSystems(const RequestFileSystemsCallback& callback,
+ const std::vector<FilePath>& file_paths);
+ content::WebContents* web_contents_;
Profile* profile_;
base::WeakPtrFactory<DevToolsFileHelper> weak_factory_;
typedef std::map<std::string, FilePath> PathsMap;
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc
index aa34605..927c276 100644
--- a/chrome/browser/devtools/devtools_window.cc
+++ b/chrome/browser/devtools/devtools_window.cc
@@ -47,6 +47,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/page_transition_types.h"
#include "grit/generated_resources.h"
@@ -97,6 +98,8 @@ void DevToolsWindow::RegisterUserPrefs(PrefServiceSyncable* prefs) {
PrefServiceSyncable::UNSYNCABLE_PREF);
prefs->RegisterDictionaryPref(prefs::kDevToolsEditedFiles,
PrefServiceSyncable::UNSYNCABLE_PREF);
+ prefs->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths,
+ PrefServiceSyncable::UNSYNCABLE_PREF);
}
// static
@@ -211,12 +214,12 @@ DevToolsWindow::DevToolsWindow(WebContents* web_contents,
dock_side_(dock_side),
is_loaded_(false),
action_on_load_(DEVTOOLS_TOGGLE_ACTION_SHOW),
- weak_factory_(this),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
width_(-1),
height_(-1) {
frontend_host_ = DevToolsClientHost::CreateDevToolsFrontendHost(web_contents,
this);
- file_helper_.reset(new DevToolsFileHelper(profile));
+ file_helper_.reset(new DevToolsFileHelper(web_contents, profile));
g_instances.Get().push_back(this);
// Wipe out page icon so that the default application icon is used.
@@ -508,13 +511,19 @@ WebContents* DevToolsWindow::OpenURLFromTab(WebContents* source,
}
void DevToolsWindow::CallClientFunction(const std::string& function_name,
- const Value* arg) {
- std::string json;
- if (arg)
- base::JSONWriter::Write(arg, &json);
-
- string16 javascript =
- ASCIIToUTF16(function_name + "(" + json + ");");
+ const Value* arg1,
+ const Value* arg2) {
+ std::string params;
+ if (arg1) {
+ std::string json;
+ base::JSONWriter::Write(arg1, &json);
+ params.append(json);
+ if (arg2) {
+ base::JSONWriter::Write(arg2, &json);
+ params.append(", " + json);
+ }
+ }
+ string16 javascript = ASCIIToUTF16(function_name + "(" + params + ");");
web_contents_->GetRenderViewHost()->
ExecuteJavascriptInWebFrame(string16(), javascript);
}
@@ -827,6 +836,39 @@ void DevToolsWindow::AppendToFile(const std::string& url,
url));
}
+namespace {
+
+DictionaryValue* CreateFileSystemValue(
+ DevToolsFileHelper::FileSystem file_system) {
+ DictionaryValue* file_system_value = new DictionaryValue();
+ file_system_value->SetString("fileSystemName", file_system.file_system_name);
+ file_system_value->SetString("rootURL", file_system.root_url);
+ file_system_value->SetString("fileSystemPath", file_system.file_system_path);
+ return file_system_value;
+}
+
+} // namespace
+
+void DevToolsWindow::RequestFileSystems() {
+ CHECK(content::GetContentClient()->HasWebUIScheme(web_contents_->GetURL()));
+ file_helper_->RequestFileSystems(
+ Bind(&DevToolsWindow::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
+}
+
+void DevToolsWindow::AddFileSystem() {
+ CHECK(content::GetContentClient()->HasWebUIScheme(web_contents_->GetURL()));
+ file_helper_->AddFileSystem(
+ Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()));
+}
+
+void DevToolsWindow::RemoveFileSystem(const std::string& file_system_path) {
+ CHECK(content::GetContentClient()->HasWebUIScheme(web_contents_->GetURL()));
+ file_helper_->RemoveFileSystem(file_system_path);
+ StringValue file_system_path_value(file_system_path);
+ CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
+ &file_system_path_value);
+}
+
void DevToolsWindow::FileSavedAs(const std::string& url) {
StringValue url_value(url);
CallClientFunction("InspectorFrontendAPI.savedURL", &url_value);
@@ -837,6 +879,30 @@ void DevToolsWindow::AppendedTo(const std::string& url) {
CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value);
}
+void DevToolsWindow::FileSystemsLoaded(
+ const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
+ ListValue file_systems_value;
+ for (size_t i = 0; i < file_systems.size(); ++i) {
+ file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
+ }
+ CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
+ &file_systems_value);
+}
+
+void DevToolsWindow::FileSystemAdded(
+ std::string error_string,
+ const DevToolsFileHelper::FileSystem& file_system) {
+ StringValue error_string_value(error_string);
+ DictionaryValue* file_system_value = NULL;
+ if (!file_system.file_system_path.empty())
+ file_system_value = CreateFileSystemValue(file_system);
+ CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
+ &error_string_value,
+ file_system_value);
+ if (file_system_value)
+ delete file_system_value;
+}
+
content::JavaScriptDialogCreator* DevToolsWindow::GetJavaScriptDialogCreator() {
if (inspected_web_contents_ && inspected_web_contents_->GetDelegate()) {
return inspected_web_contents_->GetDelegate()->
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h
index ef199b5..58a9b0b 100644
--- a/chrome/browser/devtools/devtools_window.h
+++ b/chrome/browser/devtools/devtools_window.h
@@ -142,7 +142,8 @@ class DevToolsWindow : private content::NotificationObserver,
void UpdateTheme();
void AddDevToolsExtensionsToClient();
void CallClientFunction(const std::string& function_name,
- const base::Value* arg);
+ const base::Value* arg1 = NULL,
+ const base::Value* arg2 = NULL);
// Overridden from content::WebContentsDelegate.
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
@@ -182,10 +183,17 @@ class DevToolsWindow : private content::NotificationObserver,
bool save_as) OVERRIDE;
virtual void AppendToFile(const std::string& url,
const std::string& content) OVERRIDE;
+ virtual void RequestFileSystems() OVERRIDE;
+ virtual void AddFileSystem() OVERRIDE;
+ virtual void RemoveFileSystem(const std::string& file_system_path) OVERRIDE;
// DevToolsFileHelper callbacks.
void FileSavedAs(const std::string& url);
void AppendedTo(const std::string& url);
+ void FileSystemsLoaded(
+ const std::vector<DevToolsFileHelper::FileSystem>& file_systems);
+ void FileSystemAdded(std::string error_string,
+ const DevToolsFileHelper::FileSystem& file_system);
void UpdateBrowserToolbar();
bool IsDocked();
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index eaa2156..0bb8a77 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1645,6 +1645,9 @@ const char kDevToolsDockSide[] = "devtools.dock_side";
// Maps of files edited locally using DevTools.
const char kDevToolsEditedFiles[] = "devtools.edited_files";
+// List of file system paths added in DevTools.
+const char kDevToolsFileSystemPaths[] = "devtools.file_system_paths";
+
// Integer location of the horizontal split bar in the browser view.
const char kDevToolsHSplitLocation[] = "devtools.split_location";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index fb59a0d..04b1d9f 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -571,6 +571,7 @@ extern const char kNtpAppPageNames[];
extern const char kDevToolsDisabled[];
extern const char kDevToolsDockSide[];
extern const char kDevToolsEditedFiles[];
+extern const char kDevToolsFileSystemPaths[];
extern const char kDevToolsHSplitLocation[];
extern const char kDevToolsOpenDocked[];
#if defined(OS_ANDROID)
diff --git a/content/browser/devtools/devtools_frontend_host.cc b/content/browser/devtools/devtools_frontend_host.cc
index f16dcdf..e29bd54 100644
--- a/content/browser/devtools/devtools_frontend_host.cc
+++ b/content/browser/devtools/devtools_frontend_host.cc
@@ -70,6 +70,10 @@ bool DevToolsFrontendHost::OnMessageReceived(
IPC_MESSAGE_HANDLER(DevToolsHostMsg_OpenInNewTab, OnOpenInNewTab)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_Save, OnSave)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_Append, OnAppend)
+ IPC_MESSAGE_HANDLER(DevToolsHostMsg_RequestFileSystems,
+ OnRequestFileSystems)
+ IPC_MESSAGE_HANDLER(DevToolsHostMsg_AddFileSystem, OnAddFileSystem)
+ IPC_MESSAGE_HANDLER(DevToolsHostMsg_RemoveFileSystem, OnRemoveFileSystem)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -110,6 +114,19 @@ void DevToolsFrontendHost::OnAppend(
delegate_->AppendToFile(url, content);
}
+void DevToolsFrontendHost::OnRequestFileSystems() {
+ delegate_->RequestFileSystems();
+}
+
+void DevToolsFrontendHost::OnAddFileSystem() {
+ delegate_->AddFileSystem();
+}
+
+void DevToolsFrontendHost::OnRemoveFileSystem(
+ const std::string& file_system_path) {
+ delegate_->RemoveFileSystem(file_system_path);
+}
+
void DevToolsFrontendHost::OnRequestSetDockSide(const std::string& side) {
delegate_->SetDockSide(side);
}
diff --git a/content/browser/devtools/devtools_frontend_host.h b/content/browser/devtools/devtools_frontend_host.h
index 6cb04ce..e06db3a 100644
--- a/content/browser/devtools/devtools_frontend_host.h
+++ b/content/browser/devtools/devtools_frontend_host.h
@@ -46,6 +46,9 @@ class DevToolsFrontendHost : public DevToolsClientHost,
void OnOpenInNewTab(const std::string& url);
void OnSave(const std::string& url, const std::string& content, bool save_as);
void OnAppend(const std::string& url, const std::string& content);
+ void OnRequestFileSystems();
+ void OnAddFileSystem();
+ void OnRemoveFileSystem(const std::string& file_system_path);
WebContentsImpl* web_contents_;
DevToolsFrontendHostDelegate* delegate_;
diff --git a/content/common/devtools_messages.h b/content/common/devtools_messages.h
index a472e35..8033300 100644
--- a/content/common/devtools_messages.h
+++ b/content/common/devtools_messages.h
@@ -138,6 +138,16 @@ IPC_MESSAGE_ROUTED2(DevToolsHostMsg_Append,
std::string /* url */,
std::string /* content */)
+// Requests the list of filesystems previously added for devtools.
+IPC_MESSAGE_ROUTED0(DevToolsHostMsg_RequestFileSystems)
+
+// Shows a dialog to select a folder to which an isolated filesystem is added.
+IPC_MESSAGE_ROUTED0(DevToolsHostMsg_AddFileSystem)
+
+// Removes a previously added devtools filesystem given by |file_system_path|.
+IPC_MESSAGE_ROUTED1(DevToolsHostMsg_RemoveFileSystem,
+ std::string /* file_system_path */)
+
// Updates agent runtime state stored in devtools manager in order to support
// cross-navigation instrumentation.
IPC_MESSAGE_ROUTED1(DevToolsHostMsg_SaveAgentRuntimeState,
diff --git a/content/public/browser/devtools_frontend_host_delegate.h b/content/public/browser/devtools_frontend_host_delegate.h
index 79d3d9f..b0617d2 100644
--- a/content/public/browser/devtools_frontend_host_delegate.h
+++ b/content/public/browser/devtools_frontend_host_delegate.h
@@ -42,6 +42,15 @@ class DevToolsFrontendHostDelegate {
virtual void AppendToFile(const std::string& url,
const std::string& content) = 0;
+ // Requests the list of filesystems previously added for devtools.
+ virtual void RequestFileSystems() = 0;
+
+ // Shows a dialog to select a folder to which an isolated filesystem is added.
+ virtual void AddFileSystem() = 0;
+
+ // Removes a previously added devtools filesystem given by |file_system_path|.
+ virtual void RemoveFileSystem(const std::string& file_system_path) = 0;
+
// This method is called when the contents inspected by this devtools frontend
// is closing.
virtual void InspectedContentsClosing() = 0;
diff --git a/content/renderer/devtools/devtools_client.cc b/content/renderer/devtools/devtools_client.cc
index 31db053..db3e56c 100644
--- a/content/renderer/devtools/devtools_client.cc
+++ b/content/renderer/devtools/devtools_client.cc
@@ -89,6 +89,20 @@ void DevToolsClient::append(const WebKit::WebString& url,
content.utf8()));
}
+void DevToolsClient::requestFileSystems() {
+ Send(new DevToolsHostMsg_RequestFileSystems(routing_id()));
+}
+
+void DevToolsClient::addFileSystem() {
+ Send(new DevToolsHostMsg_AddFileSystem(routing_id()));
+}
+
+void DevToolsClient::removeFileSystem(const WebString& fileSystemPath) {
+ Send(new DevToolsHostMsg_RemoveFileSystem(routing_id(),
+ fileSystemPath.utf8()));
+}
+
+
void DevToolsClient::OnDispatchOnInspectorFrontend(const std::string& message) {
web_tools_frontend_->dispatchOnInspectorFrontend(
WebString::fromUTF8(message));
diff --git a/content/renderer/devtools/devtools_client.h b/content/renderer/devtools/devtools_client.h
index f5fa8f0..6c1c276 100644
--- a/content/renderer/devtools/devtools_client.h
+++ b/content/renderer/devtools/devtools_client.h
@@ -51,6 +51,11 @@ class DevToolsClient : public RenderViewObserver,
virtual void append(const WebKit::WebString& url,
const WebKit::WebString& content) OVERRIDE;
+ virtual void requestFileSystems() OVERRIDE;
+ virtual void addFileSystem() OVERRIDE;
+ virtual void removeFileSystem(
+ const WebKit::WebString& fileSystemPath) OVERRIDE;
+
void OnDispatchOnInspectorFrontend(const std::string& message);
scoped_ptr<WebKit::WebDevToolsFrontend> web_tools_frontend_;