diff options
author | mtomasz@chromium.org <mtomasz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-13 07:12:41 +0000 |
---|---|---|
committer | mtomasz@chromium.org <mtomasz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-13 07:12:41 +0000 |
commit | 470a87031af80b04b0f5346f279cc192d3b47b25 (patch) | |
tree | 3b35bcfa86ba8b5b2eb545b73e6813140b3b6a78 | |
parent | d7f0449688f7bb010ba147eb8b4029654ba3a89b (diff) | |
download | chromium_src-470a87031af80b04b0f5346f279cc192d3b47b25.zip chromium_src-470a87031af80b04b0f5346f279cc192d3b47b25.tar.gz chromium_src-470a87031af80b04b0f5346f279cc192d3b47b25.tar.bz2 |
[fsp] Add support for opening files.
This patch adds support to opening a file. It is currently no-op, and it is
not yet bound to fileapi.
In order to bound it to fileapi::AsyncFileUtil, we need to implement closing
operation, and reading operations first. Otherwise, creating a snapshot
(required by fileapi::AsyncFileUtil) is not possible.
TEST=unit_tests: *FileSystemProvider*OpenFile*
BUG=248427
Review URL: https://codereview.chromium.org/284443002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270040 0039d316-1c4b-4281-b951-d872f2087c98
15 files changed, 506 insertions, 7 deletions
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc index d080d52..67c0fa6 100644 --- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc +++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc @@ -149,4 +149,24 @@ FileSystemProviderInternalReadDirectoryRequestedErrorFunction::RunWhenValid() { return true; } +bool +FileSystemProviderInternalOpenFileRequestedSuccessFunction::RunWhenValid() { + using api::file_system_provider_internal::OpenFileRequestedSuccess::Params; + scoped_ptr<Params> params(Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + + FulfillRequest(scoped_ptr<RequestValue>(new RequestValue()), + false /* has_more */); + return true; +} + +bool FileSystemProviderInternalOpenFileRequestedErrorFunction::RunWhenValid() { + using api::file_system_provider_internal::OpenFileRequestedError::Params; + const scoped_ptr<Params> params(Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + + RejectRequest(ProviderErrorToFileError(params->error)); + return true; +} + } // namespace extensions diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h index 21102a6b..e1b2916 100644 --- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h +++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h @@ -102,6 +102,30 @@ class FileSystemProviderInternalReadDirectoryRequestedErrorFunction virtual bool RunWhenValid() OVERRIDE; }; +class FileSystemProviderInternalOpenFileRequestedSuccessFunction + : public FileSystemProviderInternalFunction { + public: + DECLARE_EXTENSION_FUNCTION( + "fileSystemProviderInternal.openFileRequestedSuccess", + FILESYSTEMPROVIDERINTERNAL_OPENFILEREQUESTEDSUCCESS) + + protected: + virtual ~FileSystemProviderInternalOpenFileRequestedSuccessFunction() {} + virtual bool RunWhenValid() OVERRIDE; +}; + +class FileSystemProviderInternalOpenFileRequestedErrorFunction + : public FileSystemProviderInternalFunction { + public: + DECLARE_EXTENSION_FUNCTION( + "fileSystemProviderInternal.openFileRequestedError", + FILESYSTEMPROVIDERINTERNAL_OPENFILEREQUESTEDERROR) + + protected: + virtual ~FileSystemProviderInternalOpenFileRequestedErrorFunction() {} + virtual bool RunWhenValid() OVERRIDE; +}; + } // namespace extensions #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_SYSTEM_PROVIDER_FILE_SYSTEM_PROVIDER_API_H_ diff --git a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc index f27aeb0..aab2a83 100644 --- a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc +++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc @@ -118,6 +118,20 @@ void FakeProvidedFileSystem::ReadDirectory( } } +void FakeProvidedFileSystem::OpenFile( + const base::FilePath& file_path, + OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback) { + if (file_path.AsUTF8Unsafe() != "/hello.txt" || + mode == OPEN_FILE_MODE_WRITE || create) { + callback.Run(base::File::FILE_ERROR_SECURITY); + return; + } + + callback.Run(base::File::FILE_OK); +} + const ProvidedFileSystemInfo& FakeProvidedFileSystem::GetFileSystemInfo() const { return file_system_info_; diff --git a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h index 47dcdcf..2721dd0 100644 --- a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h +++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h @@ -34,6 +34,11 @@ class FakeProvidedFileSystem : public ProvidedFileSystemInterface { virtual void ReadDirectory( const base::FilePath& directory_path, const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) OVERRIDE; + virtual void OpenFile( + const base::FilePath& file_path, + OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback) OVERRIDE; virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const OVERRIDE; virtual RequestManager* GetRequestManager() OVERRIDE; diff --git a/chrome/browser/chromeos/file_system_provider/operations/open_file.cc b/chrome/browser/chromeos/file_system_provider/operations/open_file.cc new file mode 100644 index 0000000..a1a6e16 --- /dev/null +++ b/chrome/browser/chromeos/file_system_provider/operations/open_file.cc @@ -0,0 +1,67 @@ +// Copyright 2014 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/chromeos/file_system_provider/operations/open_file.h" + +#include <string> + +#include "chrome/common/extensions/api/file_system_provider.h" +#include "chrome/common/extensions/api/file_system_provider_internal.h" + +namespace chromeos { +namespace file_system_provider { +namespace operations { + +OpenFile::OpenFile(extensions::EventRouter* event_router, + const ProvidedFileSystemInfo& file_system_info, + const base::FilePath& file_path, + ProvidedFileSystemInterface::OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback) + : Operation(event_router, file_system_info), + file_path_(file_path), + mode_(mode), + create_(create), + callback_(callback) { +} + +OpenFile::~OpenFile() { +} + +bool OpenFile::Execute(int request_id) { + scoped_ptr<base::ListValue> values(new base::ListValue); + values->AppendString(file_path_.AsUTF8Unsafe()); + + switch (mode_) { + case ProvidedFileSystemInterface::OPEN_FILE_MODE_READ: + values->AppendString(extensions::api::file_system_provider::ToString( + extensions::api::file_system_provider::OPEN_FILE_MODE_READ)); + break; + case ProvidedFileSystemInterface::OPEN_FILE_MODE_WRITE: + values->AppendString(extensions::api::file_system_provider::ToString( + extensions::api::file_system_provider::OPEN_FILE_MODE_WRITE)); + break; + } + + values->AppendBoolean(create_); + + return SendEvent( + request_id, + extensions::api::file_system_provider::OnOpenFileRequested::kEventName, + values.Pass()); +} + +void OpenFile::OnSuccess(int /* request_id */, + scoped_ptr<RequestValue> result, + bool has_next) { + callback_.Run(base::File::FILE_OK); +} + +void OpenFile::OnError(int /* request_id */, base::File::Error error) { + callback_.Run(error); +} + +} // namespace operations +} // namespace file_system_provider +} // namespace chromeos diff --git a/chrome/browser/chromeos/file_system_provider/operations/open_file.h b/chrome/browser/chromeos/file_system_provider/operations/open_file.h new file mode 100644 index 0000000..efe0a53 --- /dev/null +++ b/chrome/browser/chromeos/file_system_provider/operations/open_file.h @@ -0,0 +1,61 @@ +// Copyright 2014 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_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_OPEN_FILE_H_ +#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_OPEN_FILE_H_ + +#include "base/files/file.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/file_system_provider/operations/operation.h" +#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h" +#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h" +#include "chrome/browser/chromeos/file_system_provider/request_value.h" +#include "webkit/browser/fileapi/async_file_util.h" + +namespace base { +class FilePath; +} // namespace base + +namespace extensions { +class EventRouter; +} // namespace extensions + +namespace chromeos { +namespace file_system_provider { +namespace operations { + +// Opens a file for either read or write, with optionally creating the file +// first. Note, that this is part of fileapi::CreateOrOpen file, but it does +// not download the file locally. Created per request. +class OpenFile : public Operation { + public: + OpenFile(extensions::EventRouter* event_router, + const ProvidedFileSystemInfo& file_system_info, + const base::FilePath& file_path, + ProvidedFileSystemInterface::OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback); + virtual ~OpenFile(); + + // Operation overrides. + virtual bool Execute(int request_id) OVERRIDE; + virtual void OnSuccess(int request_id, + scoped_ptr<RequestValue> result, + bool has_next) OVERRIDE; + virtual void OnError(int request_id, base::File::Error error) OVERRIDE; + + private: + base::FilePath file_path_; + ProvidedFileSystemInterface::OpenFileMode mode_; + bool create_; + const fileapi::AsyncFileUtil::StatusCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(OpenFile); +}; + +} // namespace operations +} // namespace file_system_provider +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_OPEN_FILE_H_ diff --git a/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc new file mode 100644 index 0000000..02fff32 --- /dev/null +++ b/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc @@ -0,0 +1,215 @@ +// Copyright 2014 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 <string> +#include <vector> + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "chrome/browser/chromeos/file_system_provider/operations/open_file.h" +#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h" +#include "chrome/common/extensions/api/file_system_provider.h" +#include "chrome/common/extensions/api/file_system_provider_internal.h" +#include "extensions/browser/event_router.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/browser/fileapi/async_file_util.h" + +namespace chromeos { +namespace file_system_provider { +namespace operations { +namespace { + +const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj"; +const int kFileSystemId = 1; +const int kRequestId = 2; +const base::FilePath::CharType kFilePath[] = "/directory/blueberries.txt"; + +// Fake event dispatcher implementation with extra logging capability. Acts as +// a providing extension end-point. +class LoggingDispatchEventImpl { + public: + explicit LoggingDispatchEventImpl(bool dispatch_reply) + : dispatch_reply_(dispatch_reply) {} + virtual ~LoggingDispatchEventImpl() {} + + bool OnDispatchEventImpl(scoped_ptr<extensions::Event> event) { + events_.push_back(event->DeepCopy()); + return dispatch_reply_; + } + + ScopedVector<extensions::Event>& events() { return events_; } + + private: + ScopedVector<extensions::Event> events_; + bool dispatch_reply_; + + DISALLOW_COPY_AND_ASSIGN(LoggingDispatchEventImpl); +}; + +// Callback invocation logger. Acts as a fileapi end-point. +class CallbackLogger { + public: + CallbackLogger() : weak_ptr_factory_(this) {} + virtual ~CallbackLogger() {} + + void OnOpenFile(base::File::Error result) { events_.push_back(result); } + + std::vector<base::File::Error>& events() { return events_; } + + base::WeakPtr<CallbackLogger> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + std::vector<base::File::Error> events_; + base::WeakPtrFactory<CallbackLogger> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CallbackLogger); +}; + +} // namespace + +class FileSystemProviderOperationsOpenFileTest : public testing::Test { + protected: + FileSystemProviderOperationsOpenFileTest() {} + virtual ~FileSystemProviderOperationsOpenFileTest() {} + + virtual void SetUp() OVERRIDE { + file_system_info_ = + ProvidedFileSystemInfo(kExtensionId, + kFileSystemId, + "" /* file_system_name */, + base::FilePath() /* mount_path */); + } + + ProvidedFileSystemInfo file_system_info_; +}; + +TEST_F(FileSystemProviderOperationsOpenFileTest, Execute) { + LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + CallbackLogger callback_logger; + + OpenFile open_file( + NULL, + file_system_info_, + base::FilePath::FromUTF8Unsafe(kFilePath), + ProvidedFileSystemInterface::OPEN_FILE_MODE_READ, + false /* create */, + base::Bind(&CallbackLogger::OnOpenFile, callback_logger.GetWeakPtr())); + open_file.SetDispatchEventImplForTesting( + base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_TRUE(open_file.Execute(kRequestId)); + + ASSERT_EQ(1u, dispatcher.events().size()); + extensions::Event* event = dispatcher.events()[0]; + EXPECT_EQ( + extensions::api::file_system_provider::OnOpenFileRequested::kEventName, + event->event_name); + base::ListValue* event_args = event->event_args.get(); + ASSERT_EQ(5u, event_args->GetSize()); + + int event_file_system_id = -1; + EXPECT_TRUE(event_args->GetInteger(0, &event_file_system_id)); + EXPECT_EQ(kFileSystemId, event_file_system_id); + + int event_request_id = -1; + EXPECT_TRUE(event_args->GetInteger(1, &event_request_id)); + EXPECT_EQ(kRequestId, event_request_id); + + std::string event_file_path; + EXPECT_TRUE(event_args->GetString(2, &event_file_path)); + EXPECT_EQ(kFilePath, event_file_path); + + std::string event_file_open_mode; + EXPECT_TRUE(event_args->GetString(3, &event_file_open_mode)); + const std::string expected_file_open_mode = + extensions::api::file_system_provider::ToString( + extensions::api::file_system_provider::OPEN_FILE_MODE_READ); + EXPECT_EQ(expected_file_open_mode, event_file_open_mode); + + bool event_create; + EXPECT_TRUE(event_args->GetBoolean(4, &event_create)); + EXPECT_FALSE(event_create); +} + +TEST_F(FileSystemProviderOperationsOpenFileTest, Execute_NoListener) { + LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */); + CallbackLogger callback_logger; + + OpenFile open_file( + NULL, + file_system_info_, + base::FilePath::FromUTF8Unsafe(kFilePath), + ProvidedFileSystemInterface::OPEN_FILE_MODE_READ, + false /* create */, + base::Bind(&CallbackLogger::OnOpenFile, callback_logger.GetWeakPtr())); + open_file.SetDispatchEventImplForTesting( + base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(open_file.Execute(kRequestId)); +} + +TEST_F(FileSystemProviderOperationsOpenFileTest, OnSuccess) { + using extensions::api::file_system_provider::EntryMetadata; + using extensions::api::file_system_provider_internal:: + OpenFileRequestedSuccess::Params; + + LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + CallbackLogger callback_logger; + + OpenFile open_file( + NULL, + file_system_info_, + base::FilePath::FromUTF8Unsafe(kFilePath), + ProvidedFileSystemInterface::OPEN_FILE_MODE_READ, + false /* create */, + base::Bind(&CallbackLogger::OnOpenFile, callback_logger.GetWeakPtr())); + open_file.SetDispatchEventImplForTesting( + base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_TRUE(open_file.Execute(kRequestId)); + + open_file.OnSuccess(kRequestId, + scoped_ptr<RequestValue>(new RequestValue()), + false /* has_next */); + ASSERT_EQ(1u, callback_logger.events().size()); + EXPECT_EQ(base::File::FILE_OK, callback_logger.events()[0]); +} + +TEST_F(FileSystemProviderOperationsOpenFileTest, OnError) { + using extensions::api::file_system_provider::EntryMetadata; + using extensions::api::file_system_provider_internal::OpenFileRequestedError:: + Params; + + LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + CallbackLogger callback_logger; + + OpenFile open_file( + NULL, + file_system_info_, + base::FilePath::FromUTF8Unsafe(kFilePath), + ProvidedFileSystemInterface::OPEN_FILE_MODE_READ, + false /* create */, + base::Bind(&CallbackLogger::OnOpenFile, callback_logger.GetWeakPtr())); + open_file.SetDispatchEventImplForTesting( + base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_TRUE(open_file.Execute(kRequestId)); + + open_file.OnError(kRequestId, base::File::FILE_ERROR_TOO_MANY_OPENED); + ASSERT_EQ(1u, callback_logger.events().size()); + EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, + callback_logger.events()[0]); +} + +} // namespace operations +} // namespace file_system_provider +} // namespace chromeos diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc index 7b372f4..72bdac4 100644 --- a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc +++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc @@ -6,6 +6,7 @@ #include "base/files/file.h" #include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h" +#include "chrome/browser/chromeos/file_system_provider/operations/open_file.h" #include "chrome/browser/chromeos/file_system_provider/operations/read_directory.h" #include "chrome/browser/chromeos/file_system_provider/operations/unmount.h" #include "chrome/browser/chromeos/file_system_provider/request_manager.h" @@ -29,9 +30,8 @@ ProvidedFileSystem::~ProvidedFileSystem() {} void ProvidedFileSystem::RequestUnmount( const fileapi::AsyncFileUtil::StatusCallback& callback) { if (!request_manager_.CreateRequest( - make_scoped_ptr<RequestManager::HandlerInterface>( - new operations::Unmount( - event_router_, file_system_info_, callback)))) { + scoped_ptr<RequestManager::HandlerInterface>(new operations::Unmount( + event_router_, file_system_info_, callback)))) { callback.Run(base::File::FILE_ERROR_SECURITY); } } @@ -40,7 +40,7 @@ void ProvidedFileSystem::GetMetadata( const base::FilePath& entry_path, const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) { if (!request_manager_.CreateRequest( - make_scoped_ptr<RequestManager::HandlerInterface>( + scoped_ptr<RequestManager::HandlerInterface>( new operations::GetMetadata( event_router_, file_system_info_, entry_path, callback)))) { callback.Run(base::File::FILE_ERROR_SECURITY, base::File::Info()); @@ -50,7 +50,7 @@ void ProvidedFileSystem::GetMetadata( void ProvidedFileSystem::ReadDirectory( const base::FilePath& directory_path, const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) { - if (!request_manager_.CreateRequest(make_scoped_ptr< + if (!request_manager_.CreateRequest(scoped_ptr< RequestManager::HandlerInterface>(new operations::ReadDirectory( event_router_, file_system_info_, directory_path, callback)))) { callback.Run(base::File::FILE_ERROR_SECURITY, @@ -59,6 +59,30 @@ void ProvidedFileSystem::ReadDirectory( } } +void ProvidedFileSystem::OpenFile( + const base::FilePath& file_path, + OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback) { + // Writing is not supported. Note, that this includes a situation, when a file + // exists, but |create| is set to true. + if (mode == OPEN_FILE_MODE_WRITE || create) { + callback.Run(base::File::FILE_ERROR_SECURITY); + return; + } + + if (!request_manager_.CreateRequest( + scoped_ptr<RequestManager::HandlerInterface>( + new operations::OpenFile(event_router_, + file_system_info_, + file_path, + mode, + create, + callback)))) { + callback.Run(base::File::FILE_ERROR_SECURITY); + } +} + const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { return file_system_info_; } diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system.h b/chrome/browser/chromeos/file_system_provider/provided_file_system.h index 6fffe4b..4ecc8cb 100644 --- a/chrome/browser/chromeos/file_system_provider/provided_file_system.h +++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.h @@ -38,6 +38,11 @@ class ProvidedFileSystem : public ProvidedFileSystemInterface { virtual void ReadDirectory( const base::FilePath& directory_path, const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) OVERRIDE; + virtual void OpenFile( + const base::FilePath& file_path, + OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback) OVERRIDE; virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const OVERRIDE; virtual RequestManager* GetRequestManager() OVERRIDE; diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h index 76be11d..126d532 100644 --- a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h +++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h @@ -24,6 +24,9 @@ class RequestManager; // TODO(mtomasz): Add more methods once implemented. class ProvidedFileSystemInterface { public: + // Mode of opening a file. Used by OpenFile(). + enum OpenFileMode { OPEN_FILE_MODE_READ, OPEN_FILE_MODE_WRITE }; + virtual ~ProvidedFileSystemInterface() {} // Requests unmounting of the file system. The callback is called when the @@ -43,6 +46,14 @@ class ProvidedFileSystemInterface { const base::FilePath& directory_path, const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) = 0; + // Requests opening a file at |file_path|. If |create| is set to true, it will + // create a file and return succes in case it didn't exist. + virtual void OpenFile( + const base::FilePath& file_path, + OpenFileMode mode, + bool create, + const fileapi::AsyncFileUtil::StatusCallback& callback) = 0; + // Returns a provided file system info for this file system. virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const = 0; diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index cd5c9f0..37097b3 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -382,6 +382,8 @@ 'browser/chromeos/file_system_provider/observer.h', 'browser/chromeos/file_system_provider/operations/get_metadata.cc', 'browser/chromeos/file_system_provider/operations/get_metadata.h', + 'browser/chromeos/file_system_provider/operations/open_file.cc', + 'browser/chromeos/file_system_provider/operations/open_file.h', 'browser/chromeos/file_system_provider/operations/operation.cc', 'browser/chromeos/file_system_provider/operations/operation.h', 'browser/chromeos/file_system_provider/operations/read_directory.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 6f8ace2..d19d1c3 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -711,6 +711,7 @@ 'browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc', 'browser/chromeos/file_system_provider/mount_path_util_unittest.cc', 'browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc', + 'browser/chromeos/file_system_provider/operations/open_file_unittest.cc', 'browser/chromeos/file_system_provider/operations/read_directory_unittest.cc', 'browser/chromeos/file_system_provider/provided_file_system_unittest.cc', 'browser/chromeos/file_system_provider/request_manager_unittest.cc', diff --git a/chrome/common/extensions/api/file_system_provider.idl b/chrome/common/extensions/api/file_system_provider.idl index f8ed6ba..8942bda 100644 --- a/chrome/common/extensions/api/file_system_provider.idl +++ b/chrome/common/extensions/api/file_system_provider.idl @@ -29,6 +29,12 @@ namespace fileSystemProvider { IO }; + // Mode of opening a file. Used by <code>onOpenFileRequested</code>. + enum OpenFileMode { + READ, + WRITE + }; + // Represents metadata of a file or a directory. dictionary EntryMetadata { // True if it is a directory. @@ -116,7 +122,7 @@ namespace fileSystemProvider { long fileSystemId, DOMString entryPath, MetadataCallback successCallback, - ErrorCallback errorCallback); + ProviderErrorCallback errorCallback); // Raised when contents of a directory at <code>directoryPath</code> are // requested. The results should be returned in chunks by calling the <code> @@ -126,7 +132,18 @@ namespace fileSystemProvider { long fileSystemId, DOMString directoryPath, EntriesCallback successCallback, - ErrorCallback errorCallback); + ProviderErrorCallback errorCallback); + + // Raised when opening a file at <code>filePath</code> is requested. + // If <code>create</code> is set to <code>true</code> and the file does not + // exist, then it should be created. + [maxListeners=1] static void onOpenFileRequested( + long fileSystemId, + DOMString filePath, + OpenFileMode mode, + boolean create, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); }; }; diff --git a/chrome/common/extensions/api/file_system_provider_internal.idl b/chrome/common/extensions/api/file_system_provider_internal.idl index 7a80d5b..294d09a 100644 --- a/chrome/common/extensions/api/file_system_provider_internal.idl +++ b/chrome/common/extensions/api/file_system_provider_internal.idl @@ -48,6 +48,19 @@ namespace fileSystemProviderInternal { long fileSystemId, long requestId, fileSystemProvider.ProviderError error); + + // Internal. Success callback of the <code>onOpenFileRequested</code> event. + // Must be called, when opening succeeds. + static void openFileRequestedSuccess( + long fileSystemId, + long requestId); + + // Internal. Error callback of the <code>onOpenFileRequested</code> event. + // Must be called when opening fails. + static void openFileRequestedError( + long fileSystemId, + long requestId, + fileSystemProvider.ProviderError error); }; }; diff --git a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js index f59900c..9ea4a01 100644 --- a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js @@ -161,4 +161,24 @@ eventBindings.registerArgumentMassager( fileSystemId, directoryPath, onSuccessCallback, onErrorCallback]); }); +eventBindings.registerArgumentMassager( + 'fileSystemProvider.onOpenFileRequested', + function(args, dispatch) { + var fileSystemId = args[0]; + var requestId = args[1]; + var filePath = args[2]; + var mode = args[3]; + var create = args[4]; + var onSuccessCallback = function() { + fileSystemProviderInternal.openFileRequestedSuccess( + fileSystemId, requestId); + }; + var onErrorCallback = function(error) { + fileSystemProviderInternal.openFileRequestedError( + fileSystemId, requestId, error); + } + dispatch([fileSystemId, filePath, mode, create, onSuccessCallback, + onErrorCallback]); + }); + exports.binding = binding.generate(); |