summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-08 21:00:56 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-08 21:00:56 +0000
commitf0cd4461c006a2f6c10291b72368d1c8ac560dd7 (patch)
treec54d5034d1e9ee5c38a37c10fb105b18abc83f91
parentb2bb85f8583c490a6da94a7e6d93dcdff367e4ce (diff)
downloadchromium_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
-rw-r--r--chrome/browser/file_system/file_system_dispatcher_host.cc223
-rw-r--r--chrome/browser/file_system/file_system_dispatcher_host.h34
-rw-r--r--chrome/common/file_system/file_system_dispatcher.cc3
-rw-r--r--chrome/common/render_messages_params.cc6
-rw-r--r--chrome/common/render_messages_params.h17
5 files changed, 202 insertions, 81 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_
diff --git a/chrome/common/file_system/file_system_dispatcher.cc b/chrome/common/file_system/file_system_dispatcher.cc
index d28e244..7b0492c 100644
--- a/chrome/common/file_system/file_system_dispatcher.cc
+++ b/chrome/common/file_system/file_system_dispatcher.cc
@@ -127,7 +127,8 @@ void FileSystemDispatcher::DidReadDirectory(
callbacks_.Remove(params.request_id);
WebVector<WebFileSystemEntry> entries(params.entries.size());
for (size_t i = 0; i < params.entries.size(); ++i) {
- entries[i].name = webkit_glue::FilePathToWebString(params.entries[i].name);
+ entries[i].name = webkit_glue::FilePathStringToWebString(
+ params.entries[i].name);
entries[i].isDirectory = params.entries[i].is_directory;
}
callbacks->didReadDirectory(entries, params.has_more);
diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc
index 734874c..6c9591f 100644
--- a/chrome/common/render_messages_params.cc
+++ b/chrome/common/render_messages_params.cc
@@ -1481,14 +1481,14 @@ void ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params>::Log(
l->append(")");
}
-void ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params::Entry>::Write(
+void ParamTraits<base::file_util_proxy::Entry>::Write(
Message* m,
const param_type& p) {
WriteParam(m, p.name);
WriteParam(m, p.is_directory);
}
-bool ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params::Entry>::Read(
+bool ParamTraits<base::file_util_proxy::Entry>::Read(
const Message* m,
void** iter,
param_type* p) {
@@ -1497,7 +1497,7 @@ bool ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params::Entry>::Read(
ReadParam(m, iter, &p->is_directory);
}
-void ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params::Entry>::Log(
+void ParamTraits<base::file_util_proxy::Entry>::Log(
const param_type& p,
std::string* l) {
l->append("(");
diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h
index 904e094..c5a38b6 100644
--- a/chrome/common/render_messages_params.h
+++ b/chrome/common/render_messages_params.h
@@ -11,6 +11,7 @@
#include "app/surface/transport_dib.h"
#include "base/file_path.h"
+#include "base/file_util_proxy.h"
#include "base/ref_counted.h"
#include "base/shared_memory.h"
#include "base/time.h"
@@ -846,18 +847,8 @@ struct ViewMsg_FileSystem_DidReadDirectory_Params {
// The response should have this id.
int request_id;
- // TODO(kinuko): replace this with file_util_proxy's entry structure
- // once it's defined.
- struct Entry {
- // Name of the entry.
- FilePath name;
-
- // Indicates if the entry is directory or not.
- bool is_directory;
- };
-
// A vector of directory entries.
- std::vector<Entry> entries;
+ std::vector<base::file_util_proxy::Entry> entries;
// Indicates if there will be more entries.
bool has_more;
@@ -1125,8 +1116,8 @@ struct ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params> {
};
template <>
-struct ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params::Entry> {
- typedef ViewMsg_FileSystem_DidReadDirectory_Params::Entry param_type;
+struct ParamTraits<base::file_util_proxy::Entry> {
+ typedef base::file_util_proxy::Entry param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, void** iter, param_type* p);
static void Log(const param_type& p, std::string* l);