summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/platform_file.h7
-rw-r--r--chrome/browser/file_system/browser_file_system_callback_dispatcher.cc45
-rw-r--r--chrome/browser/file_system/browser_file_system_callback_dispatcher.h33
-rw-r--r--chrome/browser/file_system/chrome_file_system_operation.cc14
-rw-r--r--chrome/browser/file_system/chrome_file_system_operation.h28
-rw-r--r--chrome/browser/file_system/chrome_file_system_operation_unittest.cc571
-rw-r--r--chrome/browser/file_system/file_system_dispatcher_host.cc76
-rw-r--r--chrome/browser/file_system/file_system_dispatcher_host.h28
-rw-r--r--chrome/chrome_browser.gypi4
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/file_system/file_system_dispatcher.cc177
-rw-r--r--chrome/common/file_system/file_system_dispatcher.h70
-rw-r--r--chrome/common/file_system/webfilesystem_impl.cc133
-rw-r--r--chrome/common/render_messages.h1
-rw-r--r--chrome/common/render_messages_internal.h20
-rw-r--r--chrome/common/render_messages_params.cc40
-rw-r--r--chrome/common/render_messages_params.h22
-rw-r--r--webkit/fileapi/file_system_callback_dispatcher.h49
-rw-r--r--webkit/fileapi/file_system_operation.cc111
-rw-r--r--webkit/fileapi/file_system_operation.h18
-rw-r--r--webkit/fileapi/file_system_operation_client.h39
-rw-r--r--webkit/fileapi/file_system_operation_unittest.cc555
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi2
-rw-r--r--webkit/tools/test_shell/simple_file_system.cc161
-rw-r--r--webkit/tools/test_shell/simple_file_system.h76
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
26 files changed, 1144 insertions, 1138 deletions
diff --git a/base/platform_file.h b/base/platform_file.h
index abe5cdd..c5ab477 100644
--- a/base/platform_file.h
+++ b/base/platform_file.h
@@ -44,6 +44,9 @@ enum PlatformFileFlags {
PLATFORM_FILE_WRITE_ATTRIBUTES = 8192 // Used on Windows only
};
+// PLATFORM_FILE_ERROR_ACCESS_DENIED is returned when a call fails because of
+// a filesystem restriction. PLATFORM_FILE_ERROR_SECURITY is returned when a
+// browser policy doesn't allow the operation to be executed.
enum PlatformFileError {
PLATFORM_FILE_OK = 0,
PLATFORM_FILE_ERROR_FAILED = -1,
@@ -55,7 +58,9 @@ enum PlatformFileError {
PLATFORM_FILE_ERROR_NO_MEMORY = -7,
PLATFORM_FILE_ERROR_NO_SPACE = -8,
PLATFORM_FILE_ERROR_NOT_A_DIRECTORY = -9,
- PLATFORM_FILE_ERROR_INVALID_OPERATION = -10
+ PLATFORM_FILE_ERROR_INVALID_OPERATION = -10,
+ PLATFORM_FILE_ERROR_SECURITY = -11,
+ PLATFORM_FILE_ERROR_ABORT = -12
};
// Used to hold information about a given file.
diff --git a/chrome/browser/file_system/browser_file_system_callback_dispatcher.cc b/chrome/browser/file_system/browser_file_system_callback_dispatcher.cc
new file mode 100644
index 0000000..107515e
--- /dev/null
+++ b/chrome/browser/file_system/browser_file_system_callback_dispatcher.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2010 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/file_system/browser_file_system_callback_dispatcher.h"
+
+#include "chrome/browser/file_system/file_system_dispatcher_host.h"
+
+BrowserFileSystemCallbackDispatcher::BrowserFileSystemCallbackDispatcher(
+ FileSystemDispatcherHost* dispatcher_host, int request_id)
+ : dispatcher_host_(dispatcher_host),
+ request_id_(request_id) {
+ DCHECK(dispatcher_host_);
+}
+
+void BrowserFileSystemCallbackDispatcher::DidSucceed() {
+ dispatcher_host_->Send(new ViewMsg_FileSystem_DidSucceed(request_id_));
+ dispatcher_host_->RemoveCompletedOperation(request_id_);
+}
+
+void BrowserFileSystemCallbackDispatcher::DidReadMetadata(
+ const base::PlatformFileInfo& info) {
+ dispatcher_host_->Send(new ViewMsg_FileSystem_DidReadMetadata(
+ request_id_, info));
+ dispatcher_host_->RemoveCompletedOperation(request_id_);
+}
+
+void BrowserFileSystemCallbackDispatcher::DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries, bool has_more) {
+ dispatcher_host_->Send(new ViewMsg_FileSystem_DidReadDirectory(
+ request_id_, entries, has_more));
+ dispatcher_host_->RemoveCompletedOperation(request_id_);
+}
+
+void BrowserFileSystemCallbackDispatcher::DidOpenFileSystem(
+ const string16&, const FilePath&) {
+ NOTREACHED();
+}
+
+void BrowserFileSystemCallbackDispatcher::DidFail(
+ base::PlatformFileError error_code) {
+ dispatcher_host_->Send(new ViewMsg_FileSystem_DidFail(
+ request_id_, error_code));
+ dispatcher_host_->RemoveCompletedOperation(request_id_);
+}
diff --git a/chrome/browser/file_system/browser_file_system_callback_dispatcher.h b/chrome/browser/file_system/browser_file_system_callback_dispatcher.h
new file mode 100644
index 0000000..0372e09
--- /dev/null
+++ b/chrome/browser/file_system/browser_file_system_callback_dispatcher.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_FILE_SYSTEM_BROWSER_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
+#define CHROME_BROWSER_FILE_SYSTEM_BROWSER_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
+
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+
+class FileSystemDispatcherHost;
+
+class BrowserFileSystemCallbackDispatcher
+ : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ BrowserFileSystemCallbackDispatcher(FileSystemDispatcherHost* dispatcher_host,
+ int request_id);
+
+ // FileSystemCallbackDispatcher implementation.
+ virtual void DidSucceed();
+ virtual void DidReadMetadata(const base::PlatformFileInfo& file_info);
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool has_more);
+ virtual void DidOpenFileSystem(const string16& name,
+ const FilePath& root_path);
+ virtual void DidFail(base::PlatformFileError error_code);
+
+ private:
+ scoped_refptr<FileSystemDispatcherHost> dispatcher_host_;
+ int request_id_;
+};
+
+#endif // CHROME_BROWSER_FILE_SYSTEM_BROWSER_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
diff --git a/chrome/browser/file_system/chrome_file_system_operation.cc b/chrome/browser/file_system/chrome_file_system_operation.cc
deleted file mode 100644
index 020aa3e..0000000
--- a/chrome/browser/file_system/chrome_file_system_operation.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2010 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/file_system/chrome_file_system_operation.h"
-
-#include "chrome/browser/chrome_thread.h"
-
-ChromeFileSystemOperation::ChromeFileSystemOperation(
- int request_id, fileapi::FileSystemOperationClient* client)
- : fileapi::FileSystemOperation(client,
- ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)),
- request_id_(request_id) { }
-
diff --git a/chrome/browser/file_system/chrome_file_system_operation.h b/chrome/browser/file_system/chrome_file_system_operation.h
deleted file mode 100644
index 3b1d3ca..0000000
--- a/chrome/browser/file_system/chrome_file_system_operation.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2010 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.
-
-#ifndef CHROME_BROWSER_FILE_SYSTEM_CHROME_FILE_SYSTEM_OPERATION_H_
-#define CHROME_BROWSER_FILE_SYSTEM_CHROME_FILE_SYSTEM_OPERATION_H_
-
-#include "webkit/fileapi/file_system_operation.h"
-
-// This class is designed to serve one-time file system operation per instance.
-// Only one method(CreateFile, CreateDirectory, Copy, Move, DirectoryExists,
-// GetMetadata, ReadDirectory and Remove) may be called during the lifetime of
-// this object and it should be called no more than once.
-class ChromeFileSystemOperation : public fileapi::FileSystemOperation {
- public:
- ChromeFileSystemOperation(
- int request_id, fileapi::FileSystemOperationClient* client);
-
- int request_id() const { return request_id_; }
-
- private:
- int request_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ChromeFileSystemOperation);
-};
-
-#endif // CHROME_BROWSER_FILE_SYSTEM_CHROME_FILE_SYSTEM_OPERATION_H_
-
diff --git a/chrome/browser/file_system/chrome_file_system_operation_unittest.cc b/chrome/browser/file_system/chrome_file_system_operation_unittest.cc
deleted file mode 100644
index 57ca164..0000000
--- a/chrome/browser/file_system/chrome_file_system_operation_unittest.cc
+++ /dev/null
@@ -1,571 +0,0 @@
-// Copyright (c) 2010 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/file_system/chrome_file_system_operation.h"
-
-#include "base/logging.h"
-#include "base/rand_util.h"
-#include "base/scoped_ptr.h"
-#include "base/scoped_temp_dir.h"
-#include "chrome/browser/chrome_thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h"
-#include "webkit/fileapi/file_system_operation_client.h"
-
-namespace {
-int kInvalidRequestId = -1;
-int kFileOperationStatusNotSet = 0;
-int kFileOperationSucceeded = 1;
-}
-
-using fileapi::FileSystemOperation;
-
-bool FileExists(FilePath path) {
- return file_util::PathExists(path) && !file_util::DirectoryExists(path);
-}
-
-class MockClient: public fileapi::FileSystemOperationClient {
- public:
- MockClient()
- : status_(kFileOperationStatusNotSet),
- request_id_(kInvalidRequestId) {
- }
-
- ~MockClient() {}
-
- virtual void DidFail(WebKit::WebFileError status,
- FileSystemOperation* operation) {
- status_ = status;
- request_id_ =
- static_cast<ChromeFileSystemOperation*>(operation)->request_id();
- }
-
- virtual void DidSucceed(FileSystemOperation* operation) {
- status_ = kFileOperationSucceeded;
- request_id_ =
- static_cast<ChromeFileSystemOperation*>(operation)->request_id();
- }
-
- virtual void DidReadMetadata(
- const base::PlatformFileInfo& info,
- FileSystemOperation* operation) {
- info_ = info;
- request_id_ =
- static_cast<ChromeFileSystemOperation*>(operation)->request_id();
- }
-
- virtual void DidReadDirectory(
- const std::vector<base::file_util_proxy::Entry>& entries,
- bool has_more,
- FileSystemOperation* operation) {
- entries_ = entries;
- request_id_ =
- static_cast<ChromeFileSystemOperation*>(operation)->request_id();
- }
-
- // Helpers for testing.
- int status() const { return status_; }
- int request_id() const { return request_id_; }
- const base::PlatformFileInfo& info() const { return info_; }
- const std::vector<base::file_util_proxy::Entry>& entries() const {
- return entries_;
- }
-
- private:
- int status_;
- int request_id_;
- base::PlatformFileInfo info_;
- std::vector<base::file_util_proxy::Entry> entries_;
-};
-
-class ChromeFileSystemOperationTest : public testing::Test {
- public:
- ChromeFileSystemOperationTest()
- : ui_thread_(ChromeThread::UI, &loop_),
- file_thread_(ChromeThread::FILE, &loop_) {
- base_.CreateUniqueTempDir();
- }
-
- protected:
- virtual void SetUp() {
- mock_client_.reset(new MockClient());
- current_request_id_ = kInvalidRequestId;
- ASSERT_TRUE(base_.IsValid());
- }
-
- // Returns a new operation pointer that is created each time it's called.
- // The pointer is owned by the test class.
- ChromeFileSystemOperation* operation() {
- current_request_id_ = base::RandInt(0, kint32max);
- operation_.reset(new ChromeFileSystemOperation(
- current_request_id_, mock_client_.get()));
- return operation_.get();
- }
-
- scoped_ptr<MockClient> mock_client_;
- int current_request_id_;
-
- MessageLoop loop_;
- ChromeThread ui_thread_;
- ChromeThread file_thread_;
-
- // Common temp base for all non-existing file/dir path test cases.
- // This is in case a dir on test machine exists. It's better to
- // create temp and then create non-existing file paths under it.
- ScopedTempDir base_;
-
- private:
- scoped_ptr<ChromeFileSystemOperation> operation_;
-
- DISALLOW_COPY_AND_ASSIGN(ChromeFileSystemOperationTest);
-};
-
-TEST_F(ChromeFileSystemOperationTest, TestMoveFailureSrcDoesntExist) {
- FilePath src(base_.path().Append(FILE_PATH_LITERAL("a")));
- FilePath dest(base_.path().Append(FILE_PATH_LITERAL("b")));
- operation()->Move(src, dest);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-
-TEST_F(ChromeFileSystemOperationTest, TestMoveFailureContainsPath) {
- FilePath file_under_base = base_.path().Append(FILE_PATH_LITERAL("b"));
- operation()->Move(base_.path(), file_under_base);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorInvalidModification, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestMoveFailureSrcDirExistsDestFile) {
- // Src exists and is dir. Dest is a file.
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
- FilePath dest_file;
- file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file);
-
- operation()->Move(base_.path(), dest_file);
- loop_.RunAllPending();
- EXPECT_EQ(mock_client_->status(), WebKit::WebFileErrorInvalidModification);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestMoveFailureDestParentDoesntExist) {
- // Dest. parent path does not exist.
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- FilePath nonexisting(base_.path().Append(FILE_PATH_LITERAL("DontExistDir")));
- FilePath nonexisting_file = nonexisting.Append(
- FILE_PATH_LITERAL("DontExistFile"));
-
- operation()->Move(src_dir.path(), nonexisting_file);
- loop_.RunAllPending();
- EXPECT_EQ(mock_client_->status(), WebKit::WebFileErrorNotFound);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- FilePath src_file;
- file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
-
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
- FilePath dest_file;
- file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file);
-
- operation()->Move(src_file, dest_file);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(FileExists(dest_file));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestMoveSuccessSrcFileAndNew) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- FilePath src_file;
- file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
-
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
- FilePath dest_file(dest_dir.path().Append(FILE_PATH_LITERAL("NewFile")));
-
- operation()->Move(src_file, dest_file);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(FileExists(dest_file));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopyFailureSrcDoesntExist) {
- FilePath src(base_.path().Append(FILE_PATH_LITERAL("a")));
- FilePath dest(base_.path().Append(FILE_PATH_LITERAL("b")));
- operation()->Copy(src, dest);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopyFailureContainsPath) {
- FilePath file_under_base = base_.path().Append(FILE_PATH_LITERAL("b"));
- operation()->Copy(base_.path(), file_under_base);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorInvalidModification, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopyFailureSrcDirExistsDestFile) {
- // Src exists and is dir. Dest is a file.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath dest_file;
- file_util::CreateTemporaryFileInDir(dir.path(), &dest_file);
-
- operation()->Copy(base_.path(), dest_file);
- loop_.RunAllPending();
- EXPECT_EQ(mock_client_->status(), WebKit::WebFileErrorInvalidModification);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopyFailureDestParentDoesntExist) {
- // Dest. parent path does not exist.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath src_dir = dir.path();
-
- FilePath nonexisting(base_.path().Append(FILE_PATH_LITERAL("DontExistDir")));
- file_util::EnsureEndsWithSeparator(&nonexisting);
- FilePath nonexisting_file = nonexisting.Append(
- FILE_PATH_LITERAL("DontExistFile"));
-
- operation()->Copy(src_dir, nonexisting_file);
- loop_.RunAllPending();
- EXPECT_EQ(mock_client_->status(), WebKit::WebFileErrorNotFound);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- FilePath src_file;
- file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
-
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
- FilePath dest_file;
- file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file);
-
- operation()->Copy(src_file, dest_file);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(FileExists(dest_file));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopySuccessSrcFileAndNew) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- FilePath src_file;
- file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
-
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
- FilePath dest_file(dest_dir.path().Append(FILE_PATH_LITERAL("NewFile")));
-
- operation()->Copy(src_file, dest_file);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(FileExists(dest_file));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopySuccessSrcDir) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
-
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
-
- operation()->Copy(src_dir.path(), dest_dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCopyDestParentExistsSuccess) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- FilePath src_file;
- file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
-
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
-
- operation()->Copy(src_file, dest_dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- FilePath src_filename(src_file.BaseName());
- EXPECT_TRUE(FileExists(dest_dir.path().Append(src_filename)));
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateFileFailure) {
- // Already existing file and exclusive true.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath file;
-
- file_util::CreateTemporaryFileInDir(dir.path(), &file);
- operation()->CreateFile(file, true);
- loop_.RunAllPending();
- EXPECT_EQ(mock_client_->status(), WebKit::WebFileErrorInvalidModification);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateFileSuccessFileExists) {
- // Already existing file and exclusive false.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath file;
- file_util::CreateTemporaryFileInDir(dir.path(), &file);
-
- operation()->CreateFile(file, false);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(FileExists(file));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateFileSuccessExclusive) {
- // File doesn't exist but exclusive is true.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath file = dir.path().Append(FILE_PATH_LITERAL("FileDoesntExist"));
- operation()->CreateFile(file, true);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(FileExists(file));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateFileSuccessFileDoesntExist) {
- // Non existing file.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath file = dir.path().Append(FILE_PATH_LITERAL("FileDoesntExist"));
- operation()->CreateFile(file, false);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest,
- TestCreateDirFailureDestParentDoesntExist) {
- // Dest. parent path does not exist.
- FilePath nonexisting(base_.path().Append(
- FILE_PATH_LITERAL("DirDoesntExist")));
- file_util::EnsureEndsWithSeparator(&nonexisting);
- FilePath nonexisting_file = nonexisting.Append(
- FILE_PATH_LITERAL("FileDoesntExist"));
- operation()->CreateDirectory(nonexisting_file, false);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateDirFailureDirExists) {
- // Exclusive and dir existing at path.
- operation()->CreateDirectory(base_.path(), true);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorInvalidModification, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateDirFailureFileExists) {
- // Exclusive true and file existing at path.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath file;
- file_util::CreateTemporaryFileInDir(dir.path(), &file);
- operation()->CreateDirectory(file, true);
- loop_.RunAllPending();
- EXPECT_EQ(mock_client_->status(),
- WebKit::WebFileErrorInvalidModification);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateDirSuccess) {
- // Dir exists and exclusive is false.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- operation()->CreateDirectory(dir.path(), false);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- // Dir doesn't exist.
- FilePath nonexisting_dir_path(FILE_PATH_LITERAL("nonexistingdir"));
- operation()->CreateDirectory(nonexisting_dir_path, false);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(file_util::DirectoryExists(nonexisting_dir_path));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestCreateDirSuccessExclusive) {
- // Dir doesn't exist.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath nonexisting_dir_path(dir.path().Append(
- FILE_PATH_LITERAL("nonexistingdir")));
-
- operation()->CreateDirectory(nonexisting_dir_path, true);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(file_util::DirectoryExists(nonexisting_dir_path));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestExistsAndMetadataFailure) {
- FilePath nonexisting_dir_path(base_.path().Append(
- FILE_PATH_LITERAL("nonexistingdir")));
- operation()->GetMetadata(nonexisting_dir_path);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
-
- operation()->FileExists(nonexisting_dir_path);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- file_util::EnsureEndsWithSeparator(&nonexisting_dir_path);
- operation()->DirectoryExists(nonexisting_dir_path);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestExistsAndMetadataSuccess) {
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
-
- operation()->DirectoryExists(dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- operation()->GetMetadata(dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_TRUE(mock_client_->info().is_directory);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- FilePath file;
- file_util::CreateTemporaryFileInDir(dir.path(), &file);
- operation()->FileExists(file);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- operation()->GetMetadata(file);
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_FALSE(mock_client_->info().is_directory);
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestReadDirFailure) {
- // Path doesn't exists
- FilePath nonexisting_dir_path(base_.path().Append(
- FILE_PATH_LITERAL("NonExistingDir")));
- file_util::EnsureEndsWithSeparator(&nonexisting_dir_path);
- operation()->ReadDirectory(nonexisting_dir_path);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- // File exists.
- ScopedTempDir dir;
- ASSERT_TRUE(dir.CreateUniqueTempDir());
- FilePath file;
- file_util::CreateTemporaryFileInDir(dir.path(), &file);
- operation()->ReadDirectory(file);
- loop_.RunAllPending();
- // TODO(kkanetkar) crbug.com/54309 to change the error code.
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestReadDirSuccess) {
- // parent_dir
- // | |
- // child_dir child_file
- // Verify reading parent_dir.
- ScopedTempDir parent_dir;
- ASSERT_TRUE(parent_dir.CreateUniqueTempDir());
- FilePath child_file;
- file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file);
- FilePath child_dir;
- ASSERT_TRUE(file_util::CreateTemporaryDirInDir(parent_dir.path(),
- FILE_PATH_LITERAL("child_dir"), &child_dir));
-
- operation()->ReadDirectory(parent_dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationStatusNotSet, mock_client_->status());
- EXPECT_EQ(2u, mock_client_->entries().size());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- for (size_t i = 0; i < mock_client_->entries().size(); ++i) {
- if (mock_client_->entries()[i].is_directory)
- EXPECT_EQ(child_dir.BaseName().value(), mock_client_->entries()[i].name);
- else
- EXPECT_EQ(child_file.BaseName().value(), mock_client_->entries()[i].name);
- }
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestRemoveFailure) {
- // Path doesn't exist.
- FilePath nonexisting(base_.path().Append(
- FILE_PATH_LITERAL("NonExistingDir")));
- file_util::EnsureEndsWithSeparator(&nonexisting);
-
- operation()->Remove(nonexisting);
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorNotFound, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-
- // By spec recursive is always false. Non-empty dir should fail.
- // parent_dir
- // | |
- // child_dir child_file
- // Verify deleting parent_dir.
- ScopedTempDir parent_dir;
- ASSERT_TRUE(parent_dir.CreateUniqueTempDir());
- FilePath child_file;
- file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file);
- FilePath child_dir;
- ASSERT_TRUE(file_util::CreateTemporaryDirInDir(parent_dir.path(),
- FILE_PATH_LITERAL("child_dir"), &child_dir));
-
- operation()->Remove(parent_dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(WebKit::WebFileErrorInvalidModification, mock_client_->status());
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
-
-TEST_F(ChromeFileSystemOperationTest, TestRemoveSuccess) {
- ScopedTempDir empty_dir;
- ASSERT_TRUE(empty_dir.CreateUniqueTempDir());
- EXPECT_TRUE(file_util::DirectoryExists(empty_dir.path()));
-
- operation()->Remove(empty_dir.path());
- loop_.RunAllPending();
- EXPECT_EQ(kFileOperationSucceeded, mock_client_->status());
- EXPECT_FALSE(file_util::DirectoryExists(empty_dir.path()));
- EXPECT_EQ(current_request_id_, mock_client_->request_id());
-}
diff --git a/chrome/browser/file_system/file_system_dispatcher_host.cc b/chrome/browser/file_system/file_system_dispatcher_host.cc
index 86555a2..385f2a4 100644
--- a/chrome/browser/file_system/file_system_dispatcher_host.cc
+++ b/chrome/browser/file_system/file_system_dispatcher_host.cc
@@ -10,13 +10,13 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/file_system/browser_file_system_callback_dispatcher.h"
#include "chrome/browser/file_system/file_system_host_context.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "googleurl/src/gurl.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h"
#include "webkit/glue/webkit_glue.h"
// A class to hold an ongoing openFileSystem completion task.
@@ -85,6 +85,9 @@ FileSystemDispatcherHost::FileSystemDispatcherHost(
DCHECK(message_sender_);
}
+FileSystemDispatcherHost::~FileSystemDispatcherHost() {
+}
+
void FileSystemDispatcherHost::Init(base::ProcessHandle process_handle) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
DCHECK(!shutdown_);
@@ -96,12 +99,6 @@ 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(
@@ -182,11 +179,12 @@ void FileSystemDispatcherHost::OnReadMetadata(
}
void FileSystemDispatcherHost::OnCreate(
- int request_id, const FilePath& path, bool exclusive, bool is_directory) {
+ int request_id, const FilePath& path, bool exclusive,
+ bool is_directory, bool recursive) {
if (!CheckValidFileSystemPath(path, request_id))
return;
if (is_directory)
- GetNewOperation(request_id)->CreateDirectory(path, exclusive);
+ GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive);
else
GetNewOperation(request_id)->CreateFile(path, exclusive);
}
@@ -208,46 +206,6 @@ void FileSystemDispatcherHost::OnReadDirectory(
GetNewOperation(request_id)->ReadDirectory(path);
}
-void FileSystemDispatcherHost::DidFail(
- WebKit::WebFileError status,
- fileapi::FileSystemOperation* operation) {
- int request_id =
- static_cast<ChromeFileSystemOperation*>(operation)->request_id();
- Send(new ViewMsg_FileSystem_DidFail(request_id, status));
- operations_.Remove(request_id);
-}
-
-void FileSystemDispatcherHost::DidSucceed(
- fileapi::FileSystemOperation* operation) {
- int request_id =
- static_cast<ChromeFileSystemOperation*>(operation)->request_id();
- Send(new ViewMsg_FileSystem_DidSucceed(request_id));
- operations_.Remove(request_id);
-}
-
-void FileSystemDispatcherHost::DidReadMetadata(
- const base::PlatformFileInfo& info,
- fileapi::FileSystemOperation* operation) {
- int request_id =
- static_cast<ChromeFileSystemOperation*>(operation)->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,
- fileapi::FileSystemOperation* operation) {
- int request_id =
- static_cast<ChromeFileSystemOperation*>(operation)->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_)
@@ -262,16 +220,24 @@ bool FileSystemDispatcherHost::CheckValidFileSystemPath(
// |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));
+ request_id, base::PLATFORM_FILE_ERROR_SECURITY));
return false;
}
return true;
}
-ChromeFileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
+fileapi::FileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
int request_id) {
- scoped_ptr<ChromeFileSystemOperation> operation(
- new ChromeFileSystemOperation(request_id, this));
- operations_.AddWithID(operation.get(), request_id);
- return operation.release();
+ BrowserFileSystemCallbackDispatcher* dispatcher =
+ new BrowserFileSystemCallbackDispatcher(this, request_id);
+ fileapi::FileSystemOperation* operation = new fileapi::FileSystemOperation(
+ dispatcher,
+ ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE));
+ operations_.AddWithID(operation, request_id);
+ return operation;
+}
+
+void FileSystemDispatcherHost::RemoveCompletedOperation(int request_id) {
+ DCHECK(operations_.Lookup(request_id));
+ operations_.Remove(request_id);
}
diff --git a/chrome/browser/file_system/file_system_dispatcher_host.h b/chrome/browser/file_system/file_system_dispatcher_host.h
index 8f21654..ac22255 100644
--- a/chrome/browser/file_system/file_system_dispatcher_host.h
+++ b/chrome/browser/file_system/file_system_dispatcher_host.h
@@ -13,9 +13,8 @@
#include "base/platform_file.h"
#include "base/scoped_callback_factory.h"
#include "base/ref_counted.h"
-#include "chrome/browser/file_system/chrome_file_system_operation.h"
#include "chrome/common/render_messages.h"
-#include "webkit/fileapi/file_system_operation_client.h"
+#include "webkit/fileapi/file_system_operation.h"
class FileSystemHostContext;
class HostContentSettingsMap;
@@ -23,12 +22,12 @@ class Receiver;
class ResourceMessageFilter;
class FileSystemDispatcherHost
- : public base::RefCountedThreadSafe<FileSystemDispatcherHost>,
- public fileapi::FileSystemOperationClient {
+ : public base::RefCountedThreadSafe<FileSystemDispatcherHost> {
public:
FileSystemDispatcherHost(IPC::Message::Sender* sender,
FileSystemHostContext* file_system_host_context,
HostContentSettingsMap* host_content_settings_map);
+ ~FileSystemDispatcherHost();
void Init(base::ProcessHandle process_handle);
void Shutdown();
@@ -46,25 +45,16 @@ class FileSystemDispatcherHost
void OnCreate(int request_id,
const FilePath& path,
bool exclusive,
- bool is_directory);
+ bool is_directory,
+ bool recursive);
void OnExists(int request_id, const FilePath& path, bool is_directory);
void OnReadDirectory(int request_id, const FilePath& path);
void Send(IPC::Message* message);
-
- // FileSystemOperationClient methods.
- virtual void DidFail(WebKit::WebFileError status,
- fileapi::FileSystemOperation* operation);
- virtual void DidSucceed(fileapi::FileSystemOperation* operation);
- virtual void DidReadMetadata(
- const base::PlatformFileInfo& info,
- fileapi::FileSystemOperation* operation);
- virtual void DidReadDirectory(
- const std::vector<base::file_util_proxy::Entry>& entries,
- bool has_more, fileapi::FileSystemOperation* operation);
+ void RemoveCompletedOperation(int request_id);
private:
- // Creates a new ChromeFileSystemOperation.
- ChromeFileSystemOperation* GetNewOperation(int request_id);
+ // Creates a new FileSystemOperation.
+ fileapi::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
@@ -85,7 +75,7 @@ class FileSystemDispatcherHost
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
// Keeps ongoing file system operations.
- typedef IDMap<ChromeFileSystemOperation, IDMapOwnPointer> OperationsMap;
+ typedef IDMap<fileapi::FileSystemOperation, IDMapOwnPointer> OperationsMap;
OperationsMap operations_;
DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcherHost);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 839dc87..ca6dd5d 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1527,8 +1527,8 @@
'browser/file_path_watcher_win.cc',
'browser/file_select_helper.cc',
'browser/file_select_helper.h',
- 'browser/file_system/chrome_file_system_operation.cc',
- 'browser/file_system/chrome_file_system_operation.h',
+ 'browser/file_system/browser_file_system_callback_dispatcher.cc',
+ 'browser/file_system/browser_file_system_callback_dispatcher.h',
'browser/file_system/file_system_dispatcher_host.cc',
'browser/file_system/file_system_dispatcher_host.h',
'browser/file_system/file_system_host_context.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 9bbe65a..28862b9 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1069,7 +1069,6 @@
'browser/extensions/user_script_listener_unittest.cc',
'browser/extensions/user_script_master_unittest.cc',
'browser/file_path_watcher_unittest.cc',
- 'browser/file_system/chrome_file_system_operation_unittest.cc',
'browser/file_system/file_system_host_context_unittest.cc',
'browser/find_backend_unittest.cc',
'browser/first_run/first_run_unittest.cc',
diff --git a/chrome/common/file_system/file_system_dispatcher.cc b/chrome/common/file_system/file_system_dispatcher.cc
index 89a2de4..8ae0c16 100644
--- a/chrome/common/file_system/file_system_dispatcher.cc
+++ b/chrome/common/file_system/file_system_dispatcher.cc
@@ -8,31 +8,20 @@
#include "chrome/common/child_thread.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileInfo.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemEntry.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemCallbacks.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/webkit_glue.h"
-using WebKit::WebFileError;
-using WebKit::WebFileInfo;
-using WebKit::WebFileSystemCallbacks;
-using WebKit::WebFileSystemEntry;
-using WebKit::WebVector;
-
FileSystemDispatcher::FileSystemDispatcher() {
}
FileSystemDispatcher::~FileSystemDispatcher() {
// Make sure we fire all the remaining callbacks.
- for (IDMap<WebFileSystemCallbacks>::iterator iter(&callbacks_);
- !iter.IsAtEnd();
- iter.Advance()) {
- int callbacks_id = iter.GetCurrentKey();
- WebFileSystemCallbacks* callbacks = iter.GetCurrentValue();
- DCHECK(callbacks);
- callbacks_.Remove(callbacks_id);
- callbacks->didFail(WebKit::WebFileErrorAbort);
+ for (IDMap<fileapi::FileSystemCallbackDispatcher, IDMapOwnPointer>::iterator
+ iter(&dispatchers_); !iter.IsAtEnd(); iter.Advance()) {
+ int request_id = iter.GetCurrentKey();
+ fileapi::FileSystemCallbackDispatcher* dispatcher = iter.GetCurrentValue();
+ DCHECK(dispatcher);
+ dispatcher->DidFail(base::PLATFORM_FILE_ERROR_ABORT);
+ dispatchers_.Remove(request_id);
}
}
@@ -48,103 +37,101 @@ bool FileSystemDispatcher::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
-void FileSystemDispatcher::Move(
- const string16& src_path, const string16& dest_path,
- WebFileSystemCallbacks* callbacks) {
- FilePath src_file_path = webkit_glue::WebStringToFilePath(src_path);
- FilePath dest_file_path = webkit_glue::WebStringToFilePath(dest_path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(new ViewHostMsg_FileSystem_Move(
- request_id, src_file_path, dest_file_path));
+bool FileSystemDispatcher::Move(
+ const FilePath& src_path,
+ const FilePath& dest_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(new ViewHostMsg_FileSystem_Move(
+ request_id, src_path, dest_path));
}
-void FileSystemDispatcher::Copy(
- const string16& src_path, const string16& dest_path,
- WebFileSystemCallbacks* callbacks) {
- FilePath src_file_path = webkit_glue::WebStringToFilePath(src_path);
- FilePath dest_file_path = webkit_glue::WebStringToFilePath(dest_path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(new ViewHostMsg_FileSystem_Copy(
- request_id, src_file_path, dest_file_path));
+bool FileSystemDispatcher::Copy(
+ const FilePath& src_path,
+ const FilePath& dest_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(new ViewHostMsg_FileSystem_Copy(
+ request_id, src_path, dest_path));
}
-void FileSystemDispatcher::Remove(
- const string16& path, WebFileSystemCallbacks* callbacks) {
- FilePath file_path = webkit_glue::WebStringToFilePath(path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(
- new ViewHostMsg_FileSystem_Remove(request_id, file_path));
+bool FileSystemDispatcher::Remove(
+ const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_Remove(request_id, path));
}
-void FileSystemDispatcher::ReadMetadata(
- const string16& path, WebFileSystemCallbacks* callbacks) {
- FilePath file_path = webkit_glue::WebStringToFilePath(path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(
- new ViewHostMsg_FileSystem_ReadMetadata(request_id, file_path));
+bool FileSystemDispatcher::ReadMetadata(
+ const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_ReadMetadata(request_id, path));
}
-void FileSystemDispatcher::Create(
- const string16& path, bool exclusive, bool is_directory,
- WebFileSystemCallbacks* callbacks) {
- FilePath file_path = webkit_glue::WebStringToFilePath(path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(new ViewHostMsg_FileSystem_Create(
- request_id, file_path, exclusive, is_directory));
+bool FileSystemDispatcher::Create(
+ const FilePath& path,
+ bool exclusive,
+ bool is_directory,
+ bool recursive,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(new ViewHostMsg_FileSystem_Create(
+ request_id, path, exclusive, is_directory, recursive));
}
-void FileSystemDispatcher::Exists(
- const string16& path, bool is_directory,
- WebFileSystemCallbacks* callbacks) {
- FilePath file_path = webkit_glue::WebStringToFilePath(path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(
- new ViewHostMsg_FileSystem_Exists(request_id, file_path, is_directory));
+bool FileSystemDispatcher::Exists(
+ const FilePath& path,
+ bool is_directory,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_Exists(request_id, path, is_directory));
}
-void FileSystemDispatcher::ReadDirectory(
- const string16& path, WebFileSystemCallbacks* callbacks) {
- FilePath file_path = webkit_glue::WebStringToFilePath(path);
- int request_id = callbacks_.Add(callbacks);
- ChildThread::current()->Send(
- new ViewHostMsg_FileSystem_ReadDirectory(request_id, file_path));
+bool FileSystemDispatcher::ReadDirectory(
+ const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_ReadDirectory(request_id, path));
}
void FileSystemDispatcher::DidSucceed(int request_id) {
- WebFileSystemCallbacks* callbacks = callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- callbacks_.Remove(request_id);
- callbacks->didSucceed();
+ fileapi::FileSystemCallbackDispatcher* dispatcher =
+ dispatchers_.Lookup(request_id);
+ DCHECK(dispatcher);
+ dispatcher->DidSucceed();
+ dispatchers_.Remove(request_id);
}
-void FileSystemDispatcher::DidReadMetadata(int request_id,
- const base::PlatformFileInfo& file_info) {
- WebFileSystemCallbacks* callbacks = callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- callbacks_.Remove(request_id);
- WebFileInfo web_file_info;
- web_file_info.modificationTime = file_info.last_modified.ToDoubleT();
- callbacks->didReadMetadata(web_file_info);
+void FileSystemDispatcher::DidReadMetadata(
+ int request_id, const base::PlatformFileInfo& file_info) {
+ fileapi::FileSystemCallbackDispatcher* dispatcher =
+ dispatchers_.Lookup(request_id);
+ DCHECK(dispatcher);
+ dispatcher->DidReadMetadata(file_info);
+ dispatchers_.Remove(request_id);
}
void FileSystemDispatcher::DidReadDirectory(
- const ViewMsg_FileSystem_DidReadDirectory_Params& params) {
- WebFileSystemCallbacks* callbacks = callbacks_.Lookup(params.request_id);
- DCHECK(callbacks);
- if (!params.has_more)
- 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::FilePathStringToWebString(
- params.entries[i].name);
- entries[i].isDirectory = params.entries[i].is_directory;
- }
- callbacks->didReadDirectory(entries, params.has_more);
+ int request_id,
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool has_more) {
+ fileapi::FileSystemCallbackDispatcher* dispatcher =
+ dispatchers_.Lookup(request_id);
+ DCHECK(dispatcher);
+ dispatcher->DidReadDirectory(entries, has_more);
+ dispatchers_.Remove(request_id);
}
-void FileSystemDispatcher::DidFail(int request_id, WebFileError code) {
- WebFileSystemCallbacks* callbacks = callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- callbacks_.Remove(request_id);
- callbacks->didFail(code);
+void FileSystemDispatcher::DidFail(
+ int request_id, base::PlatformFileError error_code) {
+ fileapi::FileSystemCallbackDispatcher* dispatcher =
+ dispatchers_.Lookup(request_id);
+ DCHECK(dispatcher);
+ dispatcher->DidFail(error_code);
+ dispatchers_.Remove(request_id);
}
diff --git a/chrome/common/file_system/file_system_dispatcher.h b/chrome/common/file_system/file_system_dispatcher.h
index 6fb9db5..8214b1c 100644
--- a/chrome/common/file_system/file_system_dispatcher.h
+++ b/chrome/common/file_system/file_system_dispatcher.h
@@ -8,24 +8,19 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/file_util_proxy.h"
#include "base/id_map.h"
#include "base/nullable_string16.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_message.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h"
-
-namespace WebKit {
-struct WebFileInfo;
-class WebFileSystemCallbacks;
-struct WebFileSystemEntry;
-}
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
namespace base {
struct PlatformFileInfo;
}
-struct ViewMsg_FileSystem_DidReadDirectory_Params;
+class FilePath;
// Dispatches and sends file system related messages sent to/from a child
// process from/to the main browser process. There is one instance
@@ -37,45 +32,38 @@ class FileSystemDispatcher {
bool OnMessageReceived(const IPC::Message& msg);
- void Move(
- const string16& src_path,
- const string16& dest_path,
- WebKit::WebFileSystemCallbacks* callbacks);
- void Copy(
- const string16& src_path,
- const string16& dest_path,
- WebKit::WebFileSystemCallbacks* callbacks);
- void Remove(
- const string16& path,
- WebKit::WebFileSystemCallbacks* callbacks);
- void ReadMetadata(
- const string16& path,
- WebKit::WebFileSystemCallbacks* callbacks);
- void Create(
- const string16& path,
- bool exclusive,
- bool for_directory,
- WebKit::WebFileSystemCallbacks* callbacks);
- void Exists(
- const string16& path,
- bool for_directory,
- WebKit::WebFileSystemCallbacks* callbacks);
- void ReadDirectory(
- const string16& path,
- WebKit::WebFileSystemCallbacks* callbacks);
+ bool Move(const FilePath& src_path,
+ const FilePath& dest_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Copy(const FilePath& src_path,
+ const FilePath& dest_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Remove(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool ReadMetadata(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Create(const FilePath& path,
+ bool exclusive,
+ bool is_directory,
+ bool recursive,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Exists(const FilePath& path,
+ bool for_directory,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool ReadDirectory(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
private:
void DidSucceed(int request_id);
- void DidReadMetadata(
- int request_id,
- const base::PlatformFileInfo& file_info);
+ void DidReadMetadata(int request_id,
+ const base::PlatformFileInfo& file_info);
void DidReadDirectory(
- const ViewMsg_FileSystem_DidReadDirectory_Params& params);
- void DidFail(
int request_id,
- WebKit::WebFileError);
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool has_more);
+ void DidFail(int request_id, base::PlatformFileError error_code);
- IDMap<WebKit::WebFileSystemCallbacks> callbacks_;
+ IDMap<fileapi::FileSystemCallbackDispatcher, IDMapOwnPointer> dispatchers_;
DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcher);
};
diff --git a/chrome/common/file_system/webfilesystem_impl.cc b/chrome/common/file_system/webfilesystem_impl.cc
index 49a07d6..546ed25 100644
--- a/chrome/common/file_system/webfilesystem_impl.cc
+++ b/chrome/common/file_system/webfilesystem_impl.cc
@@ -6,73 +6,164 @@
#include "chrome/common/file_system/file_system_dispatcher.h"
#include "chrome/common/child_thread.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileInfo.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemCallbacks.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
+#include "webkit/glue/webkit_glue.h"
-using WebKit::WebString;
+using WebKit::WebFileInfo;
using WebKit::WebFileSystemCallbacks;
+using WebKit::WebFileSystemEntry;
+using WebKit::WebString;
+using WebKit::WebVector;
+
+namespace {
+
+WebKit::WebFileError PlatformFileErrorToWebFileError(
+ base::PlatformFileError error_code) {
+ switch (error_code) {
+ case base::PLATFORM_FILE_ERROR_NOT_FOUND:
+ return WebKit::WebFileErrorNotFound;
+ case base::PLATFORM_FILE_ERROR_INVALID_OPERATION:
+ case base::PLATFORM_FILE_ERROR_EXISTS:
+ case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
+ return WebKit::WebFileErrorInvalidModification;
+ case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
+ return WebKit::WebFileErrorNoModificationAllowed;
+ case base::PLATFORM_FILE_ERROR_FAILED:
+ return WebKit::WebFileErrorInvalidState;
+ case base::PLATFORM_FILE_ERROR_ABORT:
+ return WebKit::WebFileErrorAbort;
+ default:
+ return WebKit::WebFileErrorInvalidModification;
+ }
+}
+
+class WebFileSystemCallbackDispatcherImpl
+ : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ explicit WebFileSystemCallbackDispatcherImpl(
+ WebFileSystemCallbacks* callbacks)
+ : callbacks_(callbacks) {
+ DCHECK(callbacks_);
+ }
+
+ virtual ~WebFileSystemCallbackDispatcherImpl() {
+ }
+
+ // FileSystemCallbackDispatcher implementation
+ virtual void DidSucceed() {
+ callbacks_->didSucceed();
+ }
+
+ virtual void DidReadMetadata(const base::PlatformFileInfo& file_info) {
+ WebFileInfo web_file_info;
+ web_file_info.modificationTime = file_info.last_modified.ToDoubleT();
+ callbacks_->didReadMetadata(web_file_info);
+ }
+
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries, bool has_more) {
+ WebVector<WebFileSystemEntry> file_system_entries(entries.size());
+ for (size_t i = 0; i < entries.size(); i++) {
+ file_system_entries[i].name =
+ webkit_glue::FilePathStringToWebString(entries[i].name);
+ file_system_entries[i].isDirectory = entries[i].is_directory;
+ }
+ callbacks_->didReadDirectory(file_system_entries, has_more);
+ }
+
+ virtual void DidOpenFileSystem(const string16&, const FilePath&) {
+ NOTREACHED();
+ }
+
+ virtual void DidFail(base::PlatformFileError error_code) {
+ callbacks_->didFail(PlatformFileErrorToWebFileError(error_code));
+ }
+
+ private:
+ WebFileSystemCallbacks* callbacks_;
+};
+
+} // namespace
WebFileSystemImpl::WebFileSystemImpl() {
}
void WebFileSystemImpl::move(const WebString& src_path,
- const WebString& dest_path, WebFileSystemCallbacks* callbacks) {
+ const WebString& dest_path,
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Move(src_path, dest_path, callbacks);
+ dispatcher->Move(webkit_glue::WebStringToFilePath(src_path),
+ webkit_glue::WebStringToFilePath(dest_path),
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
-void WebFileSystemImpl::copy(const WebKit::WebString& src_path,
- const WebKit::WebString& dest_path,
- WebKit::WebFileSystemCallbacks* callbacks) {
+void WebFileSystemImpl::copy(const WebString& src_path,
+ const WebString& dest_path,
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Copy(src_path, dest_path, callbacks);
+ dispatcher->Copy(webkit_glue::WebStringToFilePath(src_path),
+ webkit_glue::WebStringToFilePath(dest_path),
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::remove(const WebString& path,
- WebFileSystemCallbacks* callbacks) {
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Remove(path, callbacks);
+ dispatcher->Remove(webkit_glue::WebStringToFilePath(path),
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::readMetadata(const WebString& path,
- WebFileSystemCallbacks* callbacks) {
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->ReadMetadata(path, callbacks);
+ dispatcher->ReadMetadata(webkit_glue::WebStringToFilePath(path),
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::createFile(const WebString& path,
- bool exclusive, WebFileSystemCallbacks* callbacks) {
+ bool exclusive,
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Create(path, exclusive, false, callbacks);
+ dispatcher->Create(webkit_glue::WebStringToFilePath(path), exclusive, false,
+ false, new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::createDirectory(const WebString& path,
- bool exclusive, WebFileSystemCallbacks* callbacks) {
+ bool exclusive,
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Create(path, exclusive, true, callbacks);
+ dispatcher->Create(webkit_glue::WebStringToFilePath(path), exclusive, true,
+ false, new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::fileExists(const WebString& path,
- WebFileSystemCallbacks* callbacks) {
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Exists(path, false, callbacks);
+ dispatcher->Exists(webkit_glue::WebStringToFilePath(path), false,
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::directoryExists(const WebString& path,
- WebFileSystemCallbacks* callbacks) {
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->Exists(path, true, callbacks);
+ dispatcher->Exists(webkit_glue::WebStringToFilePath(path), true,
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
void WebFileSystemImpl::readDirectory(const WebString& path,
- WebFileSystemCallbacks* callbacks) {
+ WebFileSystemCallbacks* callbacks) {
FileSystemDispatcher* dispatcher =
ChildThread::current()->file_system_dispatcher();
- dispatcher->ReadDirectory(path, callbacks);
+ dispatcher->ReadDirectory(webkit_glue::WebStringToFilePath(path),
+ new WebFileSystemCallbackDispatcherImpl(callbacks));
}
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 8d7a973..4fcb1e5 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -106,7 +106,6 @@ struct ViewMsg_ExtensionsUpdated_Params;
struct ViewMsg_DeviceOrientationUpdated_Params;
struct ViewHostMsg_DomMessage_Params;
struct ViewHostMsg_OpenFileSystemRequest_Params;
-struct ViewMsg_FileSystem_DidReadDirectory_Params;
struct ViewHostMsg_AccessibilityNotification_Params;
// Values that may be OR'd together to form the 'flags' parameter of the
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 070123d..f391223 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -47,6 +47,12 @@ class SkBitmap;
struct ThumbnailScore;
class WebCursor;
+namespace base {
+namespace file_util_proxy {
+struct Entry;
+}
+}
+
namespace IPC {
struct ChannelHandle;
class Message;
@@ -1035,11 +1041,14 @@ IPC_BEGIN_MESSAGES(View)
IPC_MESSAGE_CONTROL2(ViewMsg_FileSystem_DidReadMetadata,
int /* request_id */,
base::PlatformFileInfo)
- IPC_MESSAGE_CONTROL1(ViewMsg_FileSystem_DidReadDirectory,
- ViewMsg_FileSystem_DidReadDirectory_Params)
+ IPC_MESSAGE_CONTROL3(ViewMsg_FileSystem_DidReadDirectory,
+ int /* request_id */,
+ std::vector<base::file_util_proxy::Entry> /* entries */,
+ bool /* has_more */)
+
IPC_MESSAGE_CONTROL2(ViewMsg_FileSystem_DidFail,
int /* request_id */,
- WebKit::WebFileError /* error_code */)
+ base::PlatformFileError /* error_code */)
// The response to ViewHostMsg_AsyncOpenFile.
IPC_MESSAGE_ROUTED3(ViewMsg_AsyncOpenFile_ACK,
@@ -2816,11 +2825,12 @@ IPC_BEGIN_MESSAGES(ViewHost)
FilePath /* path */)
// WebFileSystem::create() message.
- IPC_MESSAGE_CONTROL4(ViewHostMsg_FileSystem_Create,
+ IPC_MESSAGE_CONTROL5(ViewHostMsg_FileSystem_Create,
int /* request_id */,
FilePath /* path */,
bool /* exclusive */,
- bool /* is_directory */)
+ bool /* is_directory */,
+ bool /* recursive */)
// WebFileSystem::exists() messages.
IPC_MESSAGE_CONTROL3(ViewHostMsg_FileSystem_Exists,
diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc
index 325de2f..4fd83a3 100644
--- a/chrome/common/render_messages_params.cc
+++ b/chrome/common/render_messages_params.cc
@@ -325,16 +325,6 @@ ViewHostMsg_OpenFileSystemRequest_Params::
~ViewHostMsg_OpenFileSystemRequest_Params() {
}
-ViewMsg_FileSystem_DidReadDirectory_Params::
- ViewMsg_FileSystem_DidReadDirectory_Params()
- : request_id(0),
- has_more(false) {
-}
-
-ViewMsg_FileSystem_DidReadDirectory_Params::
- ~ViewMsg_FileSystem_DidReadDirectory_Params() {
-}
-
namespace IPC {
// Self contained templates which are only used inside serializing Params
@@ -1809,36 +1799,6 @@ void ParamTraits<ViewHostMsg_OpenFileSystemRequest_Params>::Log(
l->append(")");
}
-void ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params>::Write(
- Message* m,
- const param_type& p) {
- WriteParam(m, p.request_id);
- WriteParam(m, p.entries);
- WriteParam(m, p.has_more);
-}
-
-bool ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params>::Read(
- const Message* m,
- void** iter,
- param_type* p) {
- return
- ReadParam(m, iter, &p->request_id) &&
- ReadParam(m, iter, &p->entries) &&
- ReadParam(m, iter, &p->has_more);
-}
-
-void ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params>::Log(
- const param_type& p,
- std::string* l) {
- l->append("(");
- LogParam(p.request_id, l);
- l->append(", ");
- LogParam(p.entries, l);
- l->append(", ");
- LogParam(p.has_more, l);
- l->append(")");
-}
-
void ParamTraits<base::file_util_proxy::Entry>::Write(
Message* m,
const param_type& p) {
diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h
index 4847695..70f9825 100644
--- a/chrome/common/render_messages_params.h
+++ b/chrome/common/render_messages_params.h
@@ -964,20 +964,6 @@ struct ViewHostMsg_OpenFileSystemRequest_Params {
int64 requested_size;
};
-struct ViewMsg_FileSystem_DidReadDirectory_Params {
- ViewMsg_FileSystem_DidReadDirectory_Params();
- ~ViewMsg_FileSystem_DidReadDirectory_Params();
-
- // The response should have this id.
- int request_id;
-
- // A vector of directory entries.
- std::vector<base::file_util_proxy::Entry> entries;
-
- // Indicates if there will be more entries.
- bool has_more;
-};
-
struct ViewHostMsg_AccessibilityNotification_Params {
enum NotificationType {
// The node checked state has changed.
@@ -1259,14 +1245,6 @@ struct ParamTraits<ViewHostMsg_OpenFileSystemRequest_Params> {
};
template <>
-struct ParamTraits<ViewMsg_FileSystem_DidReadDirectory_Params> {
- typedef ViewMsg_FileSystem_DidReadDirectory_Params 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);
-};
-
-template <>
struct ParamTraits<base::file_util_proxy::Entry> {
typedef base::file_util_proxy::Entry param_type;
static void Write(Message* m, const param_type& p);
diff --git a/webkit/fileapi/file_system_callback_dispatcher.h b/webkit/fileapi/file_system_callback_dispatcher.h
new file mode 100644
index 0000000..37f22c23
--- /dev/null
+++ b/webkit/fileapi/file_system_callback_dispatcher.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2010 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.
+
+#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
+#define WEBKIT_FILEAPI_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
+
+#include <vector>
+
+#include "base/file_util_proxy.h"
+#include "base/string16.h"
+
+namespace fileapi {
+
+// This class mirrors the callbacks in
+// third_party/WebKit/WebKit/chromium/public/WebFileSystemCallbacks.h,
+// but uses chromium types.
+class FileSystemCallbackDispatcher {
+ public:
+ // Callback for various operations that don't require return values.
+ virtual void DidSucceed() = 0;
+
+ // Callback to report information for a file.
+ virtual void DidReadMetadata(const base::PlatformFileInfo& file_info) = 0;
+
+ // Callback to report the contents of a directory. If the contents of
+ // the given directory are reported in one batch, then |entries| will have
+ // the list of all files/directories in the given directory, |has_more| will
+ // be false, and this callback will be called only once. If the contents of
+ // the given directory are reported in multiple chunks, then this callback
+ // will be called multiple times, |entries| will have only a subset of
+ // all contents (the subsets reported in any two calls are disjoint), and
+ // |has_more| will be true, except for the last chunk.
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool has_more) = 0;
+
+ // Callback for opening a file system. Called with a name and root path for
+ // the FileSystem when the request is accepted. Used by WebFileSystem API.
+ virtual void DidOpenFileSystem(const string16& name,
+ const FilePath& root_path) = 0;
+
+ // Called with an error code when a requested operation has failed.
+ virtual void DidFail(base::PlatformFileError error_code) = 0;
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc
index 90eabad..dba9881 100644
--- a/webkit/fileapi/file_system_operation.cc
+++ b/webkit/fileapi/file_system_operation.cc
@@ -4,44 +4,32 @@
#include "webkit/fileapi/file_system_operation.h"
-#include "webkit/fileapi/file_system_operation_client.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h"
-
-namespace {
-// Utility method for error conversions.
-WebKit::WebFileError PlatformFileErrorToWebFileError(
- base::PlatformFileError rv) {
- switch (rv) {
- case base::PLATFORM_FILE_ERROR_NOT_FOUND:
- return WebKit::WebFileErrorNotFound;
- case base::PLATFORM_FILE_ERROR_INVALID_OPERATION:
- case base::PLATFORM_FILE_ERROR_EXISTS:
- case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
- return WebKit::WebFileErrorInvalidModification;
- case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
- return WebKit::WebFileErrorNoModificationAllowed;
- default:
- return WebKit::WebFileErrorInvalidModification;
- }
-}
-} // namespace
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
namespace fileapi {
FileSystemOperation::FileSystemOperation(
- FileSystemOperationClient* client,
+ FileSystemCallbackDispatcher* dispatcher,
scoped_refptr<base::MessageLoopProxy> proxy)
: proxy_(proxy),
- client_(client),
- callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
- operation_pending_(false) {
- DCHECK(client_);
+ dispatcher_(dispatcher),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ DCHECK(dispatcher);
+#ifndef NDEBUG
+ operation_pending_ = false;
+#endif
+}
+
+FileSystemOperation::~FileSystemOperation() {
}
void FileSystemOperation::CreateFile(const FilePath& path,
bool exclusive) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::CreateOrOpen(
proxy_, path, base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ,
callback_factory_.NewCallback(
@@ -50,18 +38,25 @@ void FileSystemOperation::CreateFile(const FilePath& path,
}
void FileSystemOperation::CreateDirectory(const FilePath& path,
- bool exclusive) {
+ bool exclusive,
+ bool recursive) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
- base::FileUtilProxy::CreateDirectory(proxy_, path, exclusive,
- false /* recursive */, callback_factory_.NewCallback(
+#endif
+
+ base::FileUtilProxy::CreateDirectory(
+ proxy_, path, exclusive, recursive, callback_factory_.NewCallback(
&FileSystemOperation::DidFinishFileOperation));
}
void FileSystemOperation::Copy(const FilePath& src_path,
const FilePath& dest_path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::Copy(proxy_, src_path, dest_path,
callback_factory_.NewCallback(
&FileSystemOperation::DidFinishFileOperation));
@@ -69,45 +64,63 @@ void FileSystemOperation::Copy(const FilePath& src_path,
void FileSystemOperation::Move(const FilePath& src_path,
const FilePath& dest_path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::Move(proxy_, src_path, dest_path,
callback_factory_.NewCallback(
&FileSystemOperation::DidFinishFileOperation));
}
void FileSystemOperation::DirectoryExists(const FilePath& path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback(
&FileSystemOperation::DidDirectoryExists));
}
void FileSystemOperation::FileExists(const FilePath& path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback(
&FileSystemOperation::DidFileExists));
}
void FileSystemOperation::GetMetadata(const FilePath& path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback(
&FileSystemOperation::DidGetMetadata));
}
void FileSystemOperation::ReadDirectory(const FilePath& path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::ReadDirectory(proxy_, path,
callback_factory_.NewCallback(
&FileSystemOperation::DidReadDirectory));
}
void FileSystemOperation::Remove(const FilePath& path) {
+#ifndef NDEBUG
DCHECK(!operation_pending_);
operation_pending_ = true;
+#endif
+
base::FileUtilProxy::Delete(proxy_, path, callback_factory_.NewCallback(
&FileSystemOperation::DidFinishFileOperation));
}
@@ -126,17 +139,17 @@ void FileSystemOperation::DidCreateFileNonExclusive(
// Suppress the already exists error and report success.
if (rv == base::PLATFORM_FILE_OK ||
rv == base::PLATFORM_FILE_ERROR_EXISTS)
- client_->DidSucceed(this);
+ dispatcher_->DidSucceed();
else
- client_->DidFail(PlatformFileErrorToWebFileError(rv), this);
+ dispatcher_->DidFail(rv);
}
void FileSystemOperation::DidFinishFileOperation(
base::PlatformFileError rv) {
if (rv == base::PLATFORM_FILE_OK)
- client_->DidSucceed(this);
+ dispatcher_->DidSucceed();
else
- client_->DidFail(PlatformFileErrorToWebFileError(rv), this);
+ dispatcher_->DidFail(rv);
}
void FileSystemOperation::DidDirectoryExists(
@@ -144,14 +157,11 @@ void FileSystemOperation::DidDirectoryExists(
const base::PlatformFileInfo& file_info) {
if (rv == base::PLATFORM_FILE_OK) {
if (file_info.is_directory)
- client_->DidSucceed(this);
+ dispatcher_->DidSucceed();
else
- client_->DidFail(WebKit::WebFileErrorInvalidState,
- this);
- } else {
- // Something else went wrong.
- client_->DidFail(PlatformFileErrorToWebFileError(rv), this);
- }
+ dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_FAILED);
+ } else
+ dispatcher_->DidFail(rv);
}
void FileSystemOperation::DidFileExists(
@@ -159,34 +169,29 @@ void FileSystemOperation::DidFileExists(
const base::PlatformFileInfo& file_info) {
if (rv == base::PLATFORM_FILE_OK) {
if (file_info.is_directory)
- client_->DidFail(WebKit::WebFileErrorInvalidState,
- this);
+ dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_FAILED);
else
- client_->DidSucceed(this);
- } else {
- // Something else went wrong.
- client_->DidFail(PlatformFileErrorToWebFileError(rv), this);
- }
+ dispatcher_->DidSucceed();
+ } else
+ dispatcher_->DidFail(rv);
}
void FileSystemOperation::DidGetMetadata(
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info) {
if (rv == base::PLATFORM_FILE_OK)
- client_->DidReadMetadata(file_info, this);
+ dispatcher_->DidReadMetadata(file_info);
else
- client_->DidFail(PlatformFileErrorToWebFileError(rv), this);
+ dispatcher_->DidFail(rv);
}
void FileSystemOperation::DidReadDirectory(
base::PlatformFileError rv,
const std::vector<base::file_util_proxy::Entry>& entries) {
if (rv == base::PLATFORM_FILE_OK)
- client_->DidReadDirectory(
- entries, false /* has_more */ , this);
+ dispatcher_->DidReadDirectory(entries, false /* has_more */);
else
- client_->DidFail(PlatformFileErrorToWebFileError(rv), this);
+ dispatcher_->DidFail(rv);
}
} // namespace fileapi
-
diff --git a/webkit/fileapi/file_system_operation.h b/webkit/fileapi/file_system_operation.h
index 9e0fed9..5df4d4d 100644
--- a/webkit/fileapi/file_system_operation.h
+++ b/webkit/fileapi/file_system_operation.h
@@ -13,10 +13,11 @@
#include "base/platform_file.h"
#include "base/ref_counted.h"
#include "base/scoped_callback_factory.h"
+#include "base/scoped_ptr.h"
namespace fileapi {
-class FileSystemOperationClient;
+class FileSystemCallbackDispatcher;
// This class is designed to serve one-time file system operation per instance.
// Only one method(CreateFile, CreateDirectory, Copy, Move, DirectoryExists,
@@ -24,15 +25,16 @@ class FileSystemOperationClient;
// this object and it should be called no more than once.
class FileSystemOperation {
public:
- FileSystemOperation(
- FileSystemOperationClient* client,
- scoped_refptr<base::MessageLoopProxy> proxy);
+ FileSystemOperation(FileSystemCallbackDispatcher* dispatcher,
+ scoped_refptr<base::MessageLoopProxy> proxy);
+ ~FileSystemOperation();
void CreateFile(const FilePath& path,
bool exclusive);
void CreateDirectory(const FilePath& path,
- bool exclusive);
+ bool exclusive,
+ bool recursive);
void Copy(const FilePath& src_path,
const FilePath& dest_path);
@@ -82,13 +84,14 @@ class FileSystemOperation {
base::PlatformFileError rv,
const std::vector<base::file_util_proxy::Entry>& entries);
- // Not owned.
- FileSystemOperationClient* client_;
+ scoped_ptr<FileSystemCallbackDispatcher> dispatcher_;
base::ScopedCallbackFactory<FileSystemOperation> callback_factory_;
+#ifndef NDEBUG
// A flag to make sure we call operation only once per instance.
bool operation_pending_;
+#endif
DISALLOW_COPY_AND_ASSIGN(FileSystemOperation);
};
@@ -96,4 +99,3 @@ class FileSystemOperation {
} // namespace fileapi
#endif // WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_H_
-
diff --git a/webkit/fileapi/file_system_operation_client.h b/webkit/fileapi/file_system_operation_client.h
deleted file mode 100644
index b126d4e..0000000
--- a/webkit/fileapi/file_system_operation_client.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2010 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.
-
-#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_CLIENT_H_
-#define WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_CLIENT_H_
-
-#include <vector>
-
-#include "base/file_util_proxy.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h"
-
-namespace fileapi {
-
-class FileSystemOperation;
-
-// Interface for client of FileSystemOperation.
-class FileSystemOperationClient {
- public:
- virtual ~FileSystemOperationClient() {}
-
- virtual void DidFail(
- WebKit::WebFileError status,
- FileSystemOperation* operation) = 0;
-
- virtual void DidSucceed(FileSystemOperation* operation) = 0;
-
- // Info about the file entry such as modification date and size.
- virtual void DidReadMetadata(const base::PlatformFileInfo& info,
- FileSystemOperation* operation) = 0;
-
- virtual void DidReadDirectory(
- const std::vector<base::file_util_proxy::Entry>& entries,
- bool has_more, FileSystemOperation* operation) = 0;
-};
-
-} // namespace fileapi
-
-#endif // WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_CLIENT_H_
diff --git a/webkit/fileapi/file_system_operation_unittest.cc b/webkit/fileapi/file_system_operation_unittest.cc
new file mode 100644
index 0000000..1d0855c
--- /dev/null
+++ b/webkit/fileapi/file_system_operation_unittest.cc
@@ -0,0 +1,555 @@
+// Copyright (c) 2010 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 "webkit/fileapi/file_system_operation.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/scoped_ptr.h"
+#include "base/scoped_temp_dir.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/fileapi/file_system_operation.h"
+
+const int kInvalidRequestId = -1;
+const int kFileOperationStatusNotSet = 0;
+const int kFileOperationSucceeded = 1;
+
+static int last_request_id = -1;
+
+bool FileExists(FilePath path) {
+ return file_util::PathExists(path) && !file_util::DirectoryExists(path);
+}
+
+class MockDispatcher : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ MockDispatcher(int request_id)
+ : status_(kFileOperationStatusNotSet),
+ request_id_(request_id) {
+ }
+
+ virtual void DidFail(base::PlatformFileError status) {
+ status_ = status;
+ }
+
+ virtual void DidSucceed() {
+ status_ = kFileOperationSucceeded;
+ }
+
+ virtual void DidReadMetadata(const base::PlatformFileInfo& info) {
+ info_ = info;
+ status_ = kFileOperationSucceeded;
+ }
+
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool /* has_more */) {
+ entries_ = entries;
+ }
+
+ virtual void DidOpenFileSystem(const string16&, const FilePath&) {
+ NOTREACHED();
+ }
+
+ // Helpers for testing.
+ int status() const { return status_; }
+ int request_id() const { return request_id_; }
+ const base::PlatformFileInfo& info() const { return info_; }
+ const std::vector<base::file_util_proxy::Entry>& entries() const {
+ return entries_;
+ }
+
+ private:
+ int status_;
+ int request_id_;
+ base::PlatformFileInfo info_;
+ std::vector<base::file_util_proxy::Entry> entries_;
+};
+
+class FileSystemOperationTest : public testing::Test {
+ public:
+ FileSystemOperationTest()
+ : request_id_(kInvalidRequestId),
+ operation_(NULL) {
+ base_.CreateUniqueTempDir();
+ EXPECT_TRUE(base_.IsValid());
+ }
+
+ fileapi::FileSystemOperation* operation() {
+ request_id_ = ++last_request_id;
+ mock_dispatcher_ = new MockDispatcher(request_id_);
+ operation_.reset(new fileapi::FileSystemOperation(
+ mock_dispatcher_, base::MessageLoopProxy::CreateForCurrentThread()));
+ return operation_.get();
+ }
+
+ protected:
+ // Common temp base for all non-existing file/dir path test cases.
+ // This is in case a dir on test machine exists. It's better to
+ // create temp and then create non-existing file paths under it.
+ ScopedTempDir base_;
+
+ int request_id_;
+ scoped_ptr<fileapi::FileSystemOperation> operation_;
+
+ // Owned by |operation_|.
+ MockDispatcher* mock_dispatcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileSystemOperationTest);
+};
+
+TEST_F(FileSystemOperationTest, TestMoveFailureSrcDoesntExist) {
+ FilePath src(base_.path().Append(FILE_PATH_LITERAL("a")));
+ FilePath dest(base_.path().Append(FILE_PATH_LITERAL("b")));
+ operation()->Move(src, dest);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+
+TEST_F(FileSystemOperationTest, TestMoveFailureContainsPath) {
+ ScopedTempDir dir_under_base;
+ dir_under_base.CreateUniqueTempDirUnderPath(base_.path());
+ operation()->Move(base_.path(), dir_under_base.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION,
+ mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestMoveFailureSrcDirExistsDestFile) {
+ // Src exists and is dir. Dest is a file.
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+ FilePath dest_file;
+ file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file);
+
+ operation()->Move(base_.path(), dest_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestMoveFailureDestParentDoesntExist) {
+ // Dest. parent path does not exist.
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+ FilePath nonexisting_file = base_.path().Append(
+ FILE_PATH_LITERAL("NonexistingDir")).Append(
+ FILE_PATH_LITERAL("NonexistingFile"));;
+
+ operation()->Move(src_dir.path(), nonexisting_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) {
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+ FilePath src_file;
+ file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
+
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+ FilePath dest_file;
+ file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file);
+
+ operation()->Move(src_file, dest_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(FileExists(dest_file));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndNew) {
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+ FilePath src_file;
+ file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
+
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+ FilePath dest_file(dest_dir.path().Append(FILE_PATH_LITERAL("NewFile")));
+
+ operation()->Move(src_file, dest_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(FileExists(dest_file));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopyFailureSrcDoesntExist) {
+ FilePath src(base_.path().Append(FILE_PATH_LITERAL("a")));
+ FilePath dest(base_.path().Append(FILE_PATH_LITERAL("b")));
+ operation()->Copy(src, dest);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopyFailureContainsPath) {
+ FilePath file_under_base = base_.path().Append(FILE_PATH_LITERAL("b"));
+ operation()->Copy(base_.path(), file_under_base);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_FAILED, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopyFailureSrcDirExistsDestFile) {
+ // Src exists and is dir. Dest is a file.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath dest_file;
+ file_util::CreateTemporaryFileInDir(dir.path(), &dest_file);
+
+ operation()->Copy(base_.path(), dest_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY,
+ mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopyFailureDestParentDoesntExist) {
+ // Dest. parent path does not exist.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath src_dir = dir.path();
+
+ FilePath nonexisting(base_.path().Append(FILE_PATH_LITERAL("DontExistDir")));
+ file_util::EnsureEndsWithSeparator(&nonexisting);
+ FilePath nonexisting_file = nonexisting.Append(
+ FILE_PATH_LITERAL("DontExistFile"));
+
+ operation()->Copy(src_dir, nonexisting_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) {
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+ FilePath src_file;
+ file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
+
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+ FilePath dest_file;
+ file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file);
+
+ operation()->Copy(src_file, dest_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(FileExists(dest_file));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndNew) {
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+ FilePath src_file;
+ file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
+
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+ FilePath dest_file(dest_dir.path().Append(FILE_PATH_LITERAL("NewFile")));
+
+ operation()->Copy(src_file, dest_file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(FileExists(dest_file));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopySuccessSrcDir) {
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+
+ operation()->Copy(src_dir.path(), dest_dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCopyDestParentExistsSuccess) {
+ ScopedTempDir src_dir;
+ ASSERT_TRUE(src_dir.CreateUniqueTempDir());
+ FilePath src_file;
+ file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file);
+
+ ScopedTempDir dest_dir;
+ ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
+
+ operation()->Copy(src_file, dest_dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ FilePath src_filename(src_file.BaseName());
+ EXPECT_TRUE(FileExists(dest_dir.path().Append(src_filename)));
+}
+
+TEST_F(FileSystemOperationTest, TestCreateFileFailure) {
+ // Already existing file and exclusive true.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath file;
+
+ file_util::CreateTemporaryFileInDir(dir.path(), &file);
+ operation()->CreateFile(file, true);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateFileSuccessFileExists) {
+ // Already existing file and exclusive false.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath file;
+ file_util::CreateTemporaryFileInDir(dir.path(), &file);
+
+ operation()->CreateFile(file, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(FileExists(file));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateFileSuccessExclusive) {
+ // File doesn't exist but exclusive is true.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath file = dir.path().Append(FILE_PATH_LITERAL("FileDoesntExist"));
+ operation()->CreateFile(file, true);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(FileExists(file));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateFileSuccessFileDoesntExist) {
+ // Non existing file.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath file = dir.path().Append(FILE_PATH_LITERAL("FileDoesntExist"));
+ operation()->CreateFile(file, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest,
+ TestCreateDirFailureDestParentDoesntExist) {
+ // Dest. parent path does not exist.
+ FilePath nonexisting(base_.path().Append(
+ FILE_PATH_LITERAL("DirDoesntExist")));
+ file_util::EnsureEndsWithSeparator(&nonexisting);
+ FilePath nonexisting_file = nonexisting.Append(
+ FILE_PATH_LITERAL("FileDoesntExist"));
+ operation()->CreateDirectory(nonexisting_file, false, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateDirFailureDirExists) {
+ // Exclusive and dir existing at path.
+ operation()->CreateDirectory(base_.path(), true, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateDirFailureFileExists) {
+ // Exclusive true and file existing at path.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath file;
+ file_util::CreateTemporaryFileInDir(dir.path(), &file);
+ operation()->CreateDirectory(file, true, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateDirSuccess) {
+ // Dir exists and exclusive is false.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ operation()->CreateDirectory(dir.path(), false, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ // Dir doesn't exist.
+ FilePath nonexisting_dir_path(FILE_PATH_LITERAL("nonexistingdir"));
+ operation()->CreateDirectory(nonexisting_dir_path, false, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(file_util::DirectoryExists(nonexisting_dir_path));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestCreateDirSuccessExclusive) {
+ // Dir doesn't exist.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath nonexisting_dir_path(dir.path().Append(
+ FILE_PATH_LITERAL("nonexistingdir")));
+
+ operation()->CreateDirectory(nonexisting_dir_path, true, false);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(file_util::DirectoryExists(nonexisting_dir_path));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestExistsAndMetadataFailure) {
+ FilePath nonexisting_dir_path(base_.path().Append(
+ FILE_PATH_LITERAL("nonexistingdir")));
+ operation()->GetMetadata(nonexisting_dir_path);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+
+ operation()->FileExists(nonexisting_dir_path);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ file_util::EnsureEndsWithSeparator(&nonexisting_dir_path);
+ operation()->DirectoryExists(nonexisting_dir_path);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestExistsAndMetadataSuccess) {
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+
+ operation()->DirectoryExists(dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ operation()->GetMetadata(dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_TRUE(mock_dispatcher_->info().is_directory);
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ FilePath file;
+ file_util::CreateTemporaryFileInDir(dir.path(), &file);
+ operation()->FileExists(file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ operation()->GetMetadata(file);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_FALSE(mock_dispatcher_->info().is_directory);
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestReadDirFailure) {
+ // Path doesn't exists
+ FilePath nonexisting_dir_path(base_.path().Append(
+ FILE_PATH_LITERAL("NonExistingDir")));
+ file_util::EnsureEndsWithSeparator(&nonexisting_dir_path);
+ operation()->ReadDirectory(nonexisting_dir_path);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ // File exists.
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ FilePath file;
+ file_util::CreateTemporaryFileInDir(dir.path(), &file);
+ operation()->ReadDirectory(file);
+ MessageLoop::current()->RunAllPending();
+ // TODO(kkanetkar) crbug.com/54309 to change the error code.
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestReadDirSuccess) {
+ // parent_dir
+ // | |
+ // child_dir child_file
+ // Verify reading parent_dir.
+ ScopedTempDir parent_dir;
+ ASSERT_TRUE(parent_dir.CreateUniqueTempDir());
+ FilePath child_file;
+ file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file);
+ FilePath child_dir;
+ ASSERT_TRUE(file_util::CreateTemporaryDirInDir(
+ parent_dir.path(), FILE_PATH_LITERAL("child_dir"), &child_dir));
+
+ operation()->ReadDirectory(parent_dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationStatusNotSet, mock_dispatcher_->status());
+ EXPECT_EQ(2u, mock_dispatcher_->entries().size());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ for (size_t i = 0; i < mock_dispatcher_->entries().size(); ++i) {
+ if (mock_dispatcher_->entries()[i].is_directory) {
+ EXPECT_EQ(child_dir.BaseName().value(),
+ mock_dispatcher_->entries()[i].name);
+ } else {
+ EXPECT_EQ(child_file.BaseName().value(),
+ mock_dispatcher_->entries()[i].name);
+ }
+ }
+}
+
+TEST_F(FileSystemOperationTest, TestRemoveFailure) {
+ // Path doesn't exist.
+ FilePath nonexisting(base_.path().Append(
+ FILE_PATH_LITERAL("NonExistingDir")));
+ file_util::EnsureEndsWithSeparator(&nonexisting);
+
+ operation()->Remove(nonexisting);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+
+ // By spec recursive is always false. Non-empty dir should fail.
+ // parent_dir
+ // | |
+ // child_dir child_file
+ // Verify deleting parent_dir.
+ ScopedTempDir parent_dir;
+ ASSERT_TRUE(parent_dir.CreateUniqueTempDir());
+ FilePath child_file;
+ file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file);
+ FilePath child_dir;
+ ASSERT_TRUE(file_util::CreateTemporaryDirInDir(
+ parent_dir.path(), FILE_PATH_LITERAL("child_dir"), &child_dir));
+
+ operation()->Remove(parent_dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION,
+ mock_dispatcher_->status());
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
+
+TEST_F(FileSystemOperationTest, TestRemoveSuccess) {
+ ScopedTempDir empty_dir;
+ ASSERT_TRUE(empty_dir.CreateUniqueTempDir());
+ EXPECT_TRUE(file_util::DirectoryExists(empty_dir.path()));
+
+ operation()->Remove(empty_dir.path());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status());
+ EXPECT_FALSE(file_util::DirectoryExists(empty_dir.path()));
+ EXPECT_EQ(request_id_, mock_dispatcher_->request_id());
+}
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index cce29cc..37c75cb 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -14,9 +14,9 @@
'<(DEPTH)/net/net.gyp:net',
],
'sources': [
+ 'file_system_callback_dispatcher.h',
'file_system_operation.cc',
'file_system_operation.h',
- 'file_system_operation_client.h',
],
'conditions': [
['inside_chromium_build==0', {
diff --git a/webkit/tools/test_shell/simple_file_system.cc b/webkit/tools/test_shell/simple_file_system.cc
index a5524db..0b76758 100644
--- a/webkit/tools/test_shell/simple_file_system.cc
+++ b/webkit/tools/test_shell/simple_file_system.cc
@@ -10,23 +10,101 @@
#include "third_party/WebKit/WebKit/chromium/public/WebFileInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemEntry.h"
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
#include "webkit/glue/webkit_glue.h"
+using WebKit::WebFileInfo;
using WebKit::WebFileSystemCallbacks;
+using WebKit::WebFileSystemEntry;
using WebKit::WebString;
+using WebKit::WebVector;
+
+namespace {
+
+WebKit::WebFileError PlatformFileErrorToWebFileError(
+ base::PlatformFileError error_code) {
+ switch (error_code) {
+ case base::PLATFORM_FILE_ERROR_NOT_FOUND:
+ return WebKit::WebFileErrorNotFound;
+ case base::PLATFORM_FILE_ERROR_INVALID_OPERATION:
+ case base::PLATFORM_FILE_ERROR_EXISTS:
+ case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
+ return WebKit::WebFileErrorInvalidModification;
+ case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
+ return WebKit::WebFileErrorNoModificationAllowed;
+ case base::PLATFORM_FILE_ERROR_FAILED:
+ return WebKit::WebFileErrorInvalidState;
+ case base::PLATFORM_FILE_ERROR_ABORT:
+ return WebKit::WebFileErrorAbort;
+ default:
+ return WebKit::WebFileErrorInvalidModification;
+ }
+}
+
+class TestShellFileSystemCallbackDispatcher
+ : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ TestShellFileSystemCallbackDispatcher(
+ SimpleFileSystem* file_system,
+ WebFileSystemCallbacks* callbacks)
+ : file_system_(file_system),
+ callbacks_(callbacks),
+ request_id_(-1) {
+ }
+
+ void set_request_id(int request_id) { request_id_ = request_id; }
+
+ virtual void DidSucceed() {
+ callbacks_->didSucceed();
+ file_system_->RemoveCompletedOperation(request_id_);
+ }
+
+ virtual void DidReadMetadata(const base::PlatformFileInfo& info) {
+ WebFileInfo web_file_info;
+ web_file_info.modificationTime = info.last_modified.ToDoubleT();
+ callbacks_->didReadMetadata(web_file_info);
+ file_system_->RemoveCompletedOperation(request_id_);
+ }
+
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool has_more) {
+ std::vector<WebFileSystemEntry> web_entries_vector;
+ for (std::vector<base::file_util_proxy::Entry>::const_iterator it =
+ entries.begin(); it != entries.end(); ++it) {
+ WebFileSystemEntry entry;
+ entry.name = webkit_glue::FilePathStringToWebString(it->name);
+ entry.isDirectory = it->is_directory;
+ web_entries_vector.push_back(entry);
+ }
+ WebVector<WebKit::WebFileSystemEntry> web_entries =
+ web_entries_vector;
+ callbacks_->didReadDirectory(web_entries, has_more);
+ file_system_->RemoveCompletedOperation(request_id_);
+ }
+
+ virtual void DidOpenFileSystem(const string16&, const FilePath&) {
+ NOTREACHED();
+ }
-TestShellFileSystemOperation::TestShellFileSystemOperation(
- fileapi::FileSystemOperationClient* client,
- scoped_refptr<base::MessageLoopProxy> proxy,
- WebFileSystemCallbacks* callbacks)
- : fileapi::FileSystemOperation(client, proxy), callbacks_(callbacks) { }
+ virtual void DidFail(base::PlatformFileError error_code) {
+ callbacks_->didFail(PlatformFileErrorToWebFileError(error_code));
+ file_system_->RemoveCompletedOperation(request_id_);
+ }
+
+ private:
+ SimpleFileSystem* file_system_;
+ WebFileSystemCallbacks* callbacks_;
+ int request_id_;
+};
+
+} // namespace
SimpleFileSystem::~SimpleFileSystem() {
// Drop all the operations.
for (OperationsMap::const_iterator iter(&operations_);
- !iter.IsAtEnd(); iter.Advance()) {
+ !iter.IsAtEnd(); iter.Advance())
operations_.Remove(iter.GetCurrentKey());
- }
}
void SimpleFileSystem::move(
@@ -72,7 +150,7 @@ void SimpleFileSystem::createDirectory(
const WebString& path, bool exclusive, WebFileSystemCallbacks* callbacks) {
FilePath filepath(webkit_glue::WebStringToFilePath(path));
- GetNewOperation(callbacks)->CreateDirectory(filepath, exclusive);
+ GetNewOperation(callbacks)->CreateDirectory(filepath, exclusive, false);
}
void SimpleFileSystem::fileExists(
@@ -96,65 +174,18 @@ void SimpleFileSystem::readDirectory(
GetNewOperation(callbacks)->ReadDirectory(filepath);
}
-void SimpleFileSystem::DidFail(WebKit::WebFileError status,
- fileapi::FileSystemOperation* operation) {
- WebFileSystemCallbacks* callbacks =
- static_cast<TestShellFileSystemOperation*>(operation)->callbacks();
- callbacks->didFail(status);
- RemoveOperation(operation);
-}
-
-void SimpleFileSystem::DidSucceed(fileapi::FileSystemOperation* operation) {
- WebFileSystemCallbacks* callbacks =
- static_cast<TestShellFileSystemOperation*>(operation)->callbacks();
- callbacks->didSucceed();
- RemoveOperation(operation);
-}
-
-void SimpleFileSystem::DidReadMetadata(
- const base::PlatformFileInfo& info,
- fileapi::FileSystemOperation* operation) {
- WebFileSystemCallbacks* callbacks =
- static_cast<TestShellFileSystemOperation*>(operation)->callbacks();
- WebKit::WebFileInfo web_file_info;
- web_file_info.modificationTime = info.last_modified.ToDoubleT();
- callbacks->didReadMetadata(web_file_info);
- RemoveOperation(operation);
-}
-
-void SimpleFileSystem::DidReadDirectory(
- const std::vector<base::file_util_proxy::Entry>& entries,
- bool has_more, fileapi::FileSystemOperation* operation) {
- WebFileSystemCallbacks* callbacks =
- static_cast<TestShellFileSystemOperation*>(operation)->callbacks();
- std::vector<WebKit::WebFileSystemEntry> web_entries_vector;
- for (std::vector<base::file_util_proxy::Entry>::const_iterator it =
- entries.begin(); it != entries.end(); ++it) {
- WebKit::WebFileSystemEntry entry;
- entry.name = webkit_glue::FilePathStringToWebString(it->name);
- entry.isDirectory = it->is_directory;
- web_entries_vector.push_back(entry);
- }
- WebKit::WebVector<WebKit::WebFileSystemEntry> web_entries =
- web_entries_vector;
- callbacks->didReadDirectory(web_entries, false);
- RemoveOperation(operation);
-}
-
-TestShellFileSystemOperation* SimpleFileSystem::GetNewOperation(
+fileapi::FileSystemOperation* SimpleFileSystem::GetNewOperation(
WebFileSystemCallbacks* callbacks) {
- scoped_ptr<TestShellFileSystemOperation> operation(
- new TestShellFileSystemOperation(
- this,
- base::MessageLoopProxy::CreateForCurrentThread(), callbacks));
- int32 request_id = operations_.Add(operation.get());
- operation->set_request_id(request_id);
- return operation.release();
+ // This pointer will be owned by |operation|.
+ TestShellFileSystemCallbackDispatcher* dispatcher =
+ new TestShellFileSystemCallbackDispatcher(this, callbacks);
+ fileapi::FileSystemOperation* operation = new fileapi::FileSystemOperation(
+ dispatcher, base::MessageLoopProxy::CreateForCurrentThread());
+ int32 request_id = operations_.Add(operation);
+ dispatcher->set_request_id(request_id);
+ return operation;
}
-void SimpleFileSystem::RemoveOperation(
- fileapi::FileSystemOperation* operation) {
- int request_id = static_cast<TestShellFileSystemOperation*>(
- operation)->request_id();
+void SimpleFileSystem::RemoveCompletedOperation(int request_id) {
operations_.Remove(request_id);
}
diff --git a/webkit/tools/test_shell/simple_file_system.h b/webkit/tools/test_shell/simple_file_system.h
index 947f804..db13d9c 100644
--- a/webkit/tools/test_shell/simple_file_system.h
+++ b/webkit/tools/test_shell/simple_file_system.h
@@ -8,84 +8,48 @@
#include <vector>
#include "base/file_util_proxy.h"
#include "base/id_map.h"
-#include "base/message_loop_proxy.h"
-#include "base/platform_file.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemCallbacks.h"
#include "webkit/fileapi/file_system_operation.h"
-#include "webkit/fileapi/file_system_operation_client.h"
-class TestShellFileSystemOperation : public fileapi::FileSystemOperation {
- public:
- TestShellFileSystemOperation(
- fileapi::FileSystemOperationClient* client,
- scoped_refptr<base::MessageLoopProxy> proxy,
- WebKit::WebFileSystemCallbacks* callbacks);
-
- WebKit::WebFileSystemCallbacks* callbacks() { return callbacks_; }
-
- void set_request_id(int request_id) { request_id_ = request_id; }
- int request_id() { return request_id_; }
-
- private:
- // Not owned.
- WebKit::WebFileSystemCallbacks* callbacks_;
-
- // Just for IDMap of operations.
- int request_id_;
-
- DISALLOW_COPY_AND_ASSIGN(TestShellFileSystemOperation);
-};
-
-class SimpleFileSystem
- : public WebKit::WebFileSystem,
- public fileapi::FileSystemOperationClient {
+class SimpleFileSystem : public WebKit::WebFileSystem {
public:
SimpleFileSystem() {}
virtual ~SimpleFileSystem();
+ void RemoveCompletedOperation(int request_id);
+
// WebKit::WebFileSystem methods.
virtual void move(const WebKit::WebString& src_path,
- const WebKit::WebString& dest_path,
- WebKit::WebFileSystemCallbacks* callbacks);
+ const WebKit::WebString& dest_path,
+ WebKit::WebFileSystemCallbacks* callbacks);
virtual void copy(const WebKit::WebString& src_path,
- const WebKit::WebString& dest_path,
- WebKit::WebFileSystemCallbacks* callbacks);
+ const WebKit::WebString& dest_path,
+ WebKit::WebFileSystemCallbacks* callbacks);
virtual void remove(const WebKit::WebString& path,
- WebKit::WebFileSystemCallbacks* callbacks);
+ WebKit::WebFileSystemCallbacks* callbacks);
virtual void readMetadata(const WebKit::WebString& path,
- WebKit::WebFileSystemCallbacks* callbacks);
- virtual void createFile(const WebKit::WebString& path, bool exclusive,
- WebKit::WebFileSystemCallbacks* callbacks);
- virtual void createDirectory(const WebKit::WebString& path, bool exclusive,
- WebKit::WebFileSystemCallbacks* callbacks);
+ WebKit::WebFileSystemCallbacks* callbacks);
+ virtual void createFile(const WebKit::WebString& path,
+ bool exclusive,
+ WebKit::WebFileSystemCallbacks* callbacks);
+ virtual void createDirectory(const WebKit::WebString& path,
+ bool exclusive,
+ WebKit::WebFileSystemCallbacks* callbacks);
virtual void fileExists(const WebKit::WebString& path,
- WebKit::WebFileSystemCallbacks* callbacks);
+ WebKit::WebFileSystemCallbacks* callbacks);
virtual void directoryExists(const WebKit::WebString& path,
- WebKit::WebFileSystemCallbacks* callbacks);
+ WebKit::WebFileSystemCallbacks* callbacks);
virtual void readDirectory(const WebKit::WebString& path,
- WebKit::WebFileSystemCallbacks* callbacks);
-
- // FileSystemOperationClient methods.
- virtual void DidFail(WebKit::WebFileError status,
- fileapi::FileSystemOperation* operation);
- virtual void DidSucceed(fileapi::FileSystemOperation* operation);
- virtual void DidReadMetadata(
- const base::PlatformFileInfo& info,
- fileapi::FileSystemOperation* operation);
- virtual void DidReadDirectory(
- const std::vector<base::file_util_proxy::Entry>& entries,
- bool has_more, fileapi::FileSystemOperation* operation);
+ WebKit::WebFileSystemCallbacks* callbacks);
private:
// Helpers.
- TestShellFileSystemOperation* GetNewOperation(
+ fileapi::FileSystemOperation* GetNewOperation(
WebKit::WebFileSystemCallbacks* callbacks);
- void RemoveOperation(fileapi::FileSystemOperation* operation);
-
// Keeps ongoing file system operations.
- typedef IDMap<TestShellFileSystemOperation, IDMapOwnPointer> OperationsMap;
+ typedef IDMap<fileapi::FileSystemOperation, IDMapOwnPointer> OperationsMap;
OperationsMap operations_;
DISALLOW_COPY_AND_ASSIGN(SimpleFileSystem);
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 490c134..3f23600 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -374,6 +374,7 @@
'../../database/database_tracker_unittest.cc',
'../../database/database_util_unittest.cc',
'../../database/quota_table_unittest.cc',
+ '../../fileapi/file_system_operation_unittest.cc',
'../../glue/bookmarklet_unittest.cc',
'../../glue/context_menu_unittest.cc',
'../../glue/cpp_bound_class_unittest.cc',