diff options
author | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-22 03:29:14 +0000 |
---|---|---|
committer | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-22 03:29:14 +0000 |
commit | 5746640f419fe2b493ed4e97aa473e96f73c8d73 (patch) | |
tree | 63b222962eb9c5ea5d230d8add24fe72e6281386 /webkit | |
parent | ae236193f7b64659caf81ba2a009f8ff4e947693 (diff) | |
download | chromium_src-5746640f419fe2b493ed4e97aa473e96f73c8d73.zip chromium_src-5746640f419fe2b493ed4e97aa473e96f73c8d73.tar.gz chromium_src-5746640f419fe2b493ed4e97aa473e96f73c8d73.tar.bz2 |
Refactor some file_system classes to use chromium types instead of
WebKit API types.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/3406008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60152 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/fileapi/file_system_callback_dispatcher.h | 49 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation.cc | 111 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation.h | 18 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation_client.h | 39 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation_unittest.cc | 555 | ||||
-rw-r--r-- | webkit/fileapi/webkit_fileapi.gypi | 2 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_file_system.cc | 161 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_file_system.h | 76 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.gypi | 1 |
9 files changed, 790 insertions, 222 deletions
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', |