diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-08 21:00:56 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-08 21:00:56 +0000 |
commit | f0cd4461c006a2f6c10291b72368d1c8ac560dd7 (patch) | |
tree | c54d5034d1e9ee5c38a37c10fb105b18abc83f91 /chrome/browser | |
parent | b2bb85f8583c490a6da94a7e6d93dcdff367e4ce (diff) | |
download | chromium_src-f0cd4461c006a2f6c10291b72368d1c8ac560dd7.zip chromium_src-f0cd4461c006a2f6c10291b72368d1c8ac560dd7.tar.gz chromium_src-f0cd4461c006a2f6c10291b72368d1c8ac560dd7.tar.bz2 |
Integrate FileSystemOperation with FileSystemDispatcherHost.
(This patch depends on unsubmitted change in file_util_proxy:
http://codereview.chromium.org/3293009/show)
BUG=32277
TEST=none; layout tests will be added later.
Review URL: http://codereview.chromium.org/3328011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58870 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/file_system/file_system_dispatcher_host.cc | 223 | ||||
-rw-r--r-- | chrome/browser/file_system/file_system_dispatcher_host.h | 34 |
2 files changed, 193 insertions, 64 deletions
diff --git a/chrome/browser/file_system/file_system_dispatcher_host.cc b/chrome/browser/file_system/file_system_dispatcher_host.cc index 172217e..e7bf5d8 100644 --- a/chrome/browser/file_system/file_system_dispatcher_host.cc +++ b/chrome/browser/file_system/file_system_dispatcher_host.cc @@ -4,7 +4,9 @@ #include "chrome/browser/file_system/file_system_dispatcher_host.h" +#include "base/file_path.h" #include "base/thread.h" +#include "base/time.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_thread.h" @@ -17,6 +19,60 @@ #include "third_party/WebKit/WebKit/chromium/public/WebFileError.h" #include "webkit/glue/webkit_glue.h" +// A class to hold an ongoing openFileSystem completion task. +struct OpenFileSystemCompletionTask { + public: + static void Run( + int request_id, + int routing_id, + const std::string& name, + const FilePath& root_path, + FileSystemDispatcherHost* dispatcher_host) { + // The task is self-destructed. + new OpenFileSystemCompletionTask(request_id, routing_id, name, root_path, + dispatcher_host); + } + + void DidFinish(base::PlatformFileError error) { + if (error == base::PLATFORM_FILE_OK) + dispatcher_host_->Send( + new ViewMsg_OpenFileSystemRequest_Complete( + routing_id_, request_id_, true, UTF8ToUTF16(name_), + webkit_glue::FilePathToWebString(root_path_))); + else + dispatcher_host_->Send( + new ViewMsg_OpenFileSystemRequest_Complete( + routing_id_, request_id_, false, string16(), string16())); + delete this; + } + + private: + OpenFileSystemCompletionTask( + int request_id, + int routing_id, + const std::string& name, + const FilePath& root_path, + FileSystemDispatcherHost* dispatcher_host) + : request_id_(request_id), + routing_id_(routing_id), + name_(name), + root_path_(root_path), + dispatcher_host_(dispatcher_host), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + base::FileUtilProxy::CreateDirectory( + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE), + root_path_, false, true, callback_factory_.NewCallback( + &OpenFileSystemCompletionTask::DidFinish)); + } + + int request_id_; + int routing_id_; + std::string name_; + FilePath root_path_; + scoped_refptr<FileSystemDispatcherHost> dispatcher_host_; + base::ScopedCallbackFactory<OpenFileSystemCompletionTask> callback_factory_; +}; + FileSystemDispatcherHost::FileSystemDispatcherHost( IPC::Message::Sender* sender, FileSystemHostContext* file_system_host_context, @@ -40,6 +96,12 @@ void FileSystemDispatcherHost::Init(base::ProcessHandle process_handle) { void FileSystemDispatcherHost::Shutdown() { message_sender_ = NULL; shutdown_ = true; + + // Drop all the operations. + for (OperationsMap::const_iterator iter(&operations_); + !iter.IsAtEnd(); iter.Advance()) { + operations_.Remove(iter.GetCurrentKey()); + } } bool FileSystemDispatcherHost::OnMessageReceived( @@ -82,97 +144,134 @@ void FileSystemDispatcherHost::OnOpenFileSystem( return; } - // TODO(kinuko): creates the root directory and if it succeeds. - - Send(new ViewMsg_OpenFileSystemRequest_Complete( - params.routing_id, - params.request_id, - true, - UTF8ToUTF16(name), - webkit_glue::FilePathToWebString(root_path))); + // Run the completion task that creates the root directory and sends + // back the status code to the dispatcher. + OpenFileSystemCompletionTask::Run( + params.request_id, params.routing_id, name, root_path, this); } void FileSystemDispatcherHost::OnMove( int request_id, const string16& src_path, const string16& dest_path) { - if (!context_->CheckValidFileSystemPath( - webkit_glue::WebStringToFilePath(src_path)) || - !context_->CheckValidFileSystemPath( - webkit_glue::WebStringToFilePath(dest_path))) { - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorSecurity)); + FilePath src_file_path = webkit_glue::WebStringToFilePath(src_path); + FilePath dest_file_path = webkit_glue::WebStringToFilePath(dest_path); + + if (!CheckValidFileSystemPath(src_file_path, request_id) || + !CheckValidFileSystemPath(dest_file_path, request_id)) return; - } - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + GetNewOperation(request_id)->Move(src_file_path, dest_file_path); } void FileSystemDispatcherHost::OnCopy( - int request_id, - const string16& src_path, - const string16& dest_path) { - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + int request_id, const string16& src_path, const string16& dest_path) { + FilePath src_file_path = webkit_glue::WebStringToFilePath(src_path); + FilePath dest_file_path = webkit_glue::WebStringToFilePath(dest_path); + + if (!CheckValidFileSystemPath(src_file_path, request_id) || + !CheckValidFileSystemPath(dest_file_path, request_id)) + return; + + GetNewOperation(request_id)->Copy(src_file_path, dest_file_path); } void FileSystemDispatcherHost::OnRemove( - int request_id, - const string16& path) { - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + int request_id, const string16& path) { + FilePath file_path = webkit_glue::WebStringToFilePath(path); + if (!CheckValidFileSystemPath(file_path, request_id)) + return; + GetNewOperation(request_id)->Remove(file_path); } void FileSystemDispatcherHost::OnReadMetadata( - int request_id, - const string16& path) { - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + int request_id, const string16& path) { + FilePath file_path = webkit_glue::WebStringToFilePath(path); + if (!CheckValidFileSystemPath(file_path, request_id)) + return; + GetNewOperation(request_id)->GetMetadata(file_path); } void FileSystemDispatcherHost::OnCreate( - int request_id, - const string16& path, - bool exclusive, - bool is_directory) { - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + int request_id, const string16& path, bool exclusive, bool is_directory) { + FilePath file_path = webkit_glue::WebStringToFilePath(path); + if (!CheckValidFileSystemPath(file_path, request_id)) + return; + if (is_directory) + GetNewOperation(request_id)->CreateDirectory(file_path, exclusive); + else + GetNewOperation(request_id)->CreateFile(file_path, exclusive); } void FileSystemDispatcherHost::OnExists( - int request_id, - const string16& path, - bool is_directory) { - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + int request_id, const string16& path, bool is_directory) { + FilePath file_path = webkit_glue::WebStringToFilePath(path); + if (!CheckValidFileSystemPath(file_path, request_id)) + return; + if (is_directory) + GetNewOperation(request_id)->DirectoryExists(file_path); + else + GetNewOperation(request_id)->FileExists(file_path); } void FileSystemDispatcherHost::OnReadDirectory( - int request_id, - const string16& path) { - // TODO(kinuko): not implemented yet. - Send(new ViewMsg_FileSystem_DidFail( - request_id, WebKit::WebFileErrorAbort)); + int request_id, const string16& path) { + FilePath file_path = webkit_glue::WebStringToFilePath(path); + if (!CheckValidFileSystemPath(file_path, request_id)) + return; + GetNewOperation(request_id)->ReadDirectory(file_path); } -void FileSystemDispatcherHost::Send(IPC::Message* message) { - if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { - if (!ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod(this, - &FileSystemDispatcherHost::Send, - message))) - delete message; - return; - } +void FileSystemDispatcherHost::DidFail( + WebKit::WebFileError status, int request_id) { + Send(new ViewMsg_FileSystem_DidFail(request_id, status)); + operations_.Remove(request_id); +} + +void FileSystemDispatcherHost::DidSucceed(int request_id) { + Send(new ViewMsg_FileSystem_DidSucceed(request_id)); + operations_.Remove(request_id); +} + +void FileSystemDispatcherHost::DidReadMetadata( + const base::PlatformFileInfo& info, int request_id) { + Send(new ViewMsg_FileSystem_DidReadMetadata(request_id, info)); + operations_.Remove(request_id); +} +void FileSystemDispatcherHost::DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>& entries, + bool has_more, int request_id) { + ViewMsg_FileSystem_DidReadDirectory_Params params; + params.request_id = request_id; + params.entries = entries; + params.has_more = has_more; + Send(new ViewMsg_FileSystem_DidReadDirectory(params)); + operations_.Remove(request_id); +} + +void FileSystemDispatcherHost::Send(IPC::Message* message) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); if (!shutdown_ && message_sender_) message_sender_->Send(message); else delete message; } + +bool FileSystemDispatcherHost::CheckValidFileSystemPath( + const FilePath& path, int request_id) { + // We may want do more checks, but for now it just checks if the given + // |path| is under the valid FileSystem root path for this host context. + if (!context_->CheckValidFileSystemPath(path)) { + Send(new ViewMsg_FileSystem_DidFail( + request_id, WebKit::WebFileErrorSecurity)); + return false; + } + return true; +} + +FileSystemOperation* FileSystemDispatcherHost::GetNewOperation( + int request_id) { + scoped_ptr<FileSystemOperation> operation( + new FileSystemOperation(request_id, this)); + operations_.AddWithID(operation.get(), request_id); + return operation.release(); +} diff --git a/chrome/browser/file_system/file_system_dispatcher_host.h b/chrome/browser/file_system/file_system_dispatcher_host.h index 320e56a..64fd73c 100644 --- a/chrome/browser/file_system/file_system_dispatcher_host.h +++ b/chrome/browser/file_system/file_system_dispatcher_host.h @@ -6,9 +6,15 @@ #define CHROME_BROWSER_FILE_SYSTEM_FILE_SYSTEM_DISPATCHER_HOST_H_ #include "base/basictypes.h" +#include "base/file_util.h" +#include "base/id_map.h" #include "base/nullable_string16.h" #include "base/process.h" +#include "base/platform_file.h" +#include "base/scoped_callback_factory.h" #include "base/ref_counted.h" +#include "chrome/browser/file_system/file_system_operation.h" +#include "chrome/browser/file_system/file_system_operation_client.h" #include "chrome/common/render_messages.h" class FileSystemHostContext; @@ -17,7 +23,8 @@ class Receiver; class ResourceMessageFilter; class FileSystemDispatcherHost - : public base::RefCountedThreadSafe<FileSystemDispatcherHost> { + : public base::RefCountedThreadSafe<FileSystemDispatcherHost>, + public FileSystemOperationClient { public: FileSystemDispatcherHost(IPC::Message::Sender* sender, FileSystemHostContext* file_system_host_context, @@ -56,8 +63,25 @@ class FileSystemDispatcherHost const string16& path); void Send(IPC::Message* message); + // FileSystemOperationClient methods. + virtual void DidFail(WebKit::WebFileError status, int request_id); + virtual void DidSucceed(int request_id); + virtual void DidReadMetadata( + const base::PlatformFileInfo& info, + int request_id); + virtual void DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>& entries, + bool has_more, + int request_id); + private: - void Move(const string16& src, const string16& dest, int operation_id); + // Creates a new FileSystemOperation. + FileSystemOperation* GetNewOperation(int request_id); + + // Checks the validity of a given |path|. Returns true if the given |path| + // is valid as a path for FileSystem API. Otherwise it sends back a + // security error code to the dispatcher and returns false. + bool CheckValidFileSystemPath(const FilePath& path, int request_id); // The sender to be used for sending out IPC messages. IPC::Message::Sender* message_sender_; @@ -71,6 +95,12 @@ class FileSystemDispatcherHost // Used to look up permissions. scoped_refptr<HostContentSettingsMap> host_content_settings_map_; + + // Keeps ongoing file system operations. + typedef IDMap<FileSystemOperation, IDMapOwnPointer> OperationsMap; + OperationsMap operations_; + + DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcherHost); }; #endif // CHROME_BROWSER_FILE_SYSTEM_FILE_SYSTEM_DISPATCHER_HOST_H_ |