diff options
author | tbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-18 03:12:54 +0000 |
---|---|---|
committer | tbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-18 03:12:54 +0000 |
commit | 9d5d6986dfaed15ef3719250fbf7fb8347bebd80 (patch) | |
tree | a472d1593efc197e15d9474d26e93530b939ec7f | |
parent | d22af016d12e789ac7c5976c300c819ebe4340b3 (diff) | |
download | chromium_src-9d5d6986dfaed15ef3719250fbf7fb8347bebd80.zip chromium_src-9d5d6986dfaed15ef3719250fbf7fb8347bebd80.tar.gz chromium_src-9d5d6986dfaed15ef3719250fbf7fb8347bebd80.tar.bz2 |
Extract external file systems handling from isolated context.
Move mount point info bookeeping from CrosMountPointProvider to ExternalMountPoints.
Add some tests for CrosMountPointProvider.
BUG=158837
TEST=content_unittests:CrosMountPointProvider*
TBR=benwells@chromium.org
Review URL: https://chromiumcodereview.appspot.com/11648027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177578 0039d316-1c4b-4281-b951-d872f2087c98
27 files changed, 1399 insertions, 383 deletions
diff --git a/chrome/browser/chromeos/drive/drive_file_system_proxy.h b/chrome/browser/chromeos/drive/drive_file_system_proxy.h index d2db758..d66b473 100644 --- a/chrome/browser/chromeos/drive/drive_file_system_proxy.h +++ b/chrome/browser/chromeos/drive/drive_file_system_proxy.h @@ -6,7 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_FILE_SYSTEM_PROXY_H_ #include "chrome/browser/chromeos/drive/drive_file_error.h" -#include "webkit/chromeos/fileapi/remote_file_system_proxy.h" +#include "webkit/fileapi/remote_file_system_proxy.h" namespace fileapi { class FileSystemURL; diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc index 2b5301b..0faa9e9 100644 --- a/chrome/browser/extensions/api/file_system/file_system_api.cc +++ b/chrome/browser/extensions/api/file_system/file_system_api.cc @@ -156,10 +156,10 @@ bool GetFilePathOfFileEntry(const std::string& filesystem_name, FilePath relative_path = FilePath::FromUTF8Unsafe(filesystem_path); FilePath virtual_path = context->CreateVirtualRootPath(filesystem_id) .Append(relative_path); - if (!context->CrackIsolatedPath(virtual_path, - &filesystem_id, - NULL, - file_path)) { + if (!context->CrackVirtualPath(virtual_path, + &filesystem_id, + NULL, + file_path)) { *error = kInvalidParameters; return false; } diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc index 62faaa7..dcc3934 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc @@ -28,6 +28,7 @@ #include "content/public/test/test_utils.h" #include "ui/shell_dialogs/select_file_dialog.h" #include "ui/shell_dialogs/selected_file_info.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_mount_point_provider.h" @@ -119,7 +120,12 @@ class SelectFileDialogExtensionBrowserTest : public ExtensionBrowserTest { fileapi::ExternalFileSystemMountPointProvider* provider = BrowserContext::GetDefaultStoragePartition(browser()->profile())-> GetFileSystemContext()->external_provider(); - provider->AddLocalMountPoint(path); + + // The Downloads mount point already exists so it must be removed before + // adding the test mount point (which will also be mapped as Downloads). + fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( + path.BaseName().AsUTF8Unsafe()); + EXPECT_TRUE(provider->AddLocalMountPoint(path)); } void CheckJavascriptErrors() { diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 6a0dac1..804605d 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -404,6 +404,7 @@ '../webkit/blob/mock_blob_url_request_context.cc', '../webkit/blob/mock_blob_url_request_context.h', '../webkit/blob/shareable_file_reference_unittest.cc', + '../webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc', '../webkit/database/database_connections_unittest.cc', '../webkit/database/database_quota_client_unittest.cc', '../webkit/database/databases_table_unittest.cc', @@ -415,6 +416,7 @@ '../webkit/dom_storage/dom_storage_database_unittest.cc', '../webkit/dom_storage/dom_storage_map_unittest.cc', '../webkit/dom_storage/session_storage_database_unittest.cc', + '../webkit/fileapi/external_mount_points_unittest.cc', '../webkit/fileapi/file_system_database_test_helper.cc', '../webkit/fileapi/file_system_database_test_helper.h', '../webkit/fileapi/file_system_directory_database_unittest.cc', diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.cc b/webkit/chromeos/fileapi/cros_mount_point_provider.cc index f61e3cc..33bcbf1 100644 --- a/webkit/chromeos/fileapi/cros_mount_point_provider.cc +++ b/webkit/chromeos/fileapi/cros_mount_point_provider.cc @@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" -#include "base/path_service.h" #include "base/stringprintf.h" #include "base/synchronization/lock.h" #include "base/utf_string_conversions.h" @@ -19,6 +18,7 @@ #include "webkit/chromeos/fileapi/file_access_permissions.h" #include "webkit/chromeos/fileapi/remote_file_stream_writer.h" #include "webkit/chromeos/fileapi/remote_file_system_operation.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_system_file_stream_reader.h" #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_system_url.h" @@ -47,16 +47,14 @@ bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) { } CrosMountPointProvider::CrosMountPointProvider( - scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy) + scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy, + scoped_refptr<fileapi::ExternalMountPoints> mount_points, + fileapi::ExternalMountPoints* system_mount_points) : special_storage_policy_(special_storage_policy), file_access_permissions_(new FileAccessPermissions()), - local_file_util_(new fileapi::IsolatedFileUtil()) { - FilePath home_path; - if (PathService::Get(base::DIR_HOME, &home_path)) - AddLocalMountPoint(home_path.AppendASCII("Downloads")); - AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/archive"))); - AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/removable"))); - AddRestrictedLocalMountPoint(FilePath(FILE_PATH_LITERAL("/usr/share/oem"))); + local_file_util_(new fileapi::IsolatedFileUtil()), + mount_points_(mount_points), + system_mount_points_(system_mount_points) { } CrosMountPointProvider::~CrosMountPointProvider() { @@ -80,8 +78,11 @@ FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread( return FilePath(); FilePath root_path; - if (!isolated_context()->GetRegisteredPath(url.filesystem_id(), &root_path)) + std::string mount_name = url.filesystem_id(); + if (!mount_points_->GetRegisteredPath(mount_name, &root_path) && + !system_mount_points_->GetRegisteredPath(mount_name, &root_path)) { return FilePath(); + } return root_path.DirName(); } @@ -128,56 +129,47 @@ void CrosMountPointProvider::DeleteFileSystem( callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); } -bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) { +bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) const { std::string mount_name = mount_point.BaseName().AsUTF8Unsafe(); FilePath path; - const bool valid = isolated_context()->GetRegisteredPath(mount_name, &path); + + const bool valid = mount_points_->GetRegisteredPath(mount_name, &path); return valid && path == mount_point; } -void CrosMountPointProvider::AddLocalMountPoint(const FilePath& mount_point) { +bool CrosMountPointProvider::AddLocalMountPoint(const FilePath& mount_point) { std::string mount_name = mount_point.BaseName().AsUTF8Unsafe(); - isolated_context()->RevokeFileSystem(mount_name); - isolated_context()->RegisterExternalFileSystem( - mount_name, - fileapi::kFileSystemTypeNativeLocal, - mount_point); - base::AutoLock locker(mount_point_map_lock_); - local_to_virtual_map_[mount_point] = mount_point.BaseName(); + return mount_points_->RegisterFileSystem( + mount_name, + fileapi::kFileSystemTypeNativeLocal, + mount_point); } -void CrosMountPointProvider::AddRestrictedLocalMountPoint( +bool CrosMountPointProvider::AddRestrictedLocalMountPoint( const FilePath& mount_point) { std::string mount_name = mount_point.BaseName().AsUTF8Unsafe(); - isolated_context()->RevokeFileSystem(mount_name); - isolated_context()->RegisterExternalFileSystem( - mount_name, - fileapi::kFileSystemTypeRestrictedNativeLocal, - mount_point); - base::AutoLock locker(mount_point_map_lock_); - local_to_virtual_map_[mount_point] = mount_point.BaseName(); + return mount_points_->RegisterFileSystem( + mount_name, + fileapi::kFileSystemTypeRestrictedNativeLocal, + mount_point); } -void CrosMountPointProvider::AddRemoteMountPoint( +bool CrosMountPointProvider::AddRemoteMountPoint( const FilePath& mount_point, fileapi::RemoteFileSystemProxyInterface* remote_proxy) { DCHECK(remote_proxy); std::string mount_name = mount_point.BaseName().AsUTF8Unsafe(); - isolated_context()->RevokeFileSystem(mount_name); - isolated_context()->RegisterExternalFileSystem(mount_name, + return mount_points_->RegisterRemoteFileSystem(mount_name, fileapi::kFileSystemTypeDrive, + remote_proxy, mount_point); - base::AutoLock locker(mount_point_map_lock_); - remote_proxy_map_[mount_name] = remote_proxy; - local_to_virtual_map_[mount_point] = mount_point.BaseName(); } void CrosMountPointProvider::RemoveMountPoint(const FilePath& mount_point) { + if (!HasMountPoint(mount_point)) + return; std::string mount_name = mount_point.BaseName().AsUTF8Unsafe(); - isolated_context()->RevokeFileSystem(mount_name); - base::AutoLock locker(mount_point_map_lock_); - remote_proxy_map_.erase(mount_name); - local_to_virtual_map_.erase(mount_point); + mount_points_->RevokeFileSystem(mount_name); } void CrosMountPointProvider::GrantFullAccessToExtension( @@ -185,8 +177,11 @@ void CrosMountPointProvider::GrantFullAccessToExtension( DCHECK(special_storage_policy_->IsFileHandler(extension_id)); if (!special_storage_policy_->IsFileHandler(extension_id)) return; - std::vector<fileapi::IsolatedContext::FileInfo> files = - isolated_context()->GetExternalMountPoints(); + + std::vector<fileapi::MountPoints::MountPointInfo> files; + mount_points_->AddMountPointInfosTo(&files); + system_mount_points_->AddMountPointInfosTo(&files); + for (size_t i = 0; i < files.size(); ++i) { file_access_permissions_->GrantAccessPermission( extension_id, @@ -204,7 +199,11 @@ void CrosMountPointProvider::GrantFileAccessToExtension( std::string id; fileapi::FileSystemType type; FilePath path; - isolated_context()->CrackIsolatedPath(virtual_path, &id, &type, &path); + if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &path) && + !system_mount_points_->CrackVirtualPath(virtual_path, + &id, &type, &path)) { + return; + } if (type == fileapi::kFileSystemTypeRestrictedNativeLocal) { LOG(ERROR) << "Can't grant access for restricted mount point"; @@ -220,11 +219,13 @@ void CrosMountPointProvider::RevokeAccessForExtension( } std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const { - std::vector<fileapi::IsolatedContext::FileInfo> files = - isolated_context()->GetExternalMountPoints(); + std::vector<fileapi::MountPoints::MountPointInfo> mount_points; + mount_points_->AddMountPointInfosTo(&mount_points); + system_mount_points_->AddMountPointInfosTo(&mount_points); + std::vector<FilePath> root_dirs; - for (size_t i = 0; i < files.size(); ++i) - root_dirs.push_back(files[i].path); + for (size_t i = 0; i < mount_points.size(); ++i) + root_dirs.push_back(mount_points[i].path); return root_dirs; } @@ -249,16 +250,16 @@ fileapi::FileSystemOperation* CrosMountPointProvider::CreateFileSystemOperation( const fileapi::FileSystemURL& url, fileapi::FileSystemContext* context, base::PlatformFileError* error_code) const { + DCHECK(url.is_valid()); + if (url.type() == fileapi::kFileSystemTypeDrive) { - base::AutoLock locker(mount_point_map_lock_); - RemoteProxyMap::const_iterator found = remote_proxy_map_.find( - url.filesystem_id()); - if (found != remote_proxy_map_.end()) { - return new chromeos::RemoteFileSystemOperation(found->second); - } else { + fileapi::RemoteFileSystemProxyInterface* remote_proxy = + GetRemoteProxy(url.filesystem_id()); + if (!remote_proxy) { *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND; return NULL; } + return new chromeos::RemoteFileSystemOperation(remote_proxy); } DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal || @@ -285,15 +286,14 @@ fileapi::FileStreamWriter* CrosMountPointProvider::CreateFileStreamWriter( const fileapi::FileSystemURL& url, int64 offset, fileapi::FileSystemContext* context) const { - if (!url.is_valid()) - return NULL; + DCHECK(url.is_valid()); + if (url.type() == fileapi::kFileSystemTypeDrive) { - base::AutoLock locker(mount_point_map_lock_); - RemoteProxyMap::const_iterator found = remote_proxy_map_.find( - url.filesystem_id()); - if (found == remote_proxy_map_.end()) + fileapi::RemoteFileSystemProxyInterface* remote_proxy = + GetRemoteProxy(url.filesystem_id()); + if (!remote_proxy) return NULL; - return new fileapi::RemoteFileStreamWriter(found->second, url, offset); + return new fileapi::RemoteFileStreamWriter(remote_proxy, url, offset); } if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal) @@ -305,21 +305,17 @@ fileapi::FileStreamWriter* CrosMountPointProvider::CreateFileStreamWriter( bool CrosMountPointProvider::GetVirtualPath(const FilePath& filesystem_path, FilePath* virtual_path) { - base::AutoLock locker(mount_point_map_lock_); - std::map<FilePath, FilePath>::reverse_iterator iter( - local_to_virtual_map_.upper_bound(filesystem_path)); - if (iter == local_to_virtual_map_.rend()) - return false; - if (iter->first == filesystem_path) { - *virtual_path = iter->second; - return true; - } - return iter->first.DirName().AppendRelativePath( - filesystem_path, virtual_path); + return mount_points_->GetVirtualPath(filesystem_path, virtual_path) || + system_mount_points_->GetVirtualPath(filesystem_path, virtual_path); } -fileapi::IsolatedContext* CrosMountPointProvider::isolated_context() const { - return fileapi::IsolatedContext::GetInstance(); +fileapi::RemoteFileSystemProxyInterface* CrosMountPointProvider::GetRemoteProxy( + const std::string& mount_name) const { + fileapi::RemoteFileSystemProxyInterface* proxy = + mount_points_->GetRemoteFileSystemProxy(mount_name); + if (proxy) + return proxy; + return system_mount_points_->GetRemoteFileSystemProxy(mount_name); } } // namespace chromeos diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.h b/webkit/chromeos/fileapi/cros_mount_point_provider.h index 6f7b38b..d34c209 100644 --- a/webkit/chromeos/fileapi/cros_mount_point_provider.h +++ b/webkit/chromeos/fileapi/cros_mount_point_provider.h @@ -18,6 +18,7 @@ #include "webkit/storage/webkit_storage_export.h" namespace fileapi { +class ExternalMountPoints; class FileSystemFileUtil; class FileSystemURL; class IsolatedContext; @@ -35,8 +36,13 @@ class WEBKIT_STORAGE_EXPORT CrosMountPointProvider using fileapi::FileSystemMountPointProvider::ValidateFileSystemCallback; using fileapi::FileSystemMountPointProvider::DeleteFileSystemCallback; + // CrosMountPointProvider will take an ownership of a |mount_points| + // reference. On the other hand, |system_mount_points| will be kept as a raw + // pointer and it should outlive CrosMountPointProvider instance. CrosMountPointProvider( - scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy); + scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy, + scoped_refptr<fileapi::ExternalMountPoints> mount_points, + fileapi::ExternalMountPoints* system_mount_points); virtual ~CrosMountPointProvider(); // Returns true if CrosMountpointProvider can handle |url|, i.e. its @@ -88,11 +94,14 @@ class WEBKIT_STORAGE_EXPORT CrosMountPointProvider const std::string& extension_id, const FilePath& virtual_path) OVERRIDE; virtual void RevokeAccessForExtension( const std::string& extension_id) OVERRIDE; - virtual bool HasMountPoint(const FilePath& mount_point) OVERRIDE; - virtual void AddLocalMountPoint(const FilePath& mount_point) OVERRIDE; - virtual void AddRestrictedLocalMountPoint( + // Note: This will ignore |system_mount_points_|. The reasoning behind this is + // the method should be used paired with Add/RemoveMountPoint methods, which + // don't affect |system_mount_points_|. + virtual bool HasMountPoint(const FilePath& mount_point) const OVERRIDE; + virtual bool AddLocalMountPoint(const FilePath& mount_point) OVERRIDE; + virtual bool AddRestrictedLocalMountPoint( const FilePath& mount_point) OVERRIDE; - virtual void AddRemoteMountPoint( + virtual bool AddRemoteMountPoint( const FilePath& mount_point, fileapi::RemoteFileSystemProxyInterface* remote_proxy) OVERRIDE; virtual void RemoveMountPoint(const FilePath& mount_point) OVERRIDE; @@ -100,22 +109,31 @@ class WEBKIT_STORAGE_EXPORT CrosMountPointProvider FilePath* virtual_path) OVERRIDE; private: - typedef scoped_refptr<fileapi::RemoteFileSystemProxyInterface> RemoteProxy; - typedef std::map<FilePath::StringType, RemoteProxy> RemoteProxyMap; - - fileapi::IsolatedContext* isolated_context() const; - - // Represents a map from mount point name to a remote proxy. - RemoteProxyMap remote_proxy_map_; - - // Reverse map for GetVirtualPath. - std::map<FilePath, FilePath> local_to_virtual_map_; - - mutable base::Lock mount_point_map_lock_; + fileapi::RemoteFileSystemProxyInterface* GetRemoteProxy( + const std::string& mount_name) const; scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; scoped_ptr<FileAccessPermissions> file_access_permissions_; scoped_ptr<fileapi::LocalFileUtil> local_file_util_; + + // Mount points specific to the owning context. + // + // Add/Remove MountPoints will affect only these mount points. + // + // It is legal to have mount points with the same name as in + // system_mount_points_. Also, mount point paths may overlap with mount point + // paths in system_mount_points_. In both cases mount points in + // |mount_points_| will have a priority. + // E.g. if |mount_points_| map 'foo1' to '/foo/foo1' and + // |file_system_mount_points_| map 'xxx' to '/foo/foo1/xxx', |GetVirtualPaths| + // will resolve '/foo/foo1/xxx/yyy' as 'foo1/xxx/yyy' (i.e. the mapping from + // |mount_points_| will be used). + scoped_refptr<fileapi::ExternalMountPoints> mount_points_; + + // Globally visible mount points. System MountPonts instance should outlive + // all CrosMountPointProvider instances, so raw pointer is safe. + fileapi::ExternalMountPoints* system_mount_points_; + DISALLOW_COPY_AND_ASSIGN(CrosMountPointProvider); }; diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc b/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc new file mode 100644 index 0000000..3dfda44 --- /dev/null +++ b/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc @@ -0,0 +1,325 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/chromeos/fileapi/cros_mount_point_provider.h" + +#include <set> + +#include "base/file_path.h" +#include "googleurl/src/url_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/fileapi/external_mount_points.h" +#include "webkit/fileapi/file_system_url.h" +#include "webkit/fileapi/isolated_context.h" +#include "webkit/quota/mock_special_storage_policy.h" + +#define FPL(x) FILE_PATH_LITERAL(x) + +namespace { + +fileapi::FileSystemURL CreateFileSystemURL(const std::string& extension, + const char* path) { + return fileapi::FileSystemURL(GURL("chrome-extension://" + extension + "/"), + fileapi::kFileSystemTypeNativeLocal, + FilePath::FromUTF8Unsafe(path)); +} + +TEST(CrosMountPointProviderTest, DefaultMountPoints) { + scoped_refptr<quota::SpecialStoragePolicy> storage_policy = + new quota::MockSpecialStoragePolicy(); + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + chromeos::CrosMountPointProvider provider( + storage_policy, + mount_points.get(), + fileapi::ExternalMountPoints::GetSystemInstance()); + // By default there should be 4 mount points. + std::vector<FilePath> root_dirs = provider.GetRootDirectories(); + std::set<FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end()); + EXPECT_EQ(4u, root_dirs.size()); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/media/removable")))); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/media/archive")))); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/usr/share/oem")))); + // Fourth mount point is Downloads, but its local path is device specific. +} + +TEST(CrosMountPointProviderTest, GetRootDirectories) { + scoped_refptr<quota::SpecialStoragePolicy> storage_policy = + new quota::MockSpecialStoragePolicy(); + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + chromeos::CrosMountPointProvider provider( + storage_policy, + mount_points.get(), + system_mount_points.get()); + + // Register 'local' test mount points. + mount_points->RegisterFileSystem("c", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FPL("/a/b/c"))); + mount_points->RegisterFileSystem("d", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FPL("/b/c/d"))); + + // Register system test mount points. + system_mount_points->RegisterFileSystem("d", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FPL("/g/c/d"))); + system_mount_points->RegisterFileSystem("e", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FPL("/g/d/e"))); + + std::vector<FilePath> root_dirs = provider.GetRootDirectories(); + std::set<FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end()); + EXPECT_EQ(4u, root_dirs.size()); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/a/b/c")))); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/b/c/d")))); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/g/c/d")))); + EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/g/d/e")))); +} + +TEST(CrosMountPointProviderTest, MountPointsVisibility) { + scoped_refptr<quota::SpecialStoragePolicy> storage_policy = + new quota::MockSpecialStoragePolicy(); + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + scoped_refptr<fileapi::ExternalMountPoints> sibling_mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + chromeos::CrosMountPointProvider provider( + storage_policy, + mount_points.get(), + system_mount_points.get()); + + // A provider that shares system_mount_points with |provider|. + chromeos::CrosMountPointProvider sibling_provider( + storage_policy, + sibling_mount_points.get(), + system_mount_points.get()); + + FilePath ignored; + + // Adding empty mount point should fail. + EXPECT_FALSE(provider.AddLocalMountPoint(FilePath())); + + // Add mount point to the provider. + EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/a/b/c")))); + + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/a/b/c")))); + // The mount point with the same name exists, but path is different. + EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/x/a/b/c")))); + EXPECT_FALSE(sibling_provider.HasMountPoint(FilePath(FPL("/a/b/c")))); + EXPECT_TRUE(mount_points->GetRegisteredPath("c", &ignored)); + EXPECT_FALSE(system_mount_points->GetRegisteredPath("c", &ignored)); + + // Add mount point directly to |mount_points|. It should be seen by + // |provider|. + EXPECT_TRUE(mount_points->RegisterFileSystem( + "d", fileapi::kFileSystemTypeNativeLocal, FilePath(FPL("/b/c/d")))); + + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/b/c/d")))); + EXPECT_FALSE(sibling_provider.HasMountPoint(FilePath(FPL("/b/c/d")))); + + // Add mount point to system mount points. + EXPECT_TRUE(system_mount_points->RegisterFileSystem( + "e", fileapi::kFileSystemTypeNativeLocal, FilePath(FPL("/g/c/d/e")))); + + EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); + EXPECT_FALSE(sibling_provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); + + // Can't remove system mount point. + provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e"))); + EXPECT_TRUE(system_mount_points->GetRegisteredPath("e", &ignored)); + + // Add a mount points whose paths overlap with the system one's. + // The same path: + EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/g/c/d/e")))); + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); + provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e"))); + EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); + // Parent path: + EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/g")))); + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/g")))); + provider.RemoveMountPoint(FilePath(FPL("/g"))); + // Child path: + EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/g/c/d/e/f/g")))); + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e/f/g")))); + provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e/f/g"))); + + // Add mount point with the same name as a global one. Should succeed. + EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/d/e")))); + + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/d/e")))); + + // Remove system mount point with the same name as the added one. + // Should fail. + provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e"))); + + EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/d/e")))); + EXPECT_TRUE(system_mount_points->GetRegisteredPath("e", &ignored)); + + // Remove mount point. + provider.RemoveMountPoint(FilePath(FPL("/d/e"))); + + EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/d/e")))); +} + +TEST(CrosMountPointProviderTest, AccessPermissions) { + url_util::AddStandardScheme("chrome-extension"); + + scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy = + new quota::MockSpecialStoragePolicy(); + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + chromeos::CrosMountPointProvider provider( + storage_policy, + mount_points.get(), + system_mount_points.get()); + + std::string extension("ddammdhioacbehjngdmkjcjbnfginlla"); + + storage_policy->AddFileHandler(extension); + + // Initialize mount points. + system_mount_points->RegisterFileSystem("system", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FPL("/g/system"))); + ASSERT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/media/removable")))); + ASSERT_TRUE(provider.AddRestrictedLocalMountPoint( + FilePath(FPL("/usr/share/oem")))); + + // Provider specific mount point access. + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "removable/foo"))); + + provider.GrantFileAccessToExtension(extension, + FilePath(FPL("removable/foo"))); + EXPECT_TRUE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "removable/foo"))); + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "removable/foo1"))); + + // System mount point access. + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "system/foo"))); + + provider.GrantFileAccessToExtension(extension, FilePath(FPL("system/foo"))); + EXPECT_TRUE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "system/foo"))); + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "system/foo1"))); + + // oem is restricted file system. + provider.GrantFileAccessToExtension(extension, FilePath(FPL("oem/foo"))); + // The extension should not be able to access the file even if + // GrantFileAccessToExtension was called. + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "oem/foo"))); + + provider.GrantFullAccessToExtension(extension); + // The extension should be able to access restricted file system after it was + // granted full access. + EXPECT_TRUE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "oem/foo"))); + // The extension which was granted full access should be able to access any + // path on current file systems. + EXPECT_TRUE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "removable/foo1"))); + EXPECT_TRUE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "system/foo1"))); + + // The extension still cannot access new mount points. + ASSERT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/foo/test")))); + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "test_/foo"))); + + provider.RevokeAccessForExtension(extension); + EXPECT_FALSE(provider.IsAccessAllowed( + CreateFileSystemURL(extension, "removable/foo"))); + + fileapi::FileSystemURL internal_url(GURL("chrome://foo"), + fileapi::kFileSystemTypeExternal, + FilePath(FPL("removable/"))); + // Internal WebUI should have full access. + EXPECT_TRUE(provider.IsAccessAllowed(internal_url)); +} + +TEST(CrosMountPointProvider, GetVirtualPathConflictWithSystemPoints) { + scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy = + new quota::MockSpecialStoragePolicy(); + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + chromeos::CrosMountPointProvider provider(storage_policy, + mount_points.get(), + system_mount_points.get()); + + const fileapi::FileSystemType type = fileapi::kFileSystemTypeNativeLocal; + + // Provider specific mount points. + ASSERT_TRUE( + mount_points->RegisterFileSystem("b", type, FilePath(FPL("/a/b")))); + ASSERT_TRUE( + mount_points->RegisterFileSystem("y", type, FilePath(FPL("/z/y")))); + ASSERT_TRUE( + mount_points->RegisterFileSystem("n", type, FilePath(FPL("/m/n")))); + + // System mount points + ASSERT_TRUE(system_mount_points->RegisterFileSystem( + "gb", type, FilePath(FPL("/a/b")))); + ASSERT_TRUE( + system_mount_points->RegisterFileSystem("gz", type, FilePath(FPL("/z")))); + ASSERT_TRUE(system_mount_points->RegisterFileSystem( + "gp", type, FilePath(FPL("/m/n/o/p")))); + + struct TestCase { + const FilePath::CharType* const local_path; + bool success; + const FilePath::CharType* const virtual_path; + }; + + const TestCase kTestCases[] = { + // Same paths in both mount points. + { FPL("/a/b/c/d"), true, FPL("b/c/d") }, + // System mount points path more specific. + { FPL("/m/n/o/p/r/s"), true, FPL("n/o/p/r/s") }, + // System mount points path less specific. + { FPL("/z/y/x"), true, FPL("y/x") }, + // Only system mount points path matches. + { FPL("/z/q/r/s"), true, FPL("gz/q/r/s") }, + // No match. + { FPL("/foo/xxx"), false, FPL("") }, + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + // Initialize virtual path with a value. + FilePath virtual_path(FPL("/mount")); + FilePath local_path(kTestCases[i].local_path); + EXPECT_EQ(kTestCases[i].success, + provider.GetVirtualPath(local_path, &virtual_path)) + << "Resolving " << kTestCases[i].local_path; + + // There are no guarantees for |virtual_path| value if |GetVirtualPath| + // fails. + if (!kTestCases[i].success) + continue; + + FilePath expected_virtual_path(kTestCases[i].virtual_path); + EXPECT_EQ(expected_virtual_path, virtual_path) + << "Resolving " << kTestCases[i].local_path; + } +} + +} // namespace + diff --git a/webkit/chromeos/fileapi/remote_file_stream_writer.cc b/webkit/chromeos/fileapi/remote_file_stream_writer.cc index 187a79a..6fcbd65 100644 --- a/webkit/chromeos/fileapi/remote_file_stream_writer.cc +++ b/webkit/chromeos/fileapi/remote_file_stream_writer.cc @@ -8,8 +8,8 @@ #include "net/base/net_errors.h" #include "webkit/blob/local_file_stream_reader.h" #include "webkit/blob/shareable_file_reference.h" -#include "webkit/chromeos/fileapi/remote_file_system_proxy.h" #include "webkit/fileapi/local_file_stream_writer.h" +#include "webkit/fileapi/remote_file_system_proxy.h" namespace fileapi { diff --git a/webkit/chromeos/fileapi/remote_file_system_operation.h b/webkit/chromeos/fileapi/remote_file_system_operation.h index 3b51707..84a6f7d 100644 --- a/webkit/chromeos/fileapi/remote_file_system_operation.h +++ b/webkit/chromeos/fileapi/remote_file_system_operation.h @@ -5,9 +5,9 @@ #ifndef WEBKIT_CHROMEOS_FILEAPI_REMOTE_FILE_SYSTEM_OPERATION_H_ #define WEBKIT_CHROMEOS_FILEAPI_REMOTE_FILE_SYSTEM_OPERATION_H_ -#include "webkit/chromeos/fileapi/remote_file_system_proxy.h" #include "webkit/fileapi/file_system_operation.h" #include "webkit/fileapi/file_writer_delegate.h" +#include "webkit/fileapi/remote_file_system_proxy.h" namespace base { class Value; diff --git a/webkit/fileapi/external_mount_points.cc b/webkit/fileapi/external_mount_points.cc new file mode 100644 index 0000000..9abba42 --- /dev/null +++ b/webkit/fileapi/external_mount_points.cc @@ -0,0 +1,331 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/external_mount_points.h" + +#include "base/file_path.h" +#include "base/lazy_instance.h" +#include "base/path_service.h" +#include "base/stl_util.h" +#include "webkit/fileapi/remote_file_system_proxy.h" + +namespace { + +// Normalizes file path so it has normalized separators and ends with exactly +// one separator. Paths have to be normalized this way for use in +// GetVirtualPath method. Separators cannot be completely stripped, or +// GetVirtualPath could not working in some edge cases. +// For example, /a/b/c(1)/d would be erroneously resolved as c/d if the +// following mount points were registered: "/a/b/c", "/a/b/c(1)". (Note: +// "/a/b/c" < "/a/b/c(1)" < "/a/b/c/"). +FilePath NormalizeFilePath(const FilePath& path) { + if (path.empty()) + return path; + + FilePath::StringType path_str = path.StripTrailingSeparators().value(); + if (!FilePath::IsSeparator(path_str[path_str.length() - 1])) + path_str.append(FILE_PATH_LITERAL("/")); + + return FilePath(path_str).NormalizePathSeparators(); +} + +// Wrapper around ref-counted ExternalMountPoints that will be used to lazily +// create and initialize LazyInstance system ExternalMountPoints. +class SystemMountPointsLazyWrapper { + public: + SystemMountPointsLazyWrapper() + : system_mount_points_(fileapi::ExternalMountPoints::CreateRefCounted()) { + RegisterDefaultMountPoints(); + } + + ~SystemMountPointsLazyWrapper() {} + + fileapi::ExternalMountPoints* get() { + return system_mount_points_.get(); + } + + private: + void RegisterDefaultMountPoints() { +#if defined(OS_CHROMEOS) + // Add default system mount points. + system_mount_points_->RegisterFileSystem( + "archive", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FILE_PATH_LITERAL("/media/archive"))); + system_mount_points_->RegisterFileSystem( + "removable", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FILE_PATH_LITERAL("/media/removable"))); + system_mount_points_->RegisterFileSystem( + "oem", + fileapi::kFileSystemTypeRestrictedNativeLocal, + FilePath(FILE_PATH_LITERAL("/usr/share/oem"))); + + // TODO(tbarzic): Move this out of here. + FilePath home_path; + if (PathService::Get(base::DIR_HOME, &home_path)) { + system_mount_points_->RegisterFileSystem( + "Downloads", + fileapi::kFileSystemTypeNativeLocal, + home_path.AppendASCII("Downloads")); + } +#endif // defined(OS_CHROMEOS) + } + + scoped_refptr<fileapi::ExternalMountPoints> system_mount_points_; +}; + +base::LazyInstance<SystemMountPointsLazyWrapper>::Leaky + g_external_mount_points = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +namespace fileapi { + +class ExternalMountPoints::Instance { + public: + Instance(FileSystemType type, + const FilePath& path, + RemoteFileSystemProxyInterface* remote_proxy); + + ~Instance(); + + FileSystemType type() const { return type_; } + const FilePath& path() const { return path_; } + RemoteFileSystemProxyInterface* remote_proxy() const { + return remote_proxy_.get(); + } + + private: + const FileSystemType type_; + const FilePath path_; + + // For file systems that have a remote file system proxy. + scoped_refptr<RemoteFileSystemProxyInterface> remote_proxy_; + + DISALLOW_COPY_AND_ASSIGN(Instance); +}; + +ExternalMountPoints::Instance::Instance(FileSystemType type, + const FilePath& path, + RemoteFileSystemProxyInterface* proxy) + : type_(type), + path_(path.StripTrailingSeparators()), + remote_proxy_(proxy) { + DCHECK(!proxy || (kFileSystemTypeDrive == type_)); +} + +ExternalMountPoints::Instance::~Instance() {} + +//-------------------------------------------------------------------------- + +// static +ExternalMountPoints* ExternalMountPoints::GetSystemInstance() { + return g_external_mount_points.Pointer()->get(); +} + +// static +scoped_refptr<ExternalMountPoints> ExternalMountPoints::CreateRefCounted() { + return new ExternalMountPoints(); +} + +bool ExternalMountPoints::RegisterFileSystem( + const std::string& mount_name, + FileSystemType type, + const FilePath& path) { + return RegisterRemoteFileSystem(mount_name, type, NULL, path); +} + +bool ExternalMountPoints::RegisterRemoteFileSystem( + const std::string& mount_name, + FileSystemType type, + RemoteFileSystemProxyInterface* remote_proxy, + const FilePath& path_in) { + base::AutoLock locker(lock_); + + FilePath path = NormalizeFilePath(path_in); + if (!ValidateNewMountPoint(mount_name, path)) + return false; + + instance_map_[mount_name] = new Instance(type, path, remote_proxy); + if (!path.empty()) + path_to_name_map_.insert(std::make_pair(path, mount_name)); + return true; +} + +bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) { + base::AutoLock locker(lock_); + NameToInstance::iterator found = instance_map_.find(mount_name); + if (found == instance_map_.end()) + return false; + Instance* instance = found->second; + path_to_name_map_.erase(NormalizeFilePath(instance->path())); + delete found->second; + instance_map_.erase(found); + return true; +} + +bool ExternalMountPoints::GetRegisteredPath( + const std::string& filesystem_id, FilePath* path) const { + DCHECK(path); + base::AutoLock locker(lock_); + NameToInstance::const_iterator found = instance_map_.find(filesystem_id); + if (found == instance_map_.end()) + return false; + *path = found->second->path(); + return true; +} + +bool ExternalMountPoints::CrackVirtualPath(const FilePath& virtual_path, + std::string* mount_name, + FileSystemType* type, + FilePath* path) const { + DCHECK(mount_name); + DCHECK(path); + + // The path should not contain any '..' references. + if (virtual_path.ReferencesParent()) + return false; + + // The virtual_path should comprise of <mount_name> and <relative_path> parts. + std::vector<FilePath::StringType> components; + virtual_path.GetComponents(&components); + if (components.size() < 1) + return false; + + std::vector<FilePath::StringType>::iterator component_iter = + components.begin(); + std::string maybe_mount_name = FilePath(*component_iter++).MaybeAsASCII(); + if (maybe_mount_name.empty()) + return false; + + FilePath cracked_path; + { + base::AutoLock locker(lock_); + NameToInstance::const_iterator found_instance = + instance_map_.find(maybe_mount_name); + if (found_instance == instance_map_.end()) + return false; + + *mount_name = maybe_mount_name; + const Instance* instance = found_instance->second; + if (type) + *type = instance->type(); + cracked_path = instance->path(); + } + + for (; component_iter != components.end(); ++component_iter) + cracked_path = cracked_path.Append(*component_iter); + *path = cracked_path; + return true; +} + +RemoteFileSystemProxyInterface* ExternalMountPoints::GetRemoteFileSystemProxy( + const std::string& mount_name) const { + base::AutoLock locker(lock_); + NameToInstance::const_iterator found = instance_map_.find(mount_name); + if (found == instance_map_.end()) + return NULL; + return found->second->remote_proxy(); +} + +void ExternalMountPoints::AddMountPointInfosTo( + std::vector<MountPointInfo>* mount_points) const { + base::AutoLock locker(lock_); + DCHECK(mount_points); + for (NameToInstance::const_iterator iter = instance_map_.begin(); + iter != instance_map_.end(); ++iter) { + mount_points->push_back(MountPointInfo(iter->first, iter->second->path())); + } +} + +bool ExternalMountPoints::GetVirtualPath(const FilePath& path_in, + FilePath* virtual_path) { + DCHECK(virtual_path); + + base::AutoLock locker(lock_); + + FilePath path = NormalizeFilePath(path_in); + std::map<FilePath, std::string>::reverse_iterator iter( + path_to_name_map_.upper_bound(path)); + if (iter == path_to_name_map_.rend()) + return false; + + *virtual_path = CreateVirtualRootPath(iter->second); + if (iter->first == path) + return true; + return iter->first.AppendRelativePath(path, virtual_path); +} + +FilePath ExternalMountPoints::CreateVirtualRootPath( + const std::string& mount_name) const { + return FilePath().AppendASCII(mount_name); +} + +ExternalMountPoints::ExternalMountPoints() {} + +ExternalMountPoints::~ExternalMountPoints() { + STLDeleteContainerPairSecondPointers(instance_map_.begin(), + instance_map_.end()); +} + +bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name, + const FilePath& path) { + lock_.AssertAcquired(); + + // Mount name must not be empty. + if (mount_name.empty()) + return false; + + // Verify there is no registered mount point with the same name. + NameToInstance::iterator found = instance_map_.find(mount_name); + if (found != instance_map_.end()) + return false; + + // Allow empty paths. + if (path.empty()) + return true; + + // Verify path is legal. + if (path.ReferencesParent() || !path.IsAbsolute()) + return false; + + // Check there the new path does not overlap with one of the existing ones. + std::map<FilePath, std::string>::reverse_iterator potential_parent( + path_to_name_map_.upper_bound(path)); + if (potential_parent != path_to_name_map_.rend()) { + if (potential_parent->first == path || + potential_parent->first.IsParent(path)) { + return false; + } + } + + std::map<FilePath, std::string>::iterator potential_child = + path_to_name_map_.upper_bound(path); + if (potential_child == path_to_name_map_.end()) + return true; + return !(potential_child->first == path) && + !path.IsParent(potential_child->first); +} + +ScopedExternalFileSystem::ScopedExternalFileSystem( + const std::string& mount_name, + FileSystemType type, + const FilePath& path) + : mount_name_(mount_name) { + ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( + mount_name, type, path); +} + +FilePath ScopedExternalFileSystem::GetVirtualRootPath() const { + return ExternalMountPoints::GetSystemInstance()-> + CreateVirtualRootPath(mount_name_); +} + +ScopedExternalFileSystem::~ScopedExternalFileSystem() { + ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(mount_name_); +} + +} // namespace fileapi + diff --git a/webkit/fileapi/external_mount_points.h b/webkit/fileapi/external_mount_points.h new file mode 100644 index 0000000..fe8d4d0 --- /dev/null +++ b/webkit/fileapi/external_mount_points.h @@ -0,0 +1,155 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_EXTERNAL_MOUNT_POINTS_H_ +#define WEBKIT_FILEAPI_EXTERNAL_MOUNT_POINTS_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/mount_points.h" +#include "webkit/storage/webkit_storage_export.h" + +class FilePath; + +namespace fileapi { +class RemoteFileSystemProxyInterface; +} + +namespace fileapi { + +// Manages external filesystem namespaces that are identified by 'mount name' +// and are persisted until RevokeFileSystem is called. +// Files in an external filesystem are identified by a filesystem URL like: +// +// filesystem:<origin>/external/<mount_name>/relative/path +// +class WEBKIT_STORAGE_EXPORT ExternalMountPoints + : public base::RefCountedThreadSafe<ExternalMountPoints>, + public MountPoints { + public: + static ExternalMountPoints* GetSystemInstance(); + static scoped_refptr<ExternalMountPoints> CreateRefCounted(); + + // Registers a new named external filesystem. + // The |path| is registered as the root path of the mount point which + // is identified by a URL "filesystem:.../external/mount_name". + // + // For example, if the path "/media/removable" is registered with + // the mount_name "removable", a filesystem URL like + // "filesystem:.../external/removable/a/b" will be resolved as + // "/media/removable/a/b". + // + // The |mount_name| should NOT contain a path separator '/'. + // Returns false if the given name is already registered. + // + // Overlapping mount points in a single MountPoints instance are not allowed. + // Adding mount point whose path overlaps with an existing mount point will + // fail. + // + // If not empty, |path| must be absolute. It is allowed for the path to be + // empty, but |GetVirtualPath| will not work for those mount points. + // + // An external file system registered by this method can be revoked + // by calling RevokeFileSystem with |mount_name|. + bool RegisterFileSystem(const std::string& mount_name, + FileSystemType type, + const FilePath& path); + + // Same as |RegisterExternalFileSystem|, but also registers a remote file + // system proxy for the file system. + bool RegisterRemoteFileSystem(const std::string& mount_name, + FileSystemType type, + RemoteFileSystemProxyInterface* remote_proxy, + const FilePath& path); + + // MountPoints overrides. + virtual bool RevokeFileSystem(const std::string& mount_name) OVERRIDE; + virtual bool GetRegisteredPath(const std::string& mount_name, + FilePath* path) const OVERRIDE; + virtual bool CrackVirtualPath(const FilePath& virtual_path, + std::string* mount_name, + FileSystemType* type, + FilePath* path) const OVERRIDE; + + // Retrieves the remote file system proxy for the registered file system. + // Returns NULL if there is no file system with the given name, or if the file + // system does not have a remote file system proxy. + RemoteFileSystemProxyInterface* GetRemoteFileSystemProxy( + const std::string& mount_name) const; + + // Returns a list of registered MountPointInfos (of <mount_name, path>). + void AddMountPointInfosTo(std::vector<MountPointInfo>* mount_points) const; + + // Converts a path on a registered file system to virtual path relative to the + // file system root. E.g. if 'Downloads' file system is mapped to + // '/usr/local/home/Downloads', and |absolute| path is set to + // '/usr/local/home/Downloads/foo', the method will set |virtual_path| to + // 'Downloads/foo'. + // Returns false if the path cannot be resolved (e.g. if the path is not + // part of any registered filesystem). + // + // Returned virtual_path will have normalized path separators. + bool GetVirtualPath(const FilePath& absolute_path, FilePath* virtual_path); + + // Returns the virtual root path that looks like /<mount_name>. + FilePath CreateVirtualRootPath(const std::string& mount_name) const; + + private: + friend class base::RefCountedThreadSafe<ExternalMountPoints>; + + // Represents each file system instance (defined in the .cc). + class Instance; + + typedef std::map<std::string, Instance*> NameToInstance; + + // Reverse map from registered path to its corresponding mount name. + typedef std::map<FilePath, std::string> PathToName; + + // Use |GetSystemInstance| of |CreateRefCounted| to get an instance. + ExternalMountPoints(); + virtual ~ExternalMountPoints(); + + // Performs sanity checks on the new mount point. + // Checks the following: + // - there is no registered mount point with mount_name + // - path does not contain a reference to a parent + // - path is absolute + // - path does not overlap with an existing mount point path. + // + // |lock_| should be taken before calling this method. + bool ValidateNewMountPoint(const std::string& mount_name, + const FilePath& path); + + // This lock needs to be obtained when accessing the instance_map_. + mutable base::Lock lock_; + + NameToInstance instance_map_; + PathToName path_to_name_map_; + + DISALLOW_COPY_AND_ASSIGN(ExternalMountPoints); +}; + +// Registers a scoped external filesystem which gets revoked when it scopes out. +class WEBKIT_STORAGE_EXPORT ScopedExternalFileSystem { + public: + ScopedExternalFileSystem(const std::string& mount_name, + FileSystemType type, + const FilePath& path); + ~ScopedExternalFileSystem(); + + FilePath GetVirtualRootPath() const; + + private: + const std::string mount_name_; +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_EXTERNAL_MOUNT_POINTS_H_ + diff --git a/webkit/fileapi/external_mount_points_unittest.cc b/webkit/fileapi/external_mount_points_unittest.cc new file mode 100644 index 0000000..379d146 --- /dev/null +++ b/webkit/fileapi/external_mount_points_unittest.cc @@ -0,0 +1,227 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/external_mount_points.h" + +#include <string> + +#include "base/file_path.h" +#include "testing/gtest/include/gtest/gtest.h" + +#define FPL FILE_PATH_LITERAL + +#if defined(FILE_PATH_USES_DRIVE_LETTERS) +#define DRIVE FPL("C:") +#else +#define DRIVE +#endif + +namespace { + +TEST(ExternalMountPointsTest, AddMountPoint) { + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + struct TestCase { + // The mount point's name. + const char* const name; + // The mount point's path. + const FilePath::CharType* const path; + // Whether the mount point registration should succeed. + bool success; + // Path returned by GetRegisteredPath. NULL if the method is expected to + // fail. + const FilePath::CharType* const registered_path; + }; + + const TestCase kTestCases[] = { + // Valid mount point. + { "test", DRIVE FPL("/foo/test"), true, DRIVE FPL("/foo/test") }, + // Valid mount point with only one path component. + { "bbb", DRIVE FPL("/bbb"), true, DRIVE FPL("/bbb") }, + // Existing mount point path is substring of the mount points path. + { "test11", DRIVE FPL("/foo/test11"), true, DRIVE FPL("/foo/test11") }, + // Path substring of an existing path. + { "test1", DRIVE FPL("/foo/test1"), true, DRIVE FPL("/foo/test1") }, + // Empty mount point name and path. + { "", DRIVE FPL(""), false, NULL }, + // Empty mount point name. + { "", DRIVE FPL("/ddd"), false, NULL }, + // Empty mount point path. + { "empty_path", FPL(""), true, FPL("") }, + // Name different from path's base name. + { "not_base_name", DRIVE FPL("/x/y/z"), true, DRIVE FPL("/x/y/z") }, + // References parent. + { "invalid", DRIVE FPL("../foo/invalid"), false, NULL }, + // Relative path. + { "relative", DRIVE FPL("foo/relative"), false, NULL }, + // Existing mount point path. + { "path_exists", DRIVE FPL("/foo/test"), false, NULL }, + // Mount point with the same name exists. + { "test", DRIVE FPL("/foo/a/test_name_exists"), false, + DRIVE FPL("/foo/test") }, + // Child of an existing mount point. + { "a1", DRIVE FPL("/foo/test/a"), false, NULL }, + // Parent of an existing mount point. + { "foo1", DRIVE FPL("/foo"), false, NULL }, + // Bit bigger depth. + { "g", DRIVE FPL("/foo/a/b/c/d/e/f/g"), true, + DRIVE FPL("/foo/a/b/c/d/e/f/g") }, + // Sibling mount point (with similar name) exists. + { "ff", DRIVE FPL("/foo/a/b/c/d/e/ff"), true, + DRIVE FPL("/foo/a/b/c/d/e/ff") }, + // Lexicographically last among existing mount points. + { "yyy", DRIVE FPL("/zzz/yyy"), true, DRIVE FPL("/zzz/yyy") }, + // Parent of the lexicographically last mount point. + { "zzz1", DRIVE FPL("/zzz"), false, NULL }, + // Child of the lexicographically last mount point. + { "xxx1", DRIVE FPL("/zzz/yyy/xxx"), false, NULL }, + // Lexicographically first among existing mount points. + { "b", DRIVE FPL("/a/b"), true, DRIVE FPL("/a/b") }, + // Parent of lexicographically first mount point. + { "a2", DRIVE FPL("/a"), false, NULL }, + // Child of lexicographically last mount point. + { "c1", DRIVE FPL("/a/b/c"), false, NULL }, + // Parent to all of the mount points. + { "root", DRIVE FPL("/"), false, NULL }, + // Path contains .. component. + { "funky", DRIVE FPL("/tt/fun/../funky"), false, NULL }, + // Windows separators. +#if defined(FILE_PATH_USES_WIN_SEPARATORS) + { "win", DRIVE FPL("\\try\\separators\\win"), true, + DRIVE FPL("\\try\\separators\\win") }, + { "win1", DRIVE FPL("\\try/separators\\win1"), true, + DRIVE FPL("\\try/separators\\win1") }, + { "win2", DRIVE FPL("\\try/separators\\win"), false, NULL }, +#else + { "win", DRIVE FPL("\\separators\\win"), false, NULL }, + { "win1", DRIVE FPL("\\try/separators\\win1"), false, NULL }, +#endif + // Win separators, but relative path. + { "win2", DRIVE FPL("try\\separators\\win2"), false, NULL }, + }; + + // Test adding mount points. + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + EXPECT_EQ(kTestCases[i].success, + mount_points->RegisterFileSystem( + kTestCases[i].name, + fileapi::kFileSystemTypeNativeLocal, + FilePath(kTestCases[i].path))) + << "Adding mount point: " << kTestCases[i].name << " with path " + << kTestCases[i].path; + } + + // Test that final mount point presence state is as expected. + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + FilePath found_path; + EXPECT_EQ(kTestCases[i].registered_path != NULL, + mount_points->GetRegisteredPath(kTestCases[i].name, &found_path)) + << "Test case: " << i; + + if (kTestCases[i].registered_path) { + FilePath expected_path(kTestCases[i].registered_path); + EXPECT_EQ(expected_path.NormalizePathSeparators(), found_path); + } + } +} + +TEST(ExternalMountPointsTest, GetVirtualPath) { + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + mount_points->RegisterFileSystem("c", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/a/b/c"))); + // Note that "/a/b/c" < "/a/b/c(1)" < "/a/b/c/". + mount_points->RegisterFileSystem("c(1)", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/a/b/c(1)"))); + mount_points->RegisterFileSystem("x", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/z/y/x"))); + mount_points->RegisterFileSystem("o", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/m/n/o"))); + // A mount point whose name does not match its path base name. + mount_points->RegisterFileSystem("mount", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/root/foo"))); + // A mount point with an empty path. + mount_points->RegisterFileSystem("empty_path", + fileapi::kFileSystemTypeNativeLocal, + FilePath(FPL(""))); + + struct TestCase { + const FilePath::CharType* const local_path; + bool success; + const FilePath::CharType* const virtual_path; + }; + + const TestCase kTestCases[] = { + // Empty path. + { FPL(""), false, FPL("") }, + // No registered mount point (but is parent to a mount point). + { DRIVE FPL("/a/b"), false, FPL("") }, + // No registered mount point (but is parent to a mount point). + { DRIVE FPL("/z/y"), false, FPL("") }, + // No registered mount point (but is parent to a mount point). + { DRIVE FPL("/m/n"), false, FPL("") }, + // No registered mount point. + { DRIVE FPL("/foo/mount"), false, FPL("") }, + // An existing mount point path is substring. + { DRIVE FPL("/a/b/c1"), false, FPL("") }, + // No leading /. + { DRIVE FPL("a/b/c"), false, FPL("") }, + // Sibling to a root path. + { DRIVE FPL("/a/b/d/e"), false, FPL("") }, + // Sibling to a root path. + { DRIVE FPL("/z/y/v/u"), false, FPL("") }, + // Sibling to a root path. + { DRIVE FPL("/m/n/p/q"), false, FPL("") }, + // Mount point root path. + { DRIVE FPL("/a/b/c"), true, FPL("c") }, + // Mount point root path. + { DRIVE FPL("/z/y/x"), true, FPL("x") }, + // Mount point root path. + { DRIVE FPL("/m/n/o"), true, FPL("o") }, + // Mount point child path. + { DRIVE FPL("/a/b/c/d/e"), true, FPL("c/d/e") }, + // Mount point child path. + { DRIVE FPL("/z/y/x/v/u"), true, FPL("x/v/u") }, + // Mount point child path. + { DRIVE FPL("/m/n/o/p/q"), true, FPL("o/p/q") }, + // Name doesn't match mount point path base name. + { DRIVE FPL("/root/foo/a/b/c"), true, FPL("mount/a/b/c") }, + { DRIVE FPL("/root/foo"), true, FPL("mount") }, + // Mount point contains character whose ASCII code is smaller than file path + // separator's. + { DRIVE FPL("/a/b/c(1)/d/e"), true, FPL("c(1)/d/e") }, +#if defined(FILE_PATH_USES_WIN_SEPARATORS) + // Path with win separators mixed in. + { DRIVE FPL("/a\\b\\c/d"), true, FPL("c/d") }, +#endif + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + // Initialize virtual path with a value. + FilePath virtual_path(DRIVE FPL("/mount")); + FilePath local_path(kTestCases[i].local_path); + EXPECT_EQ(kTestCases[i].success, + mount_points->GetVirtualPath(local_path, &virtual_path)) + << "Resolving " << kTestCases[i].local_path; + + // There are no guarantees for |virtual_path| value if |GetVirtualPath| + // fails. + if (!kTestCases[i].success) + continue; + + FilePath expected_virtual_path(kTestCases[i].virtual_path); + EXPECT_EQ(expected_virtual_path.NormalizePathSeparators(), virtual_path) + << "Resolving " << kTestCases[i].local_path; + } +} + +} // namespace + diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc index 93a0aa7..bf285ea 100644 --- a/webkit/fileapi/file_system_context.cc +++ b/webkit/fileapi/file_system_context.cc @@ -8,6 +8,7 @@ #include "base/stl_util.h" #include "base/single_thread_task_runner.h" #include "googleurl/src/gurl.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_system_file_util.h" #include "webkit/fileapi/file_system_operation.h" #include "webkit/fileapi/file_system_options.h" @@ -75,7 +76,11 @@ FileSystemContext::FileSystemContext( } #if defined(OS_CHROMEOS) external_provider_.reset( - new chromeos::CrosMountPointProvider(special_storage_policy)); + new chromeos::CrosMountPointProvider( + special_storage_policy, + // TODO(tbarzic): Switch this to |external_mount_points_|. + fileapi::ExternalMountPoints::GetSystemInstance(), + fileapi::ExternalMountPoints::GetSystemInstance())); #endif } @@ -243,6 +248,7 @@ FileSystemOperation* FileSystemContext::CreateFileSystemOperation( *error_code = base::PLATFORM_FILE_ERROR_INVALID_URL; return NULL; } + FileSystemMountPointProvider* mount_point_provider = GetMountPointProvider(url.type()); if (!mount_point_provider) { diff --git a/webkit/fileapi/file_system_mount_point_provider.h b/webkit/fileapi/file_system_mount_point_provider.h index 4f0950e..24c00fe 100644 --- a/webkit/fileapi/file_system_mount_point_provider.h +++ b/webkit/fileapi/file_system_mount_point_provider.h @@ -141,14 +141,14 @@ class ExternalFileSystemMountPointProvider virtual void RevokeAccessForExtension( const std::string& extension_id) = 0; // Checks if a given |mount_point| already exists. - virtual bool HasMountPoint(const FilePath& mount_point) = 0; + virtual bool HasMountPoint(const FilePath& mount_point) const = 0; // Adds a new local mount point. - virtual void AddLocalMountPoint(const FilePath& mount_point) = 0; + virtual bool AddLocalMountPoint(const FilePath& mount_point) = 0; // Adds a new local mount point that will be accessible only by extensions // that have been granted full acess for all external file systems. - virtual void AddRestrictedLocalMountPoint(const FilePath& mount_point) = 0; + virtual bool AddRestrictedLocalMountPoint(const FilePath& mount_point) = 0; // Adds a new remote mount point. - virtual void AddRemoteMountPoint( + virtual bool AddRemoteMountPoint( const FilePath& mount_point, RemoteFileSystemProxyInterface* remote_proxy) = 0; // Removes a mount point. diff --git a/webkit/fileapi/file_system_url.cc b/webkit/fileapi/file_system_url.cc index 9e2fdf5..b69eda1 100644 --- a/webkit/fileapi/file_system_url.cc +++ b/webkit/fileapi/file_system_url.cc @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/string_util.h" #include "net/base/escape.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/fileapi/file_system_util.h" #include "webkit/fileapi/isolated_context.h" @@ -158,7 +159,11 @@ void FileSystemURL::MayCrackIsolatedPath() { if (is_valid_ && IsolatedContext::IsIsolatedType(type_)) { // If the type is isolated, crack the path further to get the 'real' // filesystem type and path. - is_valid_ = IsolatedContext::GetInstance()->CrackIsolatedPath( + is_valid_ = ExternalMountPoints::GetSystemInstance()->CrackVirtualPath( + virtual_path_, &filesystem_id_, &type_, &path_); + if (is_valid_) + return; + is_valid_ = IsolatedContext::GetInstance()->CrackVirtualPath( virtual_path_, &filesystem_id_, &type_, &path_); } } diff --git a/webkit/fileapi/file_system_url_unittest.cc b/webkit/fileapi/file_system_url_unittest.cc index c6608cc..c1c01a3 100644 --- a/webkit/fileapi/file_system_url_unittest.cc +++ b/webkit/fileapi/file_system_url_unittest.cc @@ -7,6 +7,7 @@ #include "base/file_path.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/fileapi/file_system_util.h" #include "webkit/fileapi/isolated_context.h" @@ -14,6 +15,12 @@ #define FPL FILE_PATH_LITERAL +#if defined(FILE_PATH_USES_DRIVE_LETTERS) +#define DRIVE FPL("C:") +#else +#define DRIVE FPL("/a/") +#endif + namespace fileapi { namespace { @@ -214,8 +221,10 @@ TEST(FileSystemURLTest, DebugString) { NormalizedUTF8Path(kPath), kURL1.DebugString()); - const FilePath kRoot(FPL("root")); - ScopedExternalFileSystem scoped_fs("foo", kFileSystemTypeNativeLocal, kRoot); + const FilePath kRoot(DRIVE FPL("/root")); + ScopedExternalFileSystem scoped_fs("foo", + kFileSystemTypeNativeLocal, + kRoot.NormalizePathSeparators()); const FileSystemURL kURL2(kOrigin, kFileSystemTypeExternal, scoped_fs.GetVirtualRootPath().Append(kPath)); EXPECT_EQ("filesystem:http://example.com/external/" + diff --git a/webkit/fileapi/isolated_context.cc b/webkit/fileapi/isolated_context.cc index 057d508..1433e72 100644 --- a/webkit/fileapi/isolated_context.cc +++ b/webkit/fileapi/isolated_context.cc @@ -42,7 +42,7 @@ FilePath::StringType GetRegisterNameForPath(const FilePath& path) { bool IsSinglePathIsolatedFileSystem(FileSystemType type) { switch (type) { // As of writing dragged file system is the only filesystem - // which could have multiple toplevel paths. + // which could have multiple top-level paths. case kFileSystemTypeDragged: return false; @@ -57,15 +57,10 @@ bool IsSinglePathIsolatedFileSystem(FileSystemType type) { return true; } -} // namespace - static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = LAZY_INSTANCE_INITIALIZER; -IsolatedContext::FileInfo::FileInfo() {} -IsolatedContext::FileInfo::FileInfo( - const std::string& name, const FilePath& path) - : name(name), path(path) {} +} // namespace IsolatedContext::FileInfoSet::FileInfoSet() {} IsolatedContext::FileInfoSet::~FileInfoSet() {} @@ -78,7 +73,8 @@ bool IsolatedContext::FileInfoSet::AddPath( FilePath::StringType name = GetRegisterNameForPath(path); std::string utf8name = FilePath(name).AsUTF8Unsafe(); FilePath normalized_path = path.NormalizePathSeparators(); - bool inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; + bool inserted = + fileset_.insert(MountPointInfo(utf8name, normalized_path)).second; if (!inserted) { int suffix = 1; std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe(); @@ -87,7 +83,8 @@ bool IsolatedContext::FileInfoSet::AddPath( utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++); if (!ext.empty()) utf8name.append(ext); - inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; + inserted = + fileset_.insert(MountPointInfo(utf8name, normalized_path)).second; } } if (registered_name) @@ -100,34 +97,29 @@ bool IsolatedContext::FileInfoSet::AddPathWithName( // The given path should not contain any '..' and should be absolute. if (path.ReferencesParent() || !path.IsAbsolute()) return false; - return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; + return fileset_.insert( + MountPointInfo(name, path.NormalizePathSeparators())).second; } //-------------------------------------------------------------------------- class IsolatedContext::Instance { public: - typedef FileSystemType MountType; - // For a single-path isolated file system, which could be registered by // IsolatedContext::RegisterFileSystemForPath(). // Most of isolated file system contexts should be of this type. - Instance(FileSystemType type, const FileInfo& file_info); + Instance(FileSystemType type, const MountPointInfo& file_info); // For a multi-paths isolated file system. As of writing only file system // type which could have multi-paths is Dragged file system, and // could be registered by IsolatedContext::RegisterDraggedFileSystem(). - Instance(FileSystemType type, const std::set<FileInfo>& files); - - // For a single-path external file system. - Instance(FileSystemType type, const FilePath& path); + Instance(FileSystemType type, const std::set<MountPointInfo>& files); ~Instance(); - MountType mount_type() const { return mount_type_; } FileSystemType type() const { return type_; } - const FileInfo& file_info() const { return file_info_; } - const std::set<FileInfo>& files() const { return files_; } + const MountPointInfo& file_info() const { return file_info_; } + const std::set<MountPointInfo>& files() const { return files_; } int ref_counts() const { return ref_counts_; } void AddRef() { ++ref_counts_; } @@ -139,14 +131,13 @@ class IsolatedContext::Instance { bool IsSinglePathInstance() const; private: - const MountType mount_type_; const FileSystemType type_; // For single-path instance. - const FileInfo file_info_; + const MountPointInfo file_info_; // For multiple-path instance (e.g. dragged file system). - const std::set<FileInfo> files_; + const std::set<MountPointInfo> files_; // Reference counts. Note that an isolated filesystem is created with ref==0 // and will get deleted when the ref count reaches <=0. @@ -156,32 +147,21 @@ class IsolatedContext::Instance { }; IsolatedContext::Instance::Instance(FileSystemType type, - const FileInfo& file_info) - : mount_type_(kFileSystemTypeIsolated), - type_(type), + const MountPointInfo& file_info) + : type_(type), file_info_(file_info), ref_counts_(0) { DCHECK(IsSinglePathIsolatedFileSystem(type_)); } IsolatedContext::Instance::Instance(FileSystemType type, - const std::set<FileInfo>& files) - : mount_type_(kFileSystemTypeIsolated), - type_(type), + const std::set<MountPointInfo>& files) + : type_(type), files_(files), ref_counts_(0) { DCHECK(!IsSinglePathIsolatedFileSystem(type_)); } -IsolatedContext::Instance::Instance(FileSystemType type, - const FilePath& path) - : mount_type_(kFileSystemTypeExternal), - type_(type), - file_info_(FileInfo("", path)), - ref_counts_(0) { - DCHECK(IsSinglePathIsolatedFileSystem(type_)); -} - IsolatedContext::Instance::~Instance() {} bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, @@ -190,8 +170,8 @@ bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, *path = file_info_.path; return file_info_.name == name; } - std::set<FileInfo>::const_iterator found = files_.find( - FileInfo(name, FilePath())); + std::set<MountPointInfo>::const_iterator found = files_.find( + MountPointInfo(name, FilePath())); if (found == files_.end()) return false; *path = found->path; @@ -240,83 +220,28 @@ std::string IsolatedContext::RegisterFileSystemForPath( base::AutoLock locker(lock_); std::string filesystem_id = GetNewFileSystemId(); - instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); + instance_map_[filesystem_id] = new Instance(type, MountPointInfo(name, path)); path_to_id_map_[path].insert(filesystem_id); return filesystem_id; } -bool IsolatedContext::RegisterExternalFileSystem(const std::string& mount_name, - FileSystemType type, - const FilePath& path) { - base::AutoLock locker(lock_); - IDToInstance::iterator found = instance_map_.find(mount_name); - if (found != instance_map_.end()) - return false; - instance_map_[mount_name] = new Instance(type, path); - path_to_id_map_[path].insert(mount_name); - return true; -} - -std::vector<IsolatedContext::FileInfo> -IsolatedContext::GetExternalMountPoints() const { - base::AutoLock locker(lock_); - std::vector<FileInfo> files; - for (IDToInstance::const_iterator iter = instance_map_.begin(); - iter != instance_map_.end(); - ++iter) { - if (iter->second->mount_type() == kFileSystemTypeExternal) - files.push_back(FileInfo(iter->first, iter->second->file_info().path)); - } - return files; -} - bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { base::AutoLock locker(lock_); return UnregisterFileSystem(filesystem_id); } -void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { - base::AutoLock locker(lock_); - FilePath path(path_in.NormalizePathSeparators()); - PathToID::iterator ids_iter = path_to_id_map_.find(path); - if (ids_iter == path_to_id_map_.end()) - return; - std::set<std::string>& ids = ids_iter->second; - for (std::set<std::string>::iterator iter = ids.begin(); - iter != ids.end(); ++iter) { - IDToInstance::iterator found = instance_map_.find(*iter); - if (found != instance_map_.end()) { - delete found->second; - instance_map_.erase(found); - } - } - path_to_id_map_.erase(ids_iter); -} - -void IsolatedContext::AddReference(const std::string& filesystem_id) { - base::AutoLock locker(lock_); - DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); - instance_map_[filesystem_id]->AddRef(); -} - -void IsolatedContext::RemoveReference(const std::string& filesystem_id) { +bool IsolatedContext::GetRegisteredPath( + const std::string& filesystem_id, FilePath* path) const { + DCHECK(path); base::AutoLock locker(lock_); - // This could get called for non-existent filesystem if it has been - // already deleted by RevokeFileSystemByPath. - IDToInstance::iterator found = instance_map_.find(filesystem_id); - if (found == instance_map_.end()) - return; - Instance* instance = found->second; - DCHECK_GT(instance->ref_counts(), 0); - instance->RemoveRef(); - if (instance->ref_counts() == 0 && - instance->mount_type() != kFileSystemTypeExternal) { - bool deleted = UnregisterFileSystem(filesystem_id); - DCHECK(deleted); - } + IDToInstance::const_iterator found = instance_map_.find(filesystem_id); + if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) + return false; + *path = found->second->file_info().path; + return true; } -bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, +bool IsolatedContext::CrackVirtualPath(const FilePath& virtual_path, std::string* id_or_name, FileSystemType* type, FilePath* path) const { @@ -348,26 +273,17 @@ bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, const Instance* instance = found_instance->second; if (type) *type = instance->type(); - switch (instance->mount_type()) { - case kFileSystemTypeIsolated: { - if (component_iter == components.end()) { - // The virtual root case. - path->clear(); - return true; - } - // *component_iter should be a name of the registered path. - std::string name = FilePath(*component_iter++).AsUTF8Unsafe(); - if (!instance->ResolvePathForName(name, &cracked_path)) - return false; - break; - } - case kFileSystemTypeExternal: - cracked_path = instance->file_info().path; - break; - default: - NOTREACHED(); - break; + + if (component_iter == components.end()) { + // The virtual root case. + path->clear(); + return true; } + + // *component_iter should be a name of the registered path. + std::string name = FilePath(*component_iter++).AsUTF8Unsafe(); + if (!instance->ResolvePathForName(name, &cracked_path)) + return false; } for (; component_iter != components.end(); ++component_iter) @@ -376,8 +292,49 @@ bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, return true; } +void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { + base::AutoLock locker(lock_); + FilePath path(path_in.NormalizePathSeparators()); + PathToID::iterator ids_iter = path_to_id_map_.find(path); + if (ids_iter == path_to_id_map_.end()) + return; + std::set<std::string>& ids = ids_iter->second; + for (std::set<std::string>::iterator iter = ids.begin(); + iter != ids.end(); ++iter) { + IDToInstance::iterator found = instance_map_.find(*iter); + if (found != instance_map_.end()) { + delete found->second; + instance_map_.erase(found); + } + } + path_to_id_map_.erase(ids_iter); +} + +void IsolatedContext::AddReference(const std::string& filesystem_id) { + base::AutoLock locker(lock_); + DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); + instance_map_[filesystem_id]->AddRef(); +} + +void IsolatedContext::RemoveReference(const std::string& filesystem_id) { + base::AutoLock locker(lock_); + // This could get called for non-existent filesystem if it has been + // already deleted by RevokeFileSystemByPath. + IDToInstance::iterator found = instance_map_.find(filesystem_id); + if (found == instance_map_.end()) + return; + Instance* instance = found->second; + DCHECK_GT(instance->ref_counts(), 0); + instance->RemoveRef(); + if (instance->ref_counts() == 0) { + bool deleted = UnregisterFileSystem(filesystem_id); + DCHECK(deleted); + } +} + bool IsolatedContext::GetDraggedFileInfo( - const std::string& filesystem_id, std::vector<FileInfo>* files) const { + const std::string& filesystem_id, + std::vector<MountPointInfo>* files) const { DCHECK(files); base::AutoLock locker(lock_); IDToInstance::const_iterator found = instance_map_.find(filesystem_id); @@ -389,17 +346,6 @@ bool IsolatedContext::GetDraggedFileInfo( return true; } -bool IsolatedContext::GetRegisteredPath( - const std::string& filesystem_id, FilePath* path) const { - DCHECK(path); - base::AutoLock locker(lock_); - IDToInstance::const_iterator found = instance_map_.find(filesystem_id); - if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) - return false; - *path = found->second->file_info().path; - return true; -} - FilePath IsolatedContext::CreateVirtualRootPath( const std::string& filesystem_id) const { return FilePath().AppendASCII(filesystem_id); @@ -444,21 +390,4 @@ std::string IsolatedContext::GetNewFileSystemId() const { return id; } -ScopedExternalFileSystem::ScopedExternalFileSystem( - const std::string& mount_name, - FileSystemType type, - const FilePath& path) - : mount_name_(mount_name) { - IsolatedContext::GetInstance()->RegisterExternalFileSystem( - mount_name, type, path); -} - -FilePath ScopedExternalFileSystem::GetVirtualRootPath() const { - return IsolatedContext::GetInstance()->CreateVirtualRootPath(mount_name_); -} - -ScopedExternalFileSystem::~ScopedExternalFileSystem() { - IsolatedContext::GetInstance()->RevokeFileSystem(mount_name_); -} - } // namespace fileapi diff --git a/webkit/fileapi/isolated_context.h b/webkit/fileapi/isolated_context.h index e0cea7c..63cab56 100644 --- a/webkit/fileapi/isolated_context.h +++ b/webkit/fileapi/isolated_context.h @@ -16,60 +16,25 @@ #include "base/memory/singleton.h" #include "base/synchronization/lock.h" #include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/mount_points.h" #include "webkit/storage/webkit_storage_export.h" namespace fileapi { -// Manages isolated filesystem namespaces. -// This context class is a singleton and access to the context is -// thread-safe (protected with a lock). -// -// There are two types of filesystems managed by this context: -// isolated and external. -// The former is transient while the latter is persistent. -// -// * Transient isolated file systems have no name and are identified by -// string 'filesystem ID', which usually just looks like random value. -// This type of filesystem can be created on the fly and may go away -// when it has no references from renderers. -// Files in an isolated filesystem are registered with corresponding names -// and identified by a filesystem URL like: +// Manages isolated filesystem mount points which have no well-known names +// and are identified by a string 'filesystem ID', which usually just looks +// like random value. +// This type of filesystem can be created on the fly and may go away when it has +// no references from renderers. +// Files in an isolated filesystem are registered with corresponding names and +// identified by a filesystem URL like: // // filesystem:<origin>/isolated/<filesystem_id>/<name>/relative/path // -// * Persistent external file systems are identified by 'mount name' -// and are persisted until RevokeFileSystem is called. -// Files in an external filesystem are identified by a filesystem URL like: -// -// filesystem:<origin>/external/<mount_name>/relative/path -// -// A filesystem instance is represented by IsolatedContext::Instance, and -// managed as a map instance_map_ which maps from filesystem ID (or name) -// to the instance. -// // Some methods of this class are virtual just for mocking. // -// TODO(kinuko): This should have a better name since this handles both -// isolated and external file systems. -// -class WEBKIT_STORAGE_EXPORT IsolatedContext { +class WEBKIT_STORAGE_EXPORT IsolatedContext : public MountPoints { public: - struct WEBKIT_STORAGE_EXPORT FileInfo { - FileInfo(); - FileInfo(const std::string& name, const FilePath& path); - - // The name to be used to register the file. The registered file can - // be referred by a virtual path /<filesystem_id>/<name>. - // The name should NOT contain a path separator '/'. - std::string name; - - // The path of the file. - FilePath path; - - // For STL operation. - bool operator<(const FileInfo& that) const { return name < that.name; } - }; - class WEBKIT_STORAGE_EXPORT FileInfoSet { public: FileInfoSet(); @@ -86,10 +51,10 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext { // is not valid and could not be added. bool AddPathWithName(const FilePath& path, const std::string& name); - const std::set<FileInfo>& fileset() const { return fileset_; } + const std::set<MountPointInfo>& fileset() const { return fileset_; } private: - std::set<FileInfo> fileset_; + std::set<MountPointInfo> fileset_; }; // The instance is lazily created per browser process. @@ -133,30 +98,14 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext { const FilePath& path, std::string* register_name); - // Registers a new named external filesystem. - // The |path| is registered as the root path of the mount point which - // is identified by a URL "filesystem:.../external/mount_name". - // - // For example, if the path "/media/removable" is registered with - // the mount_name "removable", a filesystem URL like - // "filesystem:.../external/removable/a/b" will be resolved as - // "/media/removable/a/b". - // - // The |mount_name| should NOT contain a path separator '/'. - // Returns false if the given name is already registered. - // - // An external file system registered by this method can be revoked - // by calling RevokeFileSystem with |mount_name|. - bool RegisterExternalFileSystem(const std::string& mount_name, - FileSystemType type, - const FilePath& path); - - // Returns a set of FilePath (of <mount_name, path>) registered as external. - std::vector<FileInfo> GetExternalMountPoints() const; - - // Revokes the filesystem |filesystem_id|. - // Returns false if the |filesystem_id| is not (no longer) registered. - bool RevokeFileSystem(const std::string& filesystem_id); + // MountPoints override. + virtual bool RevokeFileSystem(const std::string& filesystem_id) OVERRIDE; + virtual bool GetRegisteredPath(const std::string& filesystem_id, + FilePath* path) const OVERRIDE; + virtual bool CrackVirtualPath(const FilePath& virtual_path, + std::string* filesystem_id, + FileSystemType* type, + FilePath* path) const OVERRIDE; // Revokes all filesystem(s) registered for the given path. // This is assumed to be called when the registered path becomes @@ -173,41 +122,17 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext { // Removes a reference to a filesystem specified by the given filesystem_id. // If the reference count reaches 0 the isolated context gets destroyed. - // It is ok to call this on the filesystem that has been already deleted + // It is OK to call this on the filesystem that has been already deleted // (e.g. by RevokeFileSystemByPath). void RemoveReference(const std::string& filesystem_id); - // Cracks the given |virtual_path| (which is the path part of a filesystem URL - // without '/isolated' or '/external' prefix) and populates the - // |id_or_name|, |type|, and |path| if the <id_or_name> part embedded in - // the |virtual_path| (i.e. the first component of the |virtual_path|) is a - // valid registered filesystem ID or mount name for an isolated or external - // filesystem. - // - // Returns false if the given virtual_path or the cracked id_or_name - // is not valid. - // - // Note that |path| is set to empty paths if the filesystem type is isolated - // and |virtual_path| has no <relative_path> part (i.e. pointing to the - // virtual root). - bool CrackIsolatedPath(const FilePath& virtual_path, - std::string* id_or_name, - FileSystemType* type, - FilePath* path) const; - - // Returns a set of dragged FileInfo's registered for the |filesystem_id|. + // Returns a set of dragged MountPointInfos registered for the + // |filesystem_id|. // The filesystem_id must be pointing to a dragged file system // (i.e. must be the one registered by RegisterDraggedFileSystem). // Returns false if the |filesystem_id| is not valid. bool GetDraggedFileInfo(const std::string& filesystem_id, - std::vector<FileInfo>* files) const; - - // Returns the file path registered for the |filesystem_id|. - // The filesystem_id must NOT be pointing to a dragged file system - // (i.e. must be the one registered by RegisterFileSystemForPath). - // Returns false if the |filesystem_id| is not valid. - bool GetRegisteredPath(const std::string& filesystem_id, - FilePath* path) const; + std::vector<MountPointInfo>* files) const; // Returns the virtual root path that looks like /<filesystem_id>. FilePath CreateVirtualRootPath(const std::string& filesystem_id) const; @@ -225,7 +150,7 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext { // Obtain an instance of this class via GetInstance(). IsolatedContext(); - ~IsolatedContext(); + virtual ~IsolatedContext(); // Unregisters a file system of given |filesystem_id|. Must be called with // lock_ held. Returns true if the file system is unregistered. @@ -243,20 +168,6 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext { DISALLOW_COPY_AND_ASSIGN(IsolatedContext); }; -// Registers a scoped external filesystem which gets revoked when it scopes out. -class WEBKIT_STORAGE_EXPORT ScopedExternalFileSystem { - public: - ScopedExternalFileSystem(const std::string& mount_name, - FileSystemType type, - const FilePath& path); - ~ScopedExternalFileSystem(); - - FilePath GetVirtualRootPath() const; - - private: - const std::string mount_name_; -}; - } // namespace fileapi #endif // WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ diff --git a/webkit/fileapi/isolated_context_unittest.cc b/webkit/fileapi/isolated_context_unittest.cc index 78efd16..bf36df9 100644 --- a/webkit/fileapi/isolated_context_unittest.cc +++ b/webkit/fileapi/isolated_context_unittest.cc @@ -19,7 +19,7 @@ namespace fileapi { -typedef IsolatedContext::FileInfo FileInfo; +typedef IsolatedContext::MountPointInfo FileInfo; namespace { @@ -95,7 +95,7 @@ TEST_F(IsolatedContextTest, RegisterAndRevokeTest) { std::string cracked_id; FilePath cracked_path; FileSystemType cracked_type; - ASSERT_TRUE(isolated_context()->CrackIsolatedPath( + ASSERT_TRUE(isolated_context()->CrackVirtualPath( virtual_path, &cracked_id, &cracked_type, &cracked_path)); ASSERT_EQ(kTestPaths[i].NormalizePathSeparators().value(), cracked_path.value()); @@ -191,11 +191,11 @@ TEST_F(IsolatedContextTest, CrackWithRelativePaths) { FilePath cracked_path; FileSystemType cracked_type; if (!relatives[j].valid) { - ASSERT_FALSE(isolated_context()->CrackIsolatedPath( + ASSERT_FALSE(isolated_context()->CrackVirtualPath( virtual_path, &cracked_id, &cracked_type, &cracked_path)); continue; } - ASSERT_TRUE(isolated_context()->CrackIsolatedPath( + ASSERT_TRUE(isolated_context()->CrackVirtualPath( virtual_path, &cracked_id, &cracked_type, &cracked_path)); ASSERT_EQ(kTestPaths[i].Append(relatives[j].path) .NormalizePathSeparators().value(), @@ -214,7 +214,7 @@ TEST_F(IsolatedContextTest, TestWithVirtualRoot) { // as "/" of the isolated filesystem is a pure virtual directory // that has no corresponding platform directory. FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_); - ASSERT_TRUE(isolated_context()->CrackIsolatedPath( + ASSERT_TRUE(isolated_context()->CrackVirtualPath( virtual_path, &cracked_id, NULL, &cracked_path)); ASSERT_EQ(FPL(""), cracked_path.value()); ASSERT_EQ(id_, cracked_id); @@ -223,7 +223,7 @@ TEST_F(IsolatedContextTest, TestWithVirtualRoot) { // included in the kTestPaths). virtual_path = isolated_context()->CreateVirtualRootPath( id_).AppendASCII("foo"); - ASSERT_FALSE(isolated_context()->CrackIsolatedPath( + ASSERT_FALSE(isolated_context()->CrackVirtualPath( virtual_path, &cracked_id, NULL, &cracked_path)); } diff --git a/webkit/fileapi/isolated_file_util.cc b/webkit/fileapi/isolated_file_util.cc index cf3f0ce..d50549e 100644 --- a/webkit/fileapi/isolated_file_util.cc +++ b/webkit/fileapi/isolated_file_util.cc @@ -19,7 +19,7 @@ using base::PlatformFileInfo; namespace fileapi { -typedef IsolatedContext::FileInfo FileInfo; +typedef IsolatedContext::MountPointInfo FileInfo; namespace { diff --git a/webkit/fileapi/mount_points.cc b/webkit/fileapi/mount_points.cc new file mode 100644 index 0000000..d754b25 --- /dev/null +++ b/webkit/fileapi/mount_points.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/mount_points.h" + +namespace fileapi { + +MountPoints::MountPointInfo::MountPointInfo() {} +MountPoints::MountPointInfo::MountPointInfo( + const std::string& name, const FilePath& path) + : name(name), path(path) {} + +} // namespace fileapi + diff --git a/webkit/fileapi/mount_points.h b/webkit/fileapi/mount_points.h new file mode 100644 index 0000000..0cfb57b --- /dev/null +++ b/webkit/fileapi/mount_points.h @@ -0,0 +1,77 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MOUNT_POINTS_H_ +#define WEBKIT_FILEAPI_MOUNT_POINTS_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/file_path.h" +#include "webkit/fileapi/file_system_util.h" +#include "webkit/storage/webkit_storage_export.h" + +class GURL; + +namespace fileapi { + +// Represents a set of mount points for File API. +class WEBKIT_STORAGE_EXPORT MountPoints { + public: + struct WEBKIT_STORAGE_EXPORT MountPointInfo { + MountPointInfo(); + MountPointInfo(const std::string& name, const FilePath& path); + + // The name to be used to register the path. The registered file can + // be referred by a virtual path /<filesystem_id>/<name>. + // The name should NOT contain a path separator '/'. + std::string name; + + // The path of the file. + FilePath path; + + // For STL operation. + bool operator<(const MountPointInfo& that) const { + return name < that.name; + } + }; + + MountPoints() {} + virtual ~MountPoints() {} + + // Revokes a mount point identified by |mount_name|. + // Returns false if the |mount_name| is not (no longer) registered. + // TODO(kinuko): Probably this should be rather named RevokeMountPoint. + virtual bool RevokeFileSystem(const std::string& mount_name) = 0; + + // Returns the mount point root path registered for a given |mount_name|. + // Returns false if the given |mount_name| is not valid. + virtual bool GetRegisteredPath(const std::string& mount_name, + FilePath* path) const = 0; + + // Cracks the given |virtual_path| (which is the path part of a filesystem URL + // without '/external' or '/isolated' prefix part) and populates the + // |mount_name|, |type|, and |path| if the <mount_name> part embedded in + // the |virtual_path| (i.e. the first component of the |virtual_path|) is a + // valid registered filesystem ID or mount name for an existing mount point. + // + // Returns false if the given virtual_path cannot be cracked. + // + // Note that |path| is set to empty paths if the filesystem type is isolated + // and |virtual_path| has no <relative_path> part (i.e. pointing to the + // virtual root). + virtual bool CrackVirtualPath(const FilePath& virtual_path, + std::string* mount_name, + FileSystemType* type, + FilePath* path) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(MountPoints); +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_MOUNT_POINTS_H_ + diff --git a/webkit/chromeos/fileapi/remote_file_system_proxy.h b/webkit/fileapi/remote_file_system_proxy.h index e54a266..e54a266 100644 --- a/webkit/chromeos/fileapi/remote_file_system_proxy.h +++ b/webkit/fileapi/remote_file_system_proxy.h diff --git a/webkit/fileapi/syncable/canned_syncable_file_system.cc b/webkit/fileapi/syncable/canned_syncable_file_system.cc index 05448f3..e960959 100644 --- a/webkit/fileapi/syncable/canned_syncable_file_system.cc +++ b/webkit/fileapi/syncable/canned_syncable_file_system.cc @@ -16,7 +16,6 @@ #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_system_task_runners.h" -#include "webkit/fileapi/isolated_context.h" #include "webkit/fileapi/local_file_system_operation.h" #include "webkit/fileapi/mock_file_system_options.h" #include "webkit/fileapi/sandbox_mount_point_provider.h" diff --git a/webkit/fileapi/syncable/syncable_file_system_util.cc b/webkit/fileapi/syncable/syncable_file_system_util.cc index 207f802..21652d0 100644 --- a/webkit/fileapi/syncable/syncable_file_system_util.cc +++ b/webkit/fileapi/syncable/syncable_file_system_util.cc @@ -4,21 +4,22 @@ #include "webkit/fileapi/syncable/syncable_file_system_util.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_observers.h" #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_util.h" -#include "webkit/fileapi/isolated_context.h" #include "webkit/fileapi/sandbox_mount_point_provider.h" namespace fileapi { bool RegisterSyncableFileSystem(const std::string& service_name) { - return IsolatedContext::GetInstance()->RegisterExternalFileSystem( + return ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( service_name, kFileSystemTypeSyncable, FilePath()); } bool RevokeSyncableFileSystem(const std::string& service_name) { - return IsolatedContext::GetInstance()->RevokeFileSystem(service_name); + return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( + service_name); } GURL GetSyncableFileSystemRootURI(const GURL& origin, diff --git a/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc b/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc index b8d92f6..356ff53 100644 --- a/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc +++ b/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc @@ -8,7 +8,7 @@ #include "base/message_loop.h" #include "base/message_loop_proxy.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webkit/fileapi/isolated_context.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/syncable/canned_syncable_file_system.h" #include "webkit/fileapi/syncable/local_file_sync_context.h" diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi index 39288ee..324f9e5 100644 --- a/webkit/fileapi/webkit_fileapi.gypi +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -5,6 +5,8 @@ { 'variables': { 'webkit_fileapi_sources': [ + '../fileapi/external_mount_points.cc', + '../fileapi/external_mount_points.h', '../fileapi/file_observers.h', '../fileapi/file_permission_policy.cc', '../fileapi/file_permission_policy.h', @@ -70,10 +72,13 @@ '../fileapi/media/mtp_device_file_system_config.h', '../fileapi/media/native_media_file_util.cc', '../fileapi/media/native_media_file_util.h', + '../fileapi/mount_points.cc', + '../fileapi/mount_points.h', '../fileapi/native_file_util.cc', '../fileapi/native_file_util.h', '../fileapi/obfuscated_file_util.cc', '../fileapi/obfuscated_file_util.h', + '../fileapi/remote_file_system_proxy.h', '../fileapi/sandbox_file_stream_writer.cc', '../fileapi/sandbox_file_stream_writer.h', '../fileapi/sandbox_mount_point_provider.cc', @@ -120,7 +125,6 @@ '../chromeos/fileapi/file_util_async.h', '../chromeos/fileapi/remote_file_system_operation.cc', '../chromeos/fileapi/remote_file_system_operation.h', - '../chromeos/fileapi/remote_file_system_proxy.h', '../chromeos/fileapi/remote_file_stream_writer.cc', '../chromeos/fileapi/remote_file_stream_writer.h', ], |