diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c2326debc99..d63c7a14f7c 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -33,6 +33,7 @@ #include "chrome/browser/printing/print_view_manager_basic.h" #include "chrome/browser/ui/browser_dialogs.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/navigation_entry.h" @@ -50,6 +51,7 @@ #include "content/public/common/web_preferences.h" #include "ipc/ipc_message_macros.h" #include "native_mate/dictionary.h" +#include "storage/browser/fileapi/isolated_context.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/point.h" @@ -89,6 +91,62 @@ std::string RemoveWhitespace(const std::string& str) { return str; } +storage::IsolatedContext* isolated_context() { + storage::IsolatedContext* context = + storage::IsolatedContext::GetInstance(); + DCHECK(context); + return context; +} + +std::string RegisterFileSystem(content::WebContents* web_contents, + const base::FilePath& path, + std::string* registered_name) { + std::string file_system_id = isolated_context()->RegisterFileSystemForPath( + storage::kFileSystemTypeNativeLocal, + std::string(), + path, + registered_name); + + content::ChildProcessSecurityPolicy* policy = + content::ChildProcessSecurityPolicy::GetInstance(); + content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost(); + int renderer_id = render_view_host->GetProcess()->GetID(); + policy->GrantReadFileSystem(renderer_id, file_system_id); + policy->GrantWriteFileSystem(renderer_id, file_system_id); + policy->GrantCreateFileForFileSystem(renderer_id, file_system_id); + policy->GrantDeleteFromFileSystem(renderer_id, file_system_id); + + if (!policy->CanReadFile(renderer_id, path)) + policy->GrantReadFile(renderer_id, path); + + return file_system_id; +} + +NativeWindow::FileSystem CreateFileSystemStruct( + content::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 = + storage::GetIsolatedFileSystemName(origin, file_system_id); + std::string root_url = storage::GetIsolatedFileSystemRootURIString( + origin, file_system_id, registered_name); + + return NativeWindow::FileSystem(file_system_name, + root_url, + file_system_path); +} + +base::DictionaryValue* CreateFileSystemValue( + NativeWindow::FileSystem file_system) { + base::DictionaryValue* file_system_value = new base::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 NativeWindow::NativeWindow(content::WebContents* web_contents, @@ -840,6 +898,57 @@ void NativeWindow::DevToolsFocused() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus()); } +void NativeWindow::DevToolsAddFileSystem() { + file_dialog::Filters filters; + base::FilePath default_path; + std::vector paths; + int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; + if (!file_dialog::ShowOpenDialog(this, "", default_path, + filters, flag, &paths)) + return; + + base::FilePath path = paths[0]; + std::string registered_name; + std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(), + path, + ®istered_name); + + WorkspaceMap::iterator it = saved_paths_.find(file_system_id); + if (it != saved_paths_.end()) + return; + + saved_paths_[file_system_id] = path; + + FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(), + file_system_id, + registered_name, + path.AsUTF8Unsafe()); + + scoped_ptr error_string_value( + new base::StringValue(std::string())); + scoped_ptr file_system_value; + if (!file_system.file_system_path.empty()) + file_system_value.reset(CreateFileSystemValue(file_system)); + CallDevToolsFunction("DevToolsAPI.fileSystemAdded", error_string_value.get(), + file_system_value.get(), nullptr); +} + +void NativeWindow::DevToolsRemoveFileSystem( + const std::string& file_system_path) { + base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path); + isolated_context()->RevokeFileSystemByPath(path); + + for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it) + if (it->second == path) { + saved_paths_.erase(it); + break; + } + + base::StringValue file_system_path_value(file_system_path); + CallDevToolsFunction("DevToolsAPI.fileSystemRemoved", + &file_system_path_value, nullptr, nullptr); +} + void NativeWindow::ScheduleUnresponsiveEvent(int ms) { if (!window_unresposive_closure_.IsCancelled()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 8f9d8e95a34..eb3aad65986 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -61,6 +61,22 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, public: typedef base::Callback CapturePageCallback; + struct FileSystem { + 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) { + } + + std::string file_system_name; + std::string root_url; + std::string file_system_path; + }; + class DialogScope { public: explicit DialogScope(NativeWindow* window) @@ -307,6 +323,8 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, void DevToolsAppendToFile(const std::string& url, const std::string& content) override; void DevToolsFocused() override; + void DevToolsAddFileSystem() override; + void DevToolsRemoveFileSystem(const std::string& file_system_path) override; // Whether window has standard frame. bool has_frame_; @@ -386,6 +404,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, typedef std::map PathsMap; PathsMap saved_files_; + // Maps file system id to file path, used by the file system requests + // sent from devtools. + typedef std::map WorkspaceMap; + WorkspaceMap saved_paths_; + DISALLOW_COPY_AND_ASSIGN(NativeWindow); };