summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormtomasz@chromium.org <mtomasz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-16 04:03:32 +0000
committermtomasz@chromium.org <mtomasz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-16 04:03:32 +0000
commit41259a71b1949ba38333ed04b1f7f059b1276990 (patch)
tree88ae36695bea0453239c9f12a6ab8b5114a7f3c5
parent06363a70f8cb59f5e1902d31312396d37de09c16 (diff)
downloadchromium_src-41259a71b1949ba38333ed04b1f7f059b1276990.zip
chromium_src-41259a71b1949ba38333ed04b1f7f059b1276990.tar.gz
chromium_src-41259a71b1949ba38333ed04b1f7f059b1276990.tar.bz2
[fsp] Decouple file_service_provider::Service.
This patch splits Service into thinner Service and ProvidedFileSystem. Also now, provided file system information instances are renamed to ProvidedFileSystemInfo. Such separation makes it easy to test provided file systems independently, from the service. Also, after the introduced interface will allow to create a FakeProvidedFileSystem, which will be used to test upcoming AsyncFileUtil without need of using an extension. TEST=New unit_tests:*FileSystemProviderProvidedFileSystemTest* and previous: *FileSystemProvider* (unit_tests + browser_tests). BUG=248427 R=hashimoto@chromium.org Review URL: https://codereview.chromium.org/210803003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@264106 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc25
-rw-r--r--chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h8
-rw-r--r--chrome/browser/chromeos/file_manager/volume_manager.cc33
-rw-r--r--chrome/browser/chromeos/file_manager/volume_manager.h6
-rw-r--r--chrome/browser/chromeos/file_manager/volume_manager_unittest.cc15
-rw-r--r--chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc45
-rw-r--r--chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h50
-rw-r--r--chrome/browser/chromeos/file_system_provider/mount_path_util.cc40
-rw-r--r--chrome/browser/chromeos/file_system_provider/mount_path_util.h29
-rw-r--r--chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc48
-rw-r--r--chrome/browser/chromeos/file_system_provider/observer.h9
-rw-r--r--chrome/browser/chromeos/file_system_provider/provided_file_system.cc70
-rw-r--r--chrome/browser/chromeos/file_system_provider/provided_file_system.h47
-rw-r--r--chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc25
-rw-r--r--chrome/browser/chromeos/file_system_provider/provided_file_system_info.h48
-rw-r--r--chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h38
-rw-r--r--chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc183
-rw-r--r--chrome/browser/chromeos/file_system_provider/request_manager.cc38
-rw-r--r--chrome/browser/chromeos/file_system_provider/request_manager.h30
-rw-r--r--chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc90
-rw-r--r--chrome/browser/chromeos/file_system_provider/service.cc218
-rw-r--r--chrome/browser/chromeos/file_system_provider/service.h73
-rw-r--r--chrome/browser/chromeos/file_system_provider/service_unittest.cc94
-rw-r--r--chrome/chrome_browser_chromeos.gypi5
-rw-r--r--chrome/chrome_tests_unit.gypi10
25 files changed, 931 insertions, 346 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 471f7c3..e9654d2 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
@@ -119,7 +119,6 @@ bool FileSystemProviderMountFunction::RunImpl() {
// Don't append an error on success.
SetResult(result);
- SendResponse(true);
return true;
}
@@ -142,7 +141,6 @@ bool FileSystemProviderUnmountFunction::RunImpl() {
base::ListValue* result = new base::ListValue();
SetResult(result);
- SendResponse(true);
return true;
}
@@ -155,11 +153,12 @@ bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunImpl() {
chromeos::file_system_provider::Service::Get(GetProfile());
DCHECK(service);
- if (!service->FulfillRequest(extension_id(),
- params->file_system_id,
- params->request_id,
- scoped_ptr<base::DictionaryValue>(),
- false /* has_more */)) {
+ if (!service->request_manager()->FulfillRequest(
+ extension_id(),
+ params->file_system_id,
+ params->request_id,
+ scoped_ptr<base::DictionaryValue>(),
+ false /* has_more */)) {
// TODO(mtomasz): Pass more detailed errors, rather than just a bool.
base::ListValue* result = new base::ListValue();
result->Append(
@@ -170,7 +169,6 @@ bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunImpl() {
base::ListValue* result = new base::ListValue();
SetResult(result);
- SendResponse(true);
return true;
}
@@ -183,11 +181,11 @@ bool FileSystemProviderInternalUnmountRequestedErrorFunction::RunImpl() {
chromeos::file_system_provider::Service::Get(GetProfile());
DCHECK(service);
- if (!service->RejectRequest(extension_id(),
- params->file_system_id,
- params->request_id,
- ProviderErrorToFileError(params->error))) {
- // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
+ if (!service->request_manager()->RejectRequest(
+ extension_id(),
+ params->file_system_id,
+ params->request_id,
+ ProviderErrorToFileError(params->error))) {
base::ListValue* result = new base::ListValue();
result->Append(
CreateError(kSecurityErrorName, kResponseFailedErrorMessage));
@@ -197,7 +195,6 @@ bool FileSystemProviderInternalUnmountRequestedErrorFunction::RunImpl() {
base::ListValue* result = new base::ListValue();
SetResult(result);
- SendResponse(true);
return true;
}
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 48b32bd..e6ed33b 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
@@ -10,7 +10,7 @@
namespace extensions {
-class FileSystemProviderMountFunction : public ChromeAsyncExtensionFunction {
+class FileSystemProviderMountFunction : public ChromeSyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("fileSystemProvider.mount",
FILESYSTEMPROVIDER_MOUNT)
@@ -20,7 +20,7 @@ class FileSystemProviderMountFunction : public ChromeAsyncExtensionFunction {
virtual bool RunImpl() OVERRIDE;
};
-class FileSystemProviderUnmountFunction : public ChromeAsyncExtensionFunction {
+class FileSystemProviderUnmountFunction : public ChromeSyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("fileSystemProvider.unmount",
FILESYSTEMPROVIDER_UNMOUNT)
@@ -31,7 +31,7 @@ class FileSystemProviderUnmountFunction : public ChromeAsyncExtensionFunction {
};
class FileSystemProviderInternalUnmountRequestedSuccessFunction
- : public ChromeAsyncExtensionFunction {
+ : public ChromeSyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION(
"fileSystemProviderInternal.unmountRequestedSuccess",
@@ -43,7 +43,7 @@ class FileSystemProviderInternalUnmountRequestedSuccessFunction
};
class FileSystemProviderInternalUnmountRequestedErrorFunction
- : public ChromeAsyncExtensionFunction {
+ : public ChromeSyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("fileSystemProviderInternal.unmountRequestedError",
FILESYSTEMPROVIDERINTERNAL_UNMOUNTREQUESTEDERROR)
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.cc b/chrome/browser/chromeos/file_manager/volume_manager.cc
index a8a4f33..755cfdf 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager.cc
+++ b/chrome/browser/chromeos/file_manager/volume_manager.cc
@@ -20,7 +20,7 @@
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/file_manager/volume_manager_factory.h"
#include "chrome/browser/chromeos/file_manager/volume_manager_observer.h"
-#include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/local_discovery/storage/privet_filesystem_constants.h"
#include "chrome/browser/profiles/profile.h"
@@ -96,12 +96,12 @@ std::string VolumeTypeToString(VolumeType type) {
return "archive";
case VOLUME_TYPE_CLOUD_DEVICE:
return "cloud_device";
- case VOLUME_TYPE_TESTING:
- return "testing";
case VOLUME_TYPE_PROVIDED:
return "provided";
case VOLUME_TYPE_MTP:
return "mtp";
+ case VOLUME_TYPE_TESTING:
+ return "testing";
}
NOTREACHED();
return "";
@@ -199,15 +199,16 @@ VolumeInfo CreatePrivetVolumeInfo(
}
VolumeInfo CreateProvidedFileSystemVolumeInfo(
- const chromeos::file_system_provider::ProvidedFileSystem& file_system) {
+ const chromeos::file_system_provider::ProvidedFileSystemInfo&
+ file_system_info) {
VolumeInfo volume_info;
volume_info.type = VOLUME_TYPE_PROVIDED;
- volume_info.mount_path = file_system.mount_path();
+ volume_info.mount_path = file_system_info.mount_path();
volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
volume_info.is_parent = true;
volume_info.is_read_only = true;
volume_info.volume_id = GenerateVolumeId(volume_info);
- volume_info.file_system_id = file_system.file_system_id();
+ volume_info.file_system_id = file_system_info.file_system_id();
return volume_info;
}
@@ -293,14 +294,14 @@ void VolumeManager::Initialize() {
// Subscribe to FileSystemProviderService and register currently mounted
// volumes for the profile.
if (file_system_provider_service_) {
- using chromeos::file_system_provider::ProvidedFileSystem;
+ using chromeos::file_system_provider::ProvidedFileSystemInfo;
file_system_provider_service_->AddObserver(this);
- std::vector<ProvidedFileSystem> provided_file_systems =
- file_system_provider_service_->GetMountedFileSystems();
- for (size_t i = 0; i < provided_file_systems.size(); ++i) {
+ std::vector<ProvidedFileSystemInfo> file_system_info_list =
+ file_system_provider_service_->GetProvidedFileSystemInfoList();
+ for (size_t i = 0; i < file_system_info_list.size(); ++i) {
VolumeInfo volume_info =
- CreateProvidedFileSystemVolumeInfo(provided_file_systems[i]);
+ CreateProvidedFileSystemVolumeInfo(file_system_info_list[i]);
DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, kNotRemounting);
}
}
@@ -621,9 +622,10 @@ void VolumeManager::OnFormatEvent(
}
void VolumeManager::OnProvidedFileSystemMount(
- const chromeos::file_system_provider::ProvidedFileSystem& file_system,
+ const chromeos::file_system_provider::ProvidedFileSystemInfo&
+ file_system_info,
base::File::Error error) {
- VolumeInfo volume_info = CreateProvidedFileSystemVolumeInfo(file_system);
+ VolumeInfo volume_info = CreateProvidedFileSystemVolumeInfo(file_system_info);
// TODO(mtomasz): Introduce own type, and avoid using MountError internally,
// since it is related to cros disks only.
const chromeos::MountError mount_error = error == base::File::FILE_OK
@@ -633,14 +635,15 @@ void VolumeManager::OnProvidedFileSystemMount(
}
void VolumeManager::OnProvidedFileSystemUnmount(
- const chromeos::file_system_provider::ProvidedFileSystem& file_system,
+ const chromeos::file_system_provider::ProvidedFileSystemInfo&
+ file_system_info,
base::File::Error error) {
// TODO(mtomasz): Introduce own type, and avoid using MountError internally,
// since it is related to cros disks only.
const chromeos::MountError mount_error = error == base::File::FILE_OK
? chromeos::MOUNT_ERROR_NONE
: chromeos::MOUNT_ERROR_UNKNOWN;
- VolumeInfo volume_info = CreateProvidedFileSystemVolumeInfo(file_system);
+ VolumeInfo volume_info = CreateProvidedFileSystemVolumeInfo(file_system_info);
DoUnmountEvent(mount_error, volume_info);
}
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.h b/chrome/browser/chromeos/file_manager/volume_manager.h
index bd3b11e..6c11ee1 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager.h
+++ b/chrome/browser/chromeos/file_manager/volume_manager.h
@@ -176,10 +176,12 @@ class VolumeManager : public KeyedService,
// chromeos::file_system_provider::Observer overrides.
virtual void OnProvidedFileSystemMount(
- const chromeos::file_system_provider::ProvidedFileSystem& file_system,
+ const chromeos::file_system_provider::ProvidedFileSystemInfo&
+ file_system_info,
base::File::Error error) OVERRIDE;
virtual void OnProvidedFileSystemUnmount(
- const chromeos::file_system_provider::ProvidedFileSystem& file_system,
+ const chromeos::file_system_provider::ProvidedFileSystemInfo&
+ file_system_info,
base::File::Error error) OVERRIDE;
// Called on change to kExternalStorageDisabled pref.
diff --git a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
index 828befa..dadc906 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
@@ -11,6 +11,7 @@
#include "base/prefs/pref_service.h"
#include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h"
#include "chrome/browser/chromeos/file_manager/volume_manager_observer.h"
+#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
#include "chrome/browser/chromeos/file_system_provider/service.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
@@ -146,12 +147,14 @@ class VolumeManagerTest : public testing::Test {
: profile_(new TestingProfile),
file_system_provider_service_(
new chromeos::file_system_provider::Service(profile_.get())),
- volume_manager_(new VolumeManager(
- profile_.get(),
- NULL, // DriveIntegrationService
- power_manager_client,
- disk_manager,
- file_system_provider_service_.get())) {
+ volume_manager_(
+ new VolumeManager(profile_.get(),
+ NULL, // DriveIntegrationService
+ power_manager_client,
+ disk_manager,
+ file_system_provider_service_.get())) {
+ file_system_provider_service_->SetFileSystemFactoryForTests(base::Bind(
+ &chromeos::file_system_provider::FakeProvidedFileSystem::Create));
}
Profile* profile() const { return profile_.get(); }
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
new file mode 100644
index 0000000..3530236
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
@@ -0,0 +1,45 @@
+// 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/fake_provided_file_system.h"
+
+#include "base/files/file.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "chrome/browser/chromeos/file_system_provider/request_manager.h"
+#include "extensions/browser/event_router.h"
+
+namespace chromeos {
+namespace file_system_provider {
+
+FakeProvidedFileSystem::FakeProvidedFileSystem(
+ const ProvidedFileSystemInfo& file_system_info)
+ : file_system_info_(file_system_info) {}
+
+FakeProvidedFileSystem::~FakeProvidedFileSystem() {}
+
+bool FakeProvidedFileSystem::RequestUnmount(
+ const fileapi::AsyncFileUtil::StatusCallback& callback) {
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE, base::Bind(callback, base::File::FILE_OK));
+ return true;
+}
+
+const ProvidedFileSystemInfo& FakeProvidedFileSystem::GetFileSystemInfo()
+ const {
+ return file_system_info_;
+}
+
+ProvidedFileSystemInterface* FakeProvidedFileSystem::Create(
+ extensions::EventRouter* event_router,
+ RequestManager* request_manager,
+ const ProvidedFileSystemInfo& file_system_info) {
+ // TODO(mtomasz): Create a request manager in ProvidedFileSystem, since it is
+ // only used by ProvidedFileSystem, instead of having a profile wide one.
+ // As a result, there will be no need to pass the request manager to the
+ // factory callback.
+ return new FakeProvidedFileSystem(file_system_info);
+}
+
+} // namespace file_system_provider
+} // namespace chromeos
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
new file mode 100644
index 0000000..5f82922
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h
@@ -0,0 +1,50 @@
+// 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_FAKE_PROVIDED_FILE_SYSTEM_H_
+#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_FAKE_PROVIDED_FILE_SYSTEM_H_
+
+#include <string>
+
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
+
+namespace extensions {
+class EventRouter;
+} // namespace extensions
+
+namespace chromeos {
+namespace file_system_provider {
+
+class RequestManager;
+
+// Fake provided file system implementation. Does not communicate with target
+// extensions. Used for unit tests.
+class FakeProvidedFileSystem : public ProvidedFileSystemInterface {
+ public:
+ explicit FakeProvidedFileSystem(
+ const ProvidedFileSystemInfo& file_system_info);
+ virtual ~FakeProvidedFileSystem();
+
+ // ProvidedFileSystemInterface overrides.
+ virtual bool RequestUnmount(
+ const fileapi::AsyncFileUtil::StatusCallback& callback) OVERRIDE;
+ virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const OVERRIDE;
+
+ // Factory callback, to be used in Service::SetFileSystemFactory(). Both
+ // |event_router| and |request_manager| arguments can be NULL.
+ static ProvidedFileSystemInterface* Create(
+ extensions::EventRouter* event_router,
+ RequestManager* request_manager,
+ const ProvidedFileSystemInfo& file_system_info);
+
+ private:
+ ProvidedFileSystemInfo file_system_info_;
+ DISALLOW_COPY_AND_ASSIGN(FakeProvidedFileSystem);
+};
+
+} // namespace file_system_provider
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_FAKE_PROVIDED_FILE_SYSTEM_H_
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util.cc
new file mode 100644
index 0000000..c535bdb
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util.cc
@@ -0,0 +1,40 @@
+// 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/mount_path_util.h"
+
+#include "base/files/file_path.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chromeos/login/user.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+
+namespace chromeos {
+namespace file_system_provider {
+namespace util {
+
+namespace {
+
+// Root mount path for all of the provided file systems.
+const base::FilePath::CharType kProvidedMountPointRoot[] =
+ FILE_PATH_LITERAL("/provided");
+
+} // namespace
+
+base::FilePath GetMountPointPath(Profile* profile,
+ std::string extension_id,
+ int file_system_id) {
+ chromeos::User* const user =
+ chromeos::UserManager::IsInitialized()
+ ? chromeos::UserManager::Get()->GetUserByProfile(
+ profile->GetOriginalProfile())
+ : NULL;
+ const std::string user_suffix = user ? "-" + user->username_hash() : "";
+ return base::FilePath(kProvidedMountPointRoot).AppendASCII(
+ extension_id + "-" + base::IntToString(file_system_id) + user_suffix);
+}
+
+} // namespace util
+} // namespace file_system_provider
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util.h b/chrome/browser/chromeos/file_system_provider/mount_path_util.h
new file mode 100644
index 0000000..8591546
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util.h
@@ -0,0 +1,29 @@
+// 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_MOUNT_PATH_UTIL_H_
+#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_MOUNT_PATH_UTIL_H_
+
+#include <string>
+
+class Profile;
+
+namespace base {
+class FilePath;
+} // namespace base
+
+namespace chromeos {
+namespace file_system_provider {
+namespace util {
+
+// Constructs a safe mount point path for the provided file system.
+base::FilePath GetMountPointPath(Profile* profile,
+ std::string extension_id,
+ int file_system_id);
+
+} // namespace util
+} // namespace file_system_provider
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_MOUNT_PATH_UTIL_H_
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
new file mode 100644
index 0000000..2b24956
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
@@ -0,0 +1,48 @@
+// 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 "base/files/file.h"
+#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
+#include "chrome/browser/chromeos/login/fake_user_manager.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace file_system_provider {
+namespace util {
+
+class FileSystemProviderMountPathUtilTest : public testing::Test {
+ protected:
+ FileSystemProviderMountPathUtilTest() {}
+ virtual ~FileSystemProviderMountPathUtilTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ user_manager_ = new FakeUserManager();
+ user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_));
+ profile_.reset(new TestingProfile);
+ user_manager_->AddUser(profile_->GetProfileName());
+ }
+
+ content::TestBrowserThreadBundle thread_bundle_;
+ scoped_ptr<TestingProfile> profile_;
+ scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
+ FakeUserManager* user_manager_;
+};
+
+TEST_F(FileSystemProviderMountPathUtilTest, GetMountPointPath) {
+ const std::string kExtensionId = "mbflcebpggnecokmikipoihdbecnjfoj";
+ const int kFileSystemId = 1;
+
+ base::FilePath result =
+ GetMountPointPath(profile_.get(), kExtensionId, kFileSystemId);
+ EXPECT_EQ("/provided/mbflcebpggnecokmikipoihdbecnjfoj-1-testing_profile-hash",
+ result.AsUTF8Unsafe());
+}
+
+} // namespace util
+} // namespace file_system_provider
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/observer.h b/chrome/browser/chromeos/file_system_provider/observer.h
index be4dc66..3f6347b 100644
--- a/chrome/browser/chromeos/file_system_provider/observer.h
+++ b/chrome/browser/chromeos/file_system_provider/observer.h
@@ -12,7 +12,7 @@
namespace chromeos {
namespace file_system_provider {
-class ProvidedFileSystem;
+class ProvidedFileSystemInfo;
// Observes file_system_provider::Service for mounting and unmounting events.
class Observer {
@@ -20,14 +20,15 @@ class Observer {
// Called when a file system mounting has been invoked. For success, the
// |error| argument is set to FILE_OK. Otherwise, |error| contains a specific
// error code.
- virtual void OnProvidedFileSystemMount(const ProvidedFileSystem& file_system,
- base::File::Error error) = 0;
+ virtual void OnProvidedFileSystemMount(
+ const ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error) = 0;
// Called when a file system unmounting has been invoked. For success, the
// |error| argument is set to FILE_OK. Otherwise, |error| contains a specific
// error code.
virtual void OnProvidedFileSystemUnmount(
- const ProvidedFileSystem& file_system,
+ const ProvidedFileSystemInfo& file_system_info,
base::File::Error error) = 0;
};
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 8d669af..7185c0a 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
@@ -4,21 +4,73 @@
#include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
+#include "base/files/file.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/file_system_provider/request_manager.h"
+#include "chrome/common/extensions/api/file_system_provider.h"
+#include "extensions/browser/event_router.h"
+
namespace chromeos {
namespace file_system_provider {
+namespace {
+
+// Creates values to be passed to request events. These values can be extended
+// by additional fields.
+scoped_ptr<base::ListValue> CreateRequestValues(int file_system_id,
+ int request_id) {
+ scoped_ptr<base::ListValue> values(new base::ListValue());
+ values->AppendInteger(file_system_id);
+ values->AppendInteger(request_id);
+ return values.Pass();
+}
+
+// Forwards the success callback to the status callback. Ignores arguments,
+// since unmount request does not provide arguments.
+void OnRequestUnmountSuccess(
+ const fileapi::AsyncFileUtil::StatusCallback& callback,
+ scoped_ptr<base::DictionaryValue> /* result */,
+ bool /* has_next */) {
+ callback.Run(base::File::FILE_OK);
+}
-ProvidedFileSystem::ProvidedFileSystem() {}
+} // namespace
-ProvidedFileSystem::ProvidedFileSystem(const std::string& extension_id,
- int file_system_id,
- const std::string& file_system_name,
- const base::FilePath& mount_path)
- : extension_id_(extension_id),
- file_system_id_(file_system_id),
- file_system_name_(file_system_name),
- mount_path_(mount_path) {}
+ProvidedFileSystem::ProvidedFileSystem(
+ extensions::EventRouter* event_router,
+ RequestManager* request_manager,
+ const ProvidedFileSystemInfo& file_system_info)
+ : event_router_(event_router),
+ request_manager_(request_manager),
+ file_system_info_(file_system_info) {}
ProvidedFileSystem::~ProvidedFileSystem() {}
+bool ProvidedFileSystem::RequestUnmount(
+ const fileapi::AsyncFileUtil::StatusCallback& callback) {
+ int request_id = request_manager_->CreateRequest(
+ file_system_info_.extension_id(),
+ file_system_info_.file_system_id(),
+ base::Bind(&OnRequestUnmountSuccess, callback),
+ callback);
+
+ if (!request_id)
+ return false;
+
+ scoped_ptr<base::ListValue> values(
+ CreateRequestValues(file_system_info_.file_system_id(), request_id));
+
+ event_router_->DispatchEventToExtension(
+ file_system_info_.extension_id(),
+ make_scoped_ptr(new extensions::Event(
+ extensions::api::file_system_provider::OnUnmountRequested::kEventName,
+ values.Pass())));
+
+ return true;
+}
+
+const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const {
+ return file_system_info_;
+}
+
} // namespace file_system_provider
} // namespace chromeos
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 10aa0a9..45807a4 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system.h
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.h
@@ -5,41 +5,38 @@
#ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_H_
#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_H_
-#include <string>
+#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 "base/files/file_path.h"
+namespace extensions {
+class EventRouter;
+} // namespace extensions
namespace chromeos {
namespace file_system_provider {
-// Contains information about the provided file system instance.
-class ProvidedFileSystem {
- public:
- ProvidedFileSystem();
- ProvidedFileSystem(const std::string& extension_id,
- int file_system_id,
- const std::string& file_system_name,
- const base::FilePath& mount_path);
+class RequestManager;
- ~ProvidedFileSystem();
+// Provided file system implementation. Forwards requests between providers and
+// clients.
+class ProvidedFileSystem : public ProvidedFileSystemInterface {
+ public:
+ ProvidedFileSystem(extensions::EventRouter* event_router,
+ RequestManager* request_manager,
+ const ProvidedFileSystemInfo& file_system_info);
+ virtual ~ProvidedFileSystem();
- const std::string& extension_id() const { return extension_id_; }
- int file_system_id() const { return file_system_id_; }
- const std::string& file_system_name() const { return file_system_name_; }
- const base::FilePath& mount_path() const { return mount_path_; }
+ // ProvidedFileSystemInterface overrides.
+ virtual bool RequestUnmount(
+ const fileapi::AsyncFileUtil::StatusCallback& callback) OVERRIDE;
+ virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const OVERRIDE;
private:
- // ID of the extension providing this file system.
- std::string extension_id_;
-
- // ID of the file system, used internally.
- int file_system_id_;
-
- // Name of the file system, can be rendered in the UI.
- std::string file_system_name_;
+ extensions::EventRouter* event_router_;
+ RequestManager* request_manager_;
+ ProvidedFileSystemInfo file_system_info_;
- // Mount path of the underlying file system.
- base::FilePath mount_path_;
+ DISALLOW_COPY_AND_ASSIGN(ProvidedFileSystem);
};
} // namespace file_system_provider
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc
new file mode 100644
index 0000000..b552436
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc
@@ -0,0 +1,25 @@
+// 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/provided_file_system.h"
+
+namespace chromeos {
+namespace file_system_provider {
+
+ProvidedFileSystemInfo::ProvidedFileSystemInfo() {}
+
+ProvidedFileSystemInfo::ProvidedFileSystemInfo(
+ const std::string& extension_id,
+ int file_system_id,
+ const std::string& file_system_name,
+ const base::FilePath& mount_path)
+ : extension_id_(extension_id),
+ file_system_id_(file_system_id),
+ file_system_name_(file_system_name),
+ mount_path_(mount_path) {}
+
+ProvidedFileSystemInfo::~ProvidedFileSystemInfo() {}
+
+} // namespace file_system_provider
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h
new file mode 100644
index 0000000..3b88aec
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h
@@ -0,0 +1,48 @@
+// 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_PROVIDED_FILE_SYSTEM_INFO_H_
+#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INFO_H_
+
+#include <string>
+
+#include "base/files/file_path.h"
+
+namespace chromeos {
+namespace file_system_provider {
+
+// Contains information about the provided file system instance.
+class ProvidedFileSystemInfo {
+ public:
+ ProvidedFileSystemInfo();
+ ProvidedFileSystemInfo(const std::string& extension_id,
+ int file_system_id,
+ const std::string& file_system_name,
+ const base::FilePath& mount_path);
+
+ ~ProvidedFileSystemInfo();
+
+ const std::string& extension_id() const { return extension_id_; }
+ int file_system_id() const { return file_system_id_; }
+ const std::string& file_system_name() const { return file_system_name_; }
+ const base::FilePath& mount_path() const { return mount_path_; }
+
+ private:
+ // ID of the extension providing this file system.
+ std::string extension_id_;
+
+ // ID of the file system, used internally.
+ int file_system_id_;
+
+ // Name of the file system, can be rendered in the UI.
+ std::string file_system_name_;
+
+ // Mount path of the underlying file system.
+ base::FilePath mount_path_;
+};
+
+} // namespace file_system_provider
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INFO_H_
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
new file mode 100644
index 0000000..dedb17f
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
@@ -0,0 +1,38 @@
+// 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_PROVIDED_FILE_SYSTEM_INTERFACE_H_
+#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
+
+#include "webkit/browser/fileapi/async_file_util.h"
+
+class EventRouter;
+
+namespace chromeos {
+namespace file_system_provider {
+
+class ProvidedFileSystemInfo;
+class RequestManager;
+
+// Interface for a provided file system. Acts as a proxy between providers
+// and clients.
+// TODO(mtomasz): Add more methods once implemented.
+class ProvidedFileSystemInterface {
+ public:
+ virtual ~ProvidedFileSystemInterface() {}
+
+ // Requests unmounting of the file system. The callback is called when the
+ // request is accepted or rejected, with an error code. Returns false if the
+ // request could not been created, true otherwise.
+ virtual bool RequestUnmount(
+ const fileapi::AsyncFileUtil::StatusCallback& callback) = 0;
+
+ // Returns a provided file system info for this file system.
+ virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const = 0;
+};
+
+} // namespace file_system_provider
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
new file mode 100644
index 0000000..20e520a
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
@@ -0,0 +1,183 @@
+// 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/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system.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_manager.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "extensions/browser/event_router.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace file_system_provider {
+
+namespace {
+
+const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
+const int kExpectedRequestId = 1;
+const int kFileSystemId = 2;
+const char kFileSystemName[] = "Camera Pictures";
+
+class FakeEventRouter : public extensions::EventRouter {
+ public:
+ explicit FakeEventRouter(Profile* profile) : EventRouter(profile, NULL) {}
+ virtual ~FakeEventRouter() {}
+
+ virtual void DispatchEventToExtension(const std::string& extension_id,
+ scoped_ptr<extensions::Event> event)
+ OVERRIDE {
+ extension_id_ = extension_id;
+ event_ = event.Pass();
+ }
+
+ const std::string& extension_id() const { return extension_id_; }
+
+ const extensions::Event* event() const { return event_.get(); }
+
+ private:
+ std::string extension_id_;
+ scoped_ptr<extensions::Event> event_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeEventRouter);
+};
+
+class EventLogger {
+ public:
+ EventLogger() : weak_ptr_factory_(this) {}
+ virtual ~EventLogger() {}
+
+ void OnStatusCallback(base::File::Error error) {
+ error_.reset(new base::File::Error(error));
+ }
+
+ base::File::Error* error() { return error_.get(); }
+
+ base::WeakPtr<EventLogger> GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
+
+ private:
+ scoped_ptr<base::File::Error> error_;
+
+ base::WeakPtrFactory<EventLogger> weak_ptr_factory_;
+ DISALLOW_COPY_AND_ASSIGN(EventLogger);
+};
+
+} // namespace
+
+class FileSystemProviderProvidedFileSystemTest : public testing::Test {
+ protected:
+ FileSystemProviderProvidedFileSystemTest() {}
+ virtual ~FileSystemProviderProvidedFileSystemTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ profile_.reset(new TestingProfile);
+ event_router_.reset(new FakeEventRouter(profile_.get()));
+ request_manager_.reset(new RequestManager());
+ base::FilePath mount_path =
+ util::GetMountPointPath(profile_.get(), kExtensionId, kFileSystemId);
+ file_system_info_.reset(new ProvidedFileSystemInfo(
+ kExtensionId, kFileSystemId, kFileSystemName, mount_path));
+ provided_file_system_.reset(new ProvidedFileSystem(
+ event_router_.get(), request_manager_.get(), *file_system_info_.get()));
+ }
+
+ content::TestBrowserThreadBundle thread_bundle_;
+ scoped_ptr<TestingProfile> profile_;
+ scoped_ptr<FakeEventRouter> event_router_;
+ scoped_ptr<RequestManager> request_manager_;
+ scoped_ptr<ProvidedFileSystemInfo> file_system_info_;
+ scoped_ptr<ProvidedFileSystemInterface> provided_file_system_;
+};
+
+TEST_F(FileSystemProviderProvidedFileSystemTest, RequestUnmount_Success) {
+ EventLogger logger;
+
+ bool result = provided_file_system_->RequestUnmount(
+ base::Bind(&EventLogger::OnStatusCallback, logger.GetWeakPtr()));
+ ASSERT_TRUE(result);
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that the event has been sent to the providing extension.
+ EXPECT_EQ(kExtensionId, event_router_->extension_id());
+ const extensions::Event* event = event_router_->event();
+ ASSERT_TRUE(event);
+ ASSERT_TRUE(event->event_args);
+ base::ListValue* event_args = event->event_args.get();
+ EXPECT_EQ(2u, event_args->GetSize());
+ int file_system_id = 0;
+ EXPECT_TRUE(event_args->GetInteger(0, &file_system_id));
+ EXPECT_EQ(kFileSystemId, file_system_id);
+
+ // Remember the request id, and verify it is valid.
+ int request_id = 0;
+ EXPECT_TRUE(event_args->GetInteger(1, &request_id));
+ EXPECT_EQ(kExpectedRequestId, request_id);
+
+ // Callback should not be called, yet.
+ EXPECT_FALSE(logger.error());
+
+ // Simulate sending a success response from the providing extension.
+ scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue());
+ bool reply_result = request_manager_->FulfillRequest(kExtensionId,
+ kFileSystemId,
+ request_id,
+ response.Pass(),
+ false /* has_next */);
+ EXPECT_TRUE(reply_result);
+
+ // Callback should be called. Verify the error code.
+ ASSERT_TRUE(logger.error());
+ EXPECT_EQ(base::File::FILE_OK, *logger.error());
+}
+
+TEST_F(FileSystemProviderProvidedFileSystemTest, RequestUnmount_Error) {
+ EventLogger logger;
+
+ bool result = provided_file_system_->RequestUnmount(
+ base::Bind(&EventLogger::OnStatusCallback, logger.GetWeakPtr()));
+ ASSERT_TRUE(result);
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that the event has been sent to the providing extension.
+ EXPECT_EQ(kExtensionId, event_router_->extension_id());
+ const extensions::Event* event = event_router_->event();
+ ASSERT_TRUE(event);
+ ASSERT_TRUE(event->event_args);
+ base::ListValue* event_args = event->event_args.get();
+ EXPECT_EQ(2u, event_args->GetSize());
+ int file_system_id = 0;
+ EXPECT_TRUE(event_args->GetInteger(0, &file_system_id));
+ EXPECT_EQ(kFileSystemId, file_system_id);
+
+ // Remember the request id, and verify it is valid.
+ int request_id = 0;
+ EXPECT_TRUE(event_args->GetInteger(1, &request_id));
+ EXPECT_EQ(kExpectedRequestId, request_id);
+
+ // Simulate sending an error response from the providing extension.
+ bool reply_result =
+ request_manager_->RejectRequest(kExtensionId,
+ kFileSystemId,
+ request_id,
+ base::File::FILE_ERROR_NOT_FOUND);
+ EXPECT_TRUE(reply_result);
+
+ // Callback should be called. Verify the error code.
+ ASSERT_TRUE(logger.error());
+ EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error());
+}
+
+} // namespace file_system_provider
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/request_manager.cc b/chrome/browser/chromeos/file_system_provider/request_manager.cc
index 4083f57..575dce6 100644
--- a/chrome/browser/chromeos/file_system_provider/request_manager.cc
+++ b/chrome/browser/chromeos/file_system_provider/request_manager.cc
@@ -13,7 +13,8 @@ RequestManager::RequestManager() : next_id_(1) {}
RequestManager::~RequestManager() {}
-int RequestManager::CreateRequest(const ProvidedFileSystem& file_system,
+int RequestManager::CreateRequest(const std::string& extension_id,
+ int file_system_id,
const SuccessCallback& success_callback,
const ErrorCallback& error_callback) {
// The request id is unique per request manager, so per service, thereof
@@ -25,7 +26,8 @@ int RequestManager::CreateRequest(const ProvidedFileSystem& file_system,
return 0;
Request request;
- request.file_system = file_system;
+ request.extension_id = extension_id;
+ request.file_system_id = file_system_id;
request.success_callback = success_callback;
request.error_callback = error_callback;
requests_[request_id] = request;
@@ -33,7 +35,8 @@ int RequestManager::CreateRequest(const ProvidedFileSystem& file_system,
return request_id;
}
-bool RequestManager::FulfillRequest(const ProvidedFileSystem& file_system,
+bool RequestManager::FulfillRequest(const std::string& extension_id,
+ int file_system_id,
int request_id,
scoped_ptr<base::DictionaryValue> response,
bool has_next) {
@@ -43,8 +46,8 @@ bool RequestManager::FulfillRequest(const ProvidedFileSystem& file_system,
return false;
// Check if the request belongs to the same provided file system.
- if (request_it->second.file_system.file_system_id() !=
- file_system.file_system_id()) {
+ if (request_it->second.file_system_id != file_system_id ||
+ request_it->second.extension_id != extension_id) {
return false;
}
@@ -56,7 +59,8 @@ bool RequestManager::FulfillRequest(const ProvidedFileSystem& file_system,
return true;
}
-bool RequestManager::RejectRequest(const ProvidedFileSystem& file_system,
+bool RequestManager::RejectRequest(const std::string& extension_id,
+ int file_system_id,
int request_id,
base::File::Error error) {
RequestMap::iterator request_it = requests_.find(request_id);
@@ -65,8 +69,8 @@ bool RequestManager::RejectRequest(const ProvidedFileSystem& file_system,
return false;
// Check if the request belongs to the same provided file system.
- if (request_it->second.file_system.file_system_id() !=
- file_system.file_system_id()) {
+ if (request_it->second.file_system_id != file_system_id ||
+ request_it->second.extension_id != extension_id) {
return false;
}
@@ -78,11 +82,11 @@ bool RequestManager::RejectRequest(const ProvidedFileSystem& file_system,
}
void RequestManager::OnProvidedFileSystemMount(
- const ProvidedFileSystem& file_system,
+ const ProvidedFileSystemInfo& file_system_info,
base::File::Error error) {}
void RequestManager::OnProvidedFileSystemUnmount(
- const ProvidedFileSystem& file_system,
+ const ProvidedFileSystemInfo& file_system_info,
base::File::Error error) {
// Do not continue on error, since the volume may be still mounted.
if (error != base::File::FILE_OK)
@@ -91,18 +95,20 @@ void RequestManager::OnProvidedFileSystemUnmount(
// Remove all requests for this provided file system.
RequestMap::iterator it = requests_.begin();
while (it != requests_.begin()) {
- if (it->second.file_system.file_system_id() ==
- file_system.file_system_id()) {
- RejectRequest(
- it->second.file_system, it->first, base::File::FILE_ERROR_ABORT);
+ if (it->second.file_system_id == file_system_info.file_system_id() &&
+ it->second.extension_id == file_system_info.extension_id()) {
+ RejectRequest(it->second.extension_id,
+ it->second.file_system_id,
+ it->first,
+ base::File::FILE_ERROR_ABORT);
requests_.erase(it++);
} else {
- it++;
+ ++it;
}
}
}
-RequestManager::Request::Request() {}
+RequestManager::Request::Request() : file_system_id(0) {}
RequestManager::Request::~Request() {}
diff --git a/chrome/browser/chromeos/file_system_provider/request_manager.h b/chrome/browser/chromeos/file_system_provider/request_manager.h
index 6eb2f45..a712165 100644
--- a/chrome/browser/chromeos/file_system_provider/request_manager.h
+++ b/chrome/browser/chromeos/file_system_provider/request_manager.h
@@ -12,7 +12,7 @@
#include "base/files/file.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/file_system_provider/observer.h"
-#include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
namespace base {
class DictionaryValue;
@@ -21,12 +21,13 @@ class DictionaryValue;
namespace chromeos {
namespace file_system_provider {
-typedef base::Callback<void(scoped_ptr<base::DictionaryValue>, bool has_next)>
- SuccessCallback;
+typedef base::Callback<void(scoped_ptr<base::DictionaryValue> result,
+ bool has_next)> SuccessCallback;
typedef base::Callback<void(base::File::Error)> ErrorCallback;
// Manages requests between the service, async utils and the providing
// extensions.
+// TODO(mtomasz): Create for each provided file system.
class RequestManager : public Observer {
public:
RequestManager();
@@ -34,29 +35,33 @@ class RequestManager : public Observer {
// Creates a request and returns its request id (greater than 0). Returns 0 in
// case of an error (eg. too many requests). The passed callbacks can be NULL.
- int CreateRequest(const ProvidedFileSystem& file_system,
+ int CreateRequest(const std::string& extension_id,
+ int file_system_id,
const SuccessCallback& success_callback,
const ErrorCallback& error_callback);
// Handles successful response for the |request_id|. If |has_next| is false,
// then the request is disposed, after handling the |response|. On error,
// returns false, and the request is disposed.
- bool FulfillRequest(const ProvidedFileSystem& file_system,
+ bool FulfillRequest(const std::string& extension_id,
+ int file_system_id,
int request_id,
scoped_ptr<base::DictionaryValue> response,
bool has_next);
// Handles error response for the |request_id|. If handling the error fails,
// returns false. Always disposes the request.
- bool RejectRequest(const ProvidedFileSystem& file_system,
+ bool RejectRequest(const std::string& extension_id,
+ int file_system_id,
int request_id,
base::File::Error error);
// file_system_provider::Observer overrides.
- virtual void OnProvidedFileSystemMount(const ProvidedFileSystem& file_system,
- base::File::Error error) OVERRIDE;
+ virtual void OnProvidedFileSystemMount(
+ const ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error) OVERRIDE;
virtual void OnProvidedFileSystemUnmount(
- const ProvidedFileSystem& file_system,
+ const ProvidedFileSystemInfo& file_system_info,
base::File::Error error) OVERRIDE;
private:
@@ -64,8 +69,11 @@ class RequestManager : public Observer {
Request();
~Request();
- // Provided file system handling the request.
- ProvidedFileSystem file_system;
+ // Providing extension's ID.
+ std::string extension_id;
+
+ // Provided file system's ID.
+ int file_system_id;
// Callback to be called on success.
SuccessCallback success_callback;
diff --git a/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc b/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc
index 2ca0113..2e4ab55 100644
--- a/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc
@@ -20,9 +20,6 @@ namespace {
const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
const int kFileSystemId = 1;
-const char kFileSystemName[] = "Camera Pictures";
-const base::FilePath::CharType kMountPath[] = FILE_PATH_LITERAL(
- "/provided/mbflcebpggnecokmikipoihdbecnjfoj-1-testing_profile-hash");
// Logs calls of the success and error callbacks on requests.
class EventLogger {
@@ -85,23 +82,17 @@ class FileSystemProviderRequestManagerTest : public testing::Test {
virtual void SetUp() OVERRIDE {
request_manager_.reset(new RequestManager());
-
- // Configure the testing file system.
- file_system = ProvidedFileSystem(kExtensionId,
- kFileSystemId,
- kFileSystemName,
- base::FilePath(kMountPath));
}
scoped_ptr<RequestManager> request_manager_;
- ProvidedFileSystem file_system;
};
TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill) {
EventLogger logger;
int request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
@@ -114,7 +105,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill) {
response->SetString("path", "i-like-vanilla");
bool result = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), has_next);
EXPECT_TRUE(result);
// Validate if the callback has correct arguments.
@@ -130,15 +121,16 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill) {
// Confirm, that the request is removed. Basically, fulfilling again for the
// same request, should fail.
{
+ scoped_ptr<base::DictionaryValue> response;
bool retry = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), has_next);
EXPECT_FALSE(retry);
}
// Rejecting should also fail.
{
bool retry = request_manager_->RejectRequest(
- file_system, request_id, base::File::FILE_ERROR_FAILED);
+ kExtensionId, kFileSystemId, request_id, base::File::FILE_ERROR_FAILED);
EXPECT_FALSE(retry);
}
}
@@ -147,7 +139,8 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) {
EventLogger logger;
int request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
@@ -159,7 +152,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) {
const bool has_next = true;
bool result = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), has_next);
EXPECT_TRUE(result);
// Validate if the callback has correct arguments.
@@ -174,7 +167,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) {
{
bool new_has_next = false;
bool retry = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), new_has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), new_has_next);
EXPECT_TRUE(retry);
}
@@ -183,7 +176,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) {
{
bool new_has_next = false;
bool retry = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), new_has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), new_has_next);
EXPECT_FALSE(retry);
}
}
@@ -192,7 +185,8 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndReject) {
EventLogger logger;
int request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
@@ -201,7 +195,8 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndReject) {
EXPECT_EQ(0u, logger.error_events().size());
base::File::Error error = base::File::FILE_ERROR_NO_MEMORY;
- bool result = request_manager_->RejectRequest(file_system, request_id, error);
+ bool result = request_manager_->RejectRequest(
+ kExtensionId, kFileSystemId, request_id, error);
EXPECT_TRUE(result);
// Validate if the callback has correct arguments.
@@ -216,14 +211,14 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndReject) {
scoped_ptr<base::DictionaryValue> response;
bool has_next = false;
bool retry = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), has_next);
EXPECT_FALSE(retry);
}
// Rejecting should also fail.
{
- bool retry =
- request_manager_->RejectRequest(file_system, request_id, error);
+ bool retry = request_manager_->RejectRequest(
+ kExtensionId, kFileSystemId, request_id, error);
EXPECT_FALSE(retry);
}
}
@@ -233,7 +228,8 @@ TEST_F(FileSystemProviderRequestManagerTest,
EventLogger logger;
int request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
@@ -242,8 +238,8 @@ TEST_F(FileSystemProviderRequestManagerTest,
EXPECT_EQ(0u, logger.error_events().size());
base::File::Error error = base::File::FILE_ERROR_NO_MEMORY;
- bool result =
- request_manager_->RejectRequest(file_system, request_id + 1, error);
+ bool result = request_manager_->RejectRequest(
+ kExtensionId, kFileSystemId, request_id + 1, error);
EXPECT_FALSE(result);
// Callbacks should not be called.
@@ -252,8 +248,8 @@ TEST_F(FileSystemProviderRequestManagerTest,
// Confirm, that the request hasn't been removed, by rejecting it correctly.
{
- bool retry =
- request_manager_->RejectRequest(file_system, request_id, error);
+ bool retry = request_manager_->RejectRequest(
+ kExtensionId, kFileSystemId, request_id, error);
EXPECT_TRUE(retry);
}
}
@@ -263,7 +259,8 @@ TEST_F(FileSystemProviderRequestManagerTest,
EventLogger logger;
int request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
@@ -272,8 +269,8 @@ TEST_F(FileSystemProviderRequestManagerTest,
EXPECT_EQ(0u, logger.error_events().size());
base::File::Error error = base::File::FILE_ERROR_NO_MEMORY;
- bool result =
- request_manager_->RejectRequest(file_system, request_id + 1, error);
+ bool result = request_manager_->RejectRequest(
+ kExtensionId, kFileSystemId, request_id + 1, error);
EXPECT_FALSE(result);
// Callbacks should not be called.
@@ -282,8 +279,8 @@ TEST_F(FileSystemProviderRequestManagerTest,
// Confirm, that the request hasn't been removed, by rejecting it correctly.
{
- bool retry =
- request_manager_->RejectRequest(file_system, request_id, error);
+ bool retry = request_manager_->RejectRequest(
+ kExtensionId, kFileSystemId, request_id, error);
EXPECT_TRUE(retry);
}
}
@@ -293,25 +290,20 @@ TEST_F(FileSystemProviderRequestManagerTest,
EventLogger logger;
int request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
EXPECT_EQ(1, request_id);
- // Create another file system, which has just a different fiel system id
- // (1 -> 2).
- ProvidedFileSystem another_file_system(
- kExtensionId,
- 2, // file_system_id
- "Music",
- base::FilePath::FromUTF8Unsafe(
- "/provided/mbflcebpggnecokmikipoihdbecnjfoj-2-testing_profile-hash"));
-
scoped_ptr<base::DictionaryValue> response;
const bool has_next = false;
- bool result = request_manager_->FulfillRequest(
- another_file_system, request_id, response.Pass(), has_next);
+ bool result = request_manager_->FulfillRequest(kExtensionId,
+ 2, // file_system_id
+ request_id,
+ response.Pass(),
+ has_next);
EXPECT_FALSE(result);
// Callbacks should not be called.
@@ -322,7 +314,7 @@ TEST_F(FileSystemProviderRequestManagerTest,
// with a correct file system.
{
bool retry = request_manager_->FulfillRequest(
- file_system, request_id, response.Pass(), has_next);
+ kExtensionId, kFileSystemId, request_id, response.Pass(), has_next);
EXPECT_TRUE(retry);
}
}
@@ -331,12 +323,14 @@ TEST_F(FileSystemProviderRequestManagerTest, UniqueIds) {
EventLogger logger;
int first_request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
int second_request_id = request_manager_->CreateRequest(
- file_system,
+ kExtensionId,
+ kFileSystemId,
base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()),
base::Bind(&EventLogger::OnError, logger.GetWeakPtr()));
diff --git a/chrome/browser/chromeos/file_system_provider/service.cc b/chrome/browser/chromeos/file_system_provider/service.cc
index f8e7136..5348b34 100644
--- a/chrome/browser/chromeos/file_system_provider/service.cc
+++ b/chrome/browser/chromeos/file_system_provider/service.cc
@@ -5,16 +5,14 @@
#include "chrome/browser/chromeos/file_system_provider/service.h"
#include "base/files/file_path.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/values.h"
+#include "base/stl_util.h"
+#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
#include "chrome/browser/chromeos/file_system_provider/observer.h"
#include "chrome/browser/chromeos/file_system_provider/provided_file_system.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/service_factory.h"
-#include "chrome/browser/chromeos/login/user.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/common/extensions/api/file_system_provider.h"
#include "content/public/browser/browser_thread.h"
-#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_system.h"
#include "webkit/browser/fileapi/external_mount_points.h"
@@ -22,46 +20,32 @@ namespace chromeos {
namespace file_system_provider {
namespace {
-// Root mount path for all of the provided file systems.
-const base::FilePath::CharType kProvidedMountPointRoot[] =
- FILE_PATH_LITERAL("/provided");
-
// Maximum number of file systems to be mounted in the same time, per profile.
const size_t kMaxFileSystems = 16;
-// Constructs a safe mount point path for the provided file system represented
-// by |file_system_handle|. The handle is a numeric part of the file system id.
-base::FilePath GetMountPointPath(Profile* profile,
- std::string extension_id,
- int file_system_id) {
- chromeos::User* const user =
- chromeos::UserManager::IsInitialized()
- ? chromeos::UserManager::Get()->GetUserByProfile(
- profile->GetOriginalProfile())
- : NULL;
- const std::string user_suffix = user ? "-" + user->username_hash() : "";
- return base::FilePath(kProvidedMountPointRoot).AppendASCII(
- extension_id + "-" + base::IntToString(file_system_id) + user_suffix);
-}
-
-// Creates values to be passed to request events. These values can be extended
-// by additional fields.
-scoped_ptr<base::ListValue> CreateRequestValues(int file_system_id,
- int request_id) {
- scoped_ptr<base::ListValue> values(new base::ListValue());
- values->AppendInteger(file_system_id);
- values->AppendInteger(request_id);
- return values.Pass();
+// Default factory for provided file systems. The |event_router| nor the
+// |request_manager| arguments must not be NULL.
+ProvidedFileSystemInterface* CreateProvidedFileSystem(
+ extensions::EventRouter* event_router,
+ RequestManager* request_manager,
+ const ProvidedFileSystemInfo& file_system_info) {
+ DCHECK(event_router);
+ DCHECK(request_manager);
+ return new ProvidedFileSystem(
+ event_router, request_manager, file_system_info);
}
} // namespace
Service::Service(Profile* profile)
- : profile_(profile), next_id_(1), weak_ptr_factory_(this) {
+ : profile_(profile),
+ file_system_factory_(base::Bind(CreateProvidedFileSystem)),
+ next_id_(1),
+ weak_ptr_factory_(this) {
AddObserver(&request_manager_);
}
-Service::~Service() {}
+Service::~Service() { STLDeleteValues(&file_system_map_); }
// static
Service* Service::Get(content::BrowserContext* context) {
@@ -78,21 +62,27 @@ void Service::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
+void Service::SetFileSystemFactoryForTests(
+ const FileSystemFactoryCallback& factory_callback) {
+ DCHECK(!factory_callback.is_null());
+ file_system_factory_ = factory_callback;
+}
+
int Service::MountFileSystem(const std::string& extension_id,
const std::string& file_system_name) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
// Restrict number of file systems to prevent system abusing.
- if (file_systems_.size() + 1 > kMaxFileSystems) {
+ if (file_system_map_.size() + 1 > kMaxFileSystems) {
FOR_EACH_OBSERVER(
Observer,
observers_,
- OnProvidedFileSystemMount(ProvidedFileSystem(),
+ OnProvidedFileSystemMount(ProvidedFileSystemInfo(),
base::File::FILE_ERROR_TOO_MANY_OPENED));
return 0;
}
- // The file system id is unique per service, so per profile.
+ // The provided file system id is unique per service, so per profile.
int file_system_id = next_id_;
fileapi::ExternalMountPoints* const mount_points =
@@ -102,7 +92,7 @@ int Service::MountFileSystem(const std::string& extension_id,
// The mount point path and name are unique per system, since they are system
// wide. This is necessary for copying between profiles.
const base::FilePath& mount_point_path =
- GetMountPointPath(profile_, extension_id, file_system_id);
+ util::GetMountPointPath(profile_, extension_id, file_system_id);
const std::string mount_point_name =
mount_point_path.BaseName().AsUTF8Unsafe();
@@ -113,7 +103,7 @@ int Service::MountFileSystem(const std::string& extension_id,
FOR_EACH_OBSERVER(
Observer,
observers_,
- OnProvidedFileSystemMount(ProvidedFileSystem(),
+ OnProvidedFileSystemMount(ProvidedFileSystemInfo(),
base::File::FILE_ERROR_INVALID_OPERATION));
return 0;
}
@@ -124,14 +114,22 @@ int Service::MountFileSystem(const std::string& extension_id,
// file_system_id = 41
// mount_point_name = file_system_id = b33f1337-41-5aa5
// mount_point_path = /provided/b33f1337-41-5aa5
- ProvidedFileSystem file_system(
+ ProvidedFileSystemInfo file_system_info(
extension_id, file_system_id, file_system_name, mount_point_path);
- file_systems_[file_system_id] = file_system;
+
+ // The event router may be NULL for unit tests.
+ extensions::EventRouter* event_router =
+ extensions::ExtensionSystem::Get(profile_)->event_router();
+
+ ProvidedFileSystemInterface* file_system = file_system_factory_.Run(
+ event_router, &request_manager_, file_system_info);
+ DCHECK(file_system);
+ file_system_map_[file_system_id] = file_system;
FOR_EACH_OBSERVER(
Observer,
observers_,
- OnProvidedFileSystemMount(file_system, base::File::FILE_OK));
+ OnProvidedFileSystemMount(file_system_info, base::File::FILE_OK));
next_id_++;
return file_system_id;
@@ -141,14 +139,17 @@ bool Service::UnmountFileSystem(const std::string& extension_id,
int file_system_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
- if (file_system_it == file_systems_.end() ||
- file_system_it->second.extension_id() != extension_id) {
- const ProvidedFileSystem empty_file_system;
- FOR_EACH_OBSERVER(Observer,
- observers_,
- OnProvidedFileSystemUnmount(
- empty_file_system, base::File::FILE_ERROR_NOT_FOUND));
+ ProvidedFileSystemMap::iterator file_system_it =
+ file_system_map_.find(file_system_id);
+ if (file_system_it == file_system_map_.end() ||
+ file_system_it->second->GetFileSystemInfo().extension_id() !=
+ extension_id) {
+ const ProvidedFileSystemInfo empty_file_system_info;
+ FOR_EACH_OBSERVER(
+ Observer,
+ observers_,
+ OnProvidedFileSystemUnmount(empty_file_system_info,
+ base::File::FILE_ERROR_NOT_FOUND));
return false;
}
@@ -156,13 +157,16 @@ bool Service::UnmountFileSystem(const std::string& extension_id,
fileapi::ExternalMountPoints::GetSystemInstance();
DCHECK(mount_points);
+ const ProvidedFileSystemInfo& file_system_info =
+ file_system_it->second->GetFileSystemInfo();
+
const std::string mount_point_name =
- file_system_it->second.mount_path().BaseName().value();
+ file_system_info.mount_path().BaseName().value();
if (!mount_points->RevokeFileSystem(mount_point_name)) {
FOR_EACH_OBSERVER(
Observer,
observers_,
- OnProvidedFileSystemUnmount(file_system_it->second,
+ OnProvidedFileSystemUnmount(file_system_info,
base::File::FILE_ERROR_INVALID_OPERATION));
return false;
}
@@ -170,96 +174,68 @@ bool Service::UnmountFileSystem(const std::string& extension_id,
FOR_EACH_OBSERVER(
Observer,
observers_,
- OnProvidedFileSystemUnmount(file_system_it->second, base::File::FILE_OK));
+ OnProvidedFileSystemUnmount(file_system_info, base::File::FILE_OK));
- file_systems_.erase(file_system_it);
+ delete file_system_it->second;
+ file_system_map_.erase(file_system_it);
return true;
}
-std::vector<ProvidedFileSystem> Service::GetMountedFileSystems() {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
- std::vector<ProvidedFileSystem> result;
- for (FileSystemMap::const_iterator it = file_systems_.begin();
- it != file_systems_.end();
- ++it) {
- result.push_back(it->second);
- }
- return result;
-}
-
-bool Service::FulfillRequest(const std::string& extension_id,
- int file_system_id,
- int request_id,
- scoped_ptr<base::DictionaryValue> result,
- bool has_next) {
+bool Service::RequestUnmount(int file_system_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
- if (file_system_it == file_systems_.end() ||
- file_system_it->second.extension_id() != extension_id) {
+ ProvidedFileSystemMap::iterator file_system_it =
+ file_system_map_.find(file_system_id);
+ if (file_system_it == file_system_map_.end())
return false;
- }
- return request_manager_.FulfillRequest(
- file_system_it->second, request_id, result.Pass(), has_next);
+ return file_system_it->second->RequestUnmount(
+ base::Bind(&Service::OnRequestUnmountStatus,
+ weak_ptr_factory_.GetWeakPtr(),
+ file_system_it->second->GetFileSystemInfo()));
}
-bool Service::RejectRequest(const std::string& extension_id,
- int file_system_id,
- int request_id,
- base::File::Error error) {
+std::vector<ProvidedFileSystemInfo> Service::GetProvidedFileSystemInfoList() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
- if (file_system_it == file_systems_.end() ||
- file_system_it->second.extension_id() != extension_id) {
- return false;
+ std::vector<ProvidedFileSystemInfo> result;
+ for (ProvidedFileSystemMap::const_iterator it = file_system_map_.begin();
+ it != file_system_map_.end();
+ ++it) {
+ result.push_back(it->second->GetFileSystemInfo());
}
-
- return request_manager_.RejectRequest(
- file_system_it->second, request_id, error);
+ return result;
}
-bool Service::RequestUnmount(int file_system_id) {
+ProvidedFileSystemInterface* Service::GetProvidedFileSystem(
+ const std::string& extension_id,
+ int file_system_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
- if (file_system_it == file_systems_.end())
- return false;
-
- int request_id =
- request_manager_.CreateRequest(file_system_it->second,
- SuccessCallback(),
- base::Bind(&Service::OnRequestUnmountError,
- weak_ptr_factory_.GetWeakPtr(),
- file_system_it->second));
-
- if (!request_id)
- return false;
-
- scoped_ptr<base::ListValue> values(
- CreateRequestValues(file_system_id, request_id));
-
- extensions::EventRouter* event_router =
- extensions::ExtensionSystem::Get(profile_)->event_router();
- DCHECK(event_router);
-
- event_router->DispatchEventToExtension(
- file_system_it->second.extension_id(),
- make_scoped_ptr(new extensions::Event(
- extensions::api::file_system_provider::OnUnmountRequested::kEventName,
- values.Pass())));
+ ProvidedFileSystemMap::iterator file_system_it =
+ file_system_map_.find(file_system_id);
+ if (file_system_it == file_system_map_.end() ||
+ file_system_it->second->GetFileSystemInfo().extension_id() !=
+ extension_id) {
+ return NULL;
+ }
- return true;
+ return file_system_it->second;
}
void Service::Shutdown() { RemoveObserver(&request_manager_); }
-void Service::OnRequestUnmountError(const ProvidedFileSystem& file_system,
- base::File::Error error) {
- FOR_EACH_OBSERVER(
- Observer, observers_, OnProvidedFileSystemUnmount(file_system, error));
+void Service::OnRequestUnmountStatus(
+ const ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error) {
+ // Notify observers about failure in unmounting, since mount() will not be
+ // called by the provided file system. In case of success mount() will be
+ // invoked, and observers notified, so there is no need to call them now.
+ if (error != base::File::FILE_OK) {
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ OnProvidedFileSystemUnmount(file_system_info, error));
+ }
}
} // namespace file_system_provider
diff --git a/chrome/browser/chromeos/file_system_provider/service.h b/chrome/browser/chromeos/file_system_provider/service.h
index 735e05f..adf09c5 100644
--- a/chrome/browser/chromeos/file_system_provider/service.h
+++ b/chrome/browser/chromeos/file_system_provider/service.h
@@ -21,17 +21,36 @@
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/browser_context.h"
+namespace extensions {
+class EventRouter;
+} // namespace extensions
+
namespace chromeos {
namespace file_system_provider {
+class ProvidedFileSystemFactoryInterface;
+class ProvidedFileSystemInfo;
+class ProvidedFileSystemInterface;
class ServiceFactory;
-// Manages and registers the fileSystemProvider service.
+// Manages and registers the file system provider service. Maintains provided
+// file systems.
class Service : public KeyedService {
public:
+ typedef base::Callback<ProvidedFileSystemInterface*(
+ extensions::EventRouter* event_router,
+ RequestManager* request_manager,
+ const ProvidedFileSystemInfo& file_system_info)>
+ FileSystemFactoryCallback;
+
explicit Service(Profile* profile);
virtual ~Service();
+ // Sets a custom ProvidedFileSystemInterface factory. Used by unit tests,
+ // where an event router is not available.
+ void SetFileSystemFactoryForTests(
+ const FileSystemFactoryCallback& factory_callback);
+
// Mounts a file system provided by an extension with the |extension_id|.
// For success, it returns a numeric file system id, which is an
// auto-incremented non-zero value. For failures, it returns zero.
@@ -42,30 +61,21 @@ class Service : public KeyedService {
// |extension_id|. For success returns true, otherwise false.
bool UnmountFileSystem(const std::string& extension_id, int file_system_id);
- // Returns a list of currently mounted file systems. All items are copied.
- std::vector<ProvidedFileSystem> GetMountedFileSystems();
-
- // Handles successful response for the |request_id|. If |has_next| is false,
- // then the request is disposed, after handling the |response|. On error,
- // returns false, and the request is disposed.
- bool FulfillRequest(const std::string& extension_id,
- int file_system_id,
- int request_id,
- scoped_ptr<base::DictionaryValue> result,
- bool has_next);
-
- // Handles error response for the |request_id|. If handling the error fails,
- // returns false. Always disposes the request.
- bool RejectRequest(const std::string& extension_id,
- int file_system_id,
- int request_id,
- base::File::Error error);
-
- // Requests unmounting of a file system with the passed |file_system_id|.
- // Returns true is unmounting has been requested. False, if the request is
- // invalid (eg. already unmounted).
+ // Requests unmounting of the file system. The callback is called when the
+ // request is accepted or rejected, with an error code. Returns false if the
+ // request could not been created, true otherwise.
bool RequestUnmount(int file_system_id);
+ // Returns a list of information of all currently provided file systems. All
+ // items are copied.
+ std::vector<ProvidedFileSystemInfo> GetProvidedFileSystemInfoList();
+
+ // Returns a provided file system with |file_system_id|, handled by
+ // the extension with |extension_id|. If not found, then returns NULL.
+ ProvidedFileSystemInterface* GetProvidedFileSystem(
+ const std::string& extension_id,
+ int file_system_id);
+
// Adds and removes observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
@@ -76,18 +86,23 @@ class Service : public KeyedService {
// BrowserContextKeyedService overrides.
virtual void Shutdown() OVERRIDE;
+ // Getter for the request manager. Used by the extension API to forward
+ // replies. Valid as long as the service.
+ RequestManager* request_manager() { return &request_manager_; }
+
private:
- typedef std::map<int, ProvidedFileSystem> FileSystemMap;
+ typedef std::map<int, ProvidedFileSystemInterface*> ProvidedFileSystemMap;
- // Called when the providing extension calls the success callback for the
- // onUnmountRequested event.
- void OnRequestUnmountError(const ProvidedFileSystem& file_system,
- base::File::Error error);
+ // Called when the providing extension accepts or refuses a unmount request.
+ // If |error| is equal to FILE_OK, then the request is accepted.
+ void OnRequestUnmountStatus(const ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error);
RequestManager request_manager_;
Profile* profile_;
+ FileSystemFactoryCallback file_system_factory_;
ObserverList<Observer> observers_;
- FileSystemMap file_systems_;
+ ProvidedFileSystemMap file_system_map_; // Owns pointers.
int next_id_;
base::WeakPtrFactory<Service> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/file_system_provider/service_unittest.cc b/chrome/browser/chromeos/file_system_provider/service_unittest.cc
index d72dd01..a24dd23 100644
--- a/chrome/browser/chromeos/file_system_provider/service_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/service_unittest.cc
@@ -7,8 +7,10 @@
#include "base/files/file.h"
#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
+#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
#include "chrome/browser/chromeos/file_system_provider/observer.h"
-#include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
#include "chrome/browser/chromeos/file_system_provider/service.h"
#include "chrome/browser/chromeos/login/fake_user_manager.h"
#include "chrome/test/base/testing_profile.h"
@@ -28,15 +30,18 @@ class LoggingObserver : public Observer {
public:
class Event {
public:
- Event(const ProvidedFileSystem& file_system, base::File::Error error)
- : file_system_(file_system), error_(error) {}
+ Event(const ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error)
+ : file_system_info_(file_system_info), error_(error) {}
~Event() {}
- const ProvidedFileSystem& file_system() { return file_system_; }
+ const ProvidedFileSystemInfo& file_system_info() {
+ return file_system_info_;
+ }
base::File::Error error() { return error_; }
private:
- ProvidedFileSystem file_system_;
+ ProvidedFileSystemInfo file_system_info_;
base::File::Error error_;
};
@@ -44,15 +49,16 @@ class LoggingObserver : public Observer {
virtual ~LoggingObserver() {}
// file_system_provider::Observer overrides.
- virtual void OnProvidedFileSystemMount(const ProvidedFileSystem& file_system,
- base::File::Error error) OVERRIDE {
- mounts.push_back(Event(file_system, error));
+ virtual void OnProvidedFileSystemMount(
+ const ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error) OVERRIDE {
+ mounts.push_back(Event(file_system_info, error));
}
virtual void OnProvidedFileSystemUnmount(
- const ProvidedFileSystem& file_system,
+ const ProvidedFileSystemInfo& file_system_info,
base::File::Error error) OVERRIDE {
- unmounts.push_back(Event(file_system, error));
+ unmounts.push_back(Event(file_system_info, error));
}
std::vector<Event> mounts;
@@ -72,6 +78,8 @@ class FileSystemProviderServiceTest : public testing::Test {
profile_.reset(new TestingProfile);
user_manager_->AddUser(profile_->GetProfileName());
file_system_provider_service_.reset(new Service(profile_.get()));
+ file_system_provider_service_->SetFileSystemFactoryForTests(
+ base::Bind(&FakeProvidedFileSystem::Create));
}
virtual void TearDown() {
@@ -94,18 +102,20 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) {
EXPECT_LT(0, file_system_id);
ASSERT_EQ(1u, observer.mounts.size());
- EXPECT_EQ(kExtensionId, observer.mounts[0].file_system().extension_id());
- EXPECT_EQ(1, observer.mounts[0].file_system().file_system_id());
- EXPECT_EQ("/provided/mbflcebpggnecokmikipoihdbecnjfoj-1-testing_profile-hash",
- observer.mounts[0].file_system().mount_path().AsUTF8Unsafe());
+ EXPECT_EQ(kExtensionId, observer.mounts[0].file_system_info().extension_id());
+ EXPECT_EQ(1, observer.mounts[0].file_system_info().file_system_id());
+ base::FilePath expected_mount_path =
+ util::GetMountPointPath(profile_.get(), kExtensionId, file_system_id);
+ EXPECT_EQ(expected_mount_path.AsUTF8Unsafe(),
+ observer.mounts[0].file_system_info().mount_path().AsUTF8Unsafe());
EXPECT_EQ(kFileSystemName,
- observer.mounts[0].file_system().file_system_name());
+ observer.mounts[0].file_system_info().file_system_name());
EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
ASSERT_EQ(0u, observer.unmounts.size());
- std::vector<ProvidedFileSystem> provided_file_systems =
- file_system_provider_service_->GetMountedFileSystems();
- ASSERT_EQ(1u, provided_file_systems.size());
+ std::vector<ProvidedFileSystemInfo> file_system_info_list =
+ file_system_provider_service_->GetProvidedFileSystemInfoList();
+ ASSERT_EQ(1u, file_system_info_list.size());
file_system_provider_service_->RemoveObserver(&observer);
}
@@ -127,9 +137,9 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem_UniqueIds) {
EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
EXPECT_EQ(base::File::FILE_OK, observer.mounts[1].error());
- std::vector<ProvidedFileSystem> provided_file_systems =
- file_system_provider_service_->GetMountedFileSystems();
- ASSERT_EQ(2u, provided_file_systems.size());
+ std::vector<ProvidedFileSystemInfo> file_system_info_list =
+ file_system_provider_service_->GetProvidedFileSystemInfoList();
+ ASSERT_EQ(2u, file_system_info_list.size());
file_system_provider_service_->RemoveObserver(&observer);
}
@@ -154,12 +164,10 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem_StressTest) {
ASSERT_EQ(kMaxFileSystems + 1, observer.mounts.size());
EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED,
observer.mounts[kMaxFileSystems].error());
- ASSERT_EQ(kMaxFileSystems,
- file_system_provider_service_->GetMountedFileSystems().size());
- std::vector<ProvidedFileSystem> provided_file_systems =
- file_system_provider_service_->GetMountedFileSystems();
- ASSERT_EQ(kMaxFileSystems, provided_file_systems.size());
+ std::vector<ProvidedFileSystemInfo> file_system_info_list =
+ file_system_provider_service_->GetProvidedFileSystemInfoList();
+ ASSERT_EQ(kMaxFileSystems, file_system_info_list.size());
file_system_provider_service_->RemoveObserver(&observer);
}
@@ -179,16 +187,20 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem) {
ASSERT_EQ(1u, observer.unmounts.size());
EXPECT_EQ(base::File::FILE_OK, observer.unmounts[0].error());
- EXPECT_EQ(kExtensionId, observer.unmounts[0].file_system().extension_id());
- EXPECT_EQ(1, observer.unmounts[0].file_system().file_system_id());
- EXPECT_EQ("/provided/mbflcebpggnecokmikipoihdbecnjfoj-1-testing_profile-hash",
- observer.unmounts[0].file_system().mount_path().AsUTF8Unsafe());
+ EXPECT_EQ(kExtensionId,
+ observer.unmounts[0].file_system_info().extension_id());
+ EXPECT_EQ(1, observer.unmounts[0].file_system_info().file_system_id());
+ base::FilePath expected_mount_path =
+ util::GetMountPointPath(profile_.get(), kExtensionId, file_system_id);
+ EXPECT_EQ(
+ expected_mount_path.AsUTF8Unsafe(),
+ observer.unmounts[0].file_system_info().mount_path().AsUTF8Unsafe());
EXPECT_EQ(kFileSystemName,
- observer.unmounts[0].file_system().file_system_name());
+ observer.unmounts[0].file_system_info().file_system_name());
- std::vector<ProvidedFileSystem> provided_file_systems =
- file_system_provider_service_->GetMountedFileSystems();
- ASSERT_EQ(0u, provided_file_systems.size());
+ std::vector<ProvidedFileSystemInfo> file_system_info_list =
+ file_system_provider_service_->GetProvidedFileSystemInfoList();
+ ASSERT_EQ(0u, file_system_info_list.size());
file_system_provider_service_->RemoveObserver(&observer);
}
@@ -203,18 +215,22 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_WrongExtensionId) {
kExtensionId, kFileSystemName);
EXPECT_LT(0, file_system_id);
ASSERT_EQ(1u, observer.mounts.size());
- ASSERT_EQ(1u, file_system_provider_service_->GetMountedFileSystems().size());
+ ASSERT_EQ(
+ 1u,
+ file_system_provider_service_->GetProvidedFileSystemInfoList().size());
const bool result = file_system_provider_service_->UnmountFileSystem(
kWrongExtensionId, file_system_id);
EXPECT_FALSE(result);
ASSERT_EQ(1u, observer.unmounts.size());
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, observer.unmounts[0].error());
- ASSERT_EQ(1u, file_system_provider_service_->GetMountedFileSystems().size());
+ ASSERT_EQ(
+ 1u,
+ file_system_provider_service_->GetProvidedFileSystemInfoList().size());
- std::vector<ProvidedFileSystem> provided_file_systems =
- file_system_provider_service_->GetMountedFileSystems();
- ASSERT_EQ(1u, provided_file_systems.size());
+ std::vector<ProvidedFileSystemInfo> file_system_info_list =
+ file_system_provider_service_->GetProvidedFileSystemInfoList();
+ ASSERT_EQ(1u, file_system_info_list.size());
file_system_provider_service_->RemoveObserver(&observer);
}
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index a57b01d..1236ce9 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -369,9 +369,14 @@
'browser/chromeos/file_manager/volume_manager_observer.h',
'browser/chromeos/file_manager/zip_file_creator.cc',
'browser/chromeos/file_manager/zip_file_creator.h',
+ 'browser/chromeos/file_system_provider/mount_path_util.cc',
+ 'browser/chromeos/file_system_provider/mount_path_util.h',
'browser/chromeos/file_system_provider/observer.h',
'browser/chromeos/file_system_provider/provided_file_system.cc',
'browser/chromeos/file_system_provider/provided_file_system.h',
+ 'browser/chromeos/file_system_provider/provided_file_system_info.cc',
+ 'browser/chromeos/file_system_provider/provided_file_system_info.h',
+ 'browser/chromeos/file_system_provider/provided_file_system_interface.h',
'browser/chromeos/file_system_provider/request_manager.cc',
'browser/chromeos/file_system_provider/request_manager.h',
'browser/chromeos/file_system_provider/service.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index b3a797a..702d19a 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -695,6 +695,9 @@
'browser/chromeos/extensions/default_app_order_unittest.cc',
'browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc',
'browser/chromeos/extensions/external_cache_unittest.cc',
+ 'browser/chromeos/extensions/device_local_account_management_policy_provider_unittest.cc',
+ 'browser/chromeos/extensions/wallpaper_private_api_unittest.cc',
+ 'browser/chromeos/external_metrics_unittest.cc',
'browser/chromeos/file_manager/fake_disk_mount_manager.cc',
'browser/chromeos/file_manager/fake_disk_mount_manager.h',
'browser/chromeos/file_manager/file_tasks_unittest.cc',
@@ -704,11 +707,12 @@
'browser/chromeos/file_manager/path_util_unittest.cc',
'browser/chromeos/file_manager/url_util_unittest.cc',
'browser/chromeos/file_manager/volume_manager_unittest.cc',
+ 'browser/chromeos/file_system_provider/fake_provided_file_system.cc',
+ 'browser/chromeos/file_system_provider/fake_provided_file_system.h',
+ 'browser/chromeos/file_system_provider/mount_path_util_unittest.cc',
+ 'browser/chromeos/file_system_provider/provided_file_system_unittest.cc',
'browser/chromeos/file_system_provider/request_manager_unittest.cc',
'browser/chromeos/file_system_provider/service_unittest.cc',
- 'browser/chromeos/extensions/device_local_account_management_policy_provider_unittest.cc',
- 'browser/chromeos/extensions/wallpaper_private_api_unittest.cc',
- 'browser/chromeos/external_metrics_unittest.cc',
'browser/chromeos/fileapi/file_access_permissions_unittest.cc',
'browser/chromeos/fileapi/file_system_backend_unittest.cc',
'browser/chromeos/imageburner/burn_device_handler_unittest.cc',