summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 14:55:37 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 14:55:37 +0000
commit9fb9294aab92e35d9584df40d853be5e7ca25ea0 (patch)
treedcb89bceb4352859ca54fe7995a1c1d66190369c /webkit
parent262a1f2968e0cb860f4eec37fa07cd51aba48fba (diff)
downloadchromium_src-9fb9294aab92e35d9584df40d853be5e7ca25ea0.zip
chromium_src-9fb9294aab92e35d9584df40d853be5e7ca25ea0.tar.gz
chromium_src-9fb9294aab92e35d9584df40d853be5e7ca25ea0.tar.bz2
Integrate external mount points to IsolatedContext
* To support MTP/Media filesystems in CrOS's FileBrowser * To eventually support external, persistent mount points in sans-CrOS chrome (currently ifdef'ed only for cros since we need http://crbug.com/142289 to do the same in chrome) * To introduce more finer-grained filesystem types * To reduce duplicated code What this patch actually does: - Add external mount point support in IsolatedContext - Introduce new filesystem types, NativeLocal and GData, to represent file systems supported by CrOS - Replace CrOSMountPointProvider's internal mount map with IsolatedContext BUG=139223 TEST=manually tested TEST=existing tests Review URL: https://chromiumcodereview.appspot.com/10823273 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152559 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/chromeos/fileapi/cros_mount_point_provider.cc190
-rw-r--r--webkit/chromeos/fileapi/cros_mount_point_provider.h66
-rw-r--r--webkit/fileapi/file_system_context.cc7
-rw-r--r--webkit/fileapi/file_system_mount_point_provider.h6
-rw-r--r--webkit/fileapi/file_system_types.h27
-rw-r--r--webkit/fileapi/file_system_url.cc18
-rw-r--r--webkit/fileapi/file_system_url.h50
-rw-r--r--webkit/fileapi/file_system_util.cc7
-rw-r--r--webkit/fileapi/isolated_context.cc174
-rw-r--r--webkit/fileapi/isolated_context.h130
-rw-r--r--webkit/fileapi/isolated_mount_point_provider.cc10
-rw-r--r--webkit/fileapi/local_file_system_operation.cc3
12 files changed, 426 insertions, 262 deletions
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.cc b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
index fcb71ce..20c1c52 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.cc
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
@@ -23,6 +23,8 @@
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_url.h"
#include "webkit/fileapi/file_system_util.h"
+#include "webkit/fileapi/isolated_context.h"
+#include "webkit/fileapi/isolated_file_util.h"
#include "webkit/fileapi/local_file_stream_writer.h"
#include "webkit/fileapi/local_file_system_operation.h"
#include "webkit/glue/webkit_glue.h"
@@ -35,23 +37,19 @@ const char kChromeUIScheme[] = "chrome";
namespace chromeos {
-CrosMountPointProvider::MountPoint::MountPoint(
- const FilePath& in_web_root_path,
- const FilePath& in_local_root_path,
- FileSystemLocation in_location,
- fileapi::RemoteFileSystemProxyInterface* in_proxy)
- : web_root_path(in_web_root_path), local_root_path(in_local_root_path),
- location(in_location), remote_proxy(in_proxy) {
-}
-
-CrosMountPointProvider::MountPoint::~MountPoint() {
+// static
+bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
+ if (!url.is_valid())
+ return false;
+ return url.type() == fileapi::kFileSystemTypeNativeLocal ||
+ url.type() == fileapi::kFileSystemTypeDrive;
}
CrosMountPointProvider::CrosMountPointProvider(
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy)
: special_storage_policy_(special_storage_policy),
file_access_permissions_(new FileAccessPermissions()),
- local_file_util_(new fileapi::LocalFileUtil()) {
+ local_file_util_(new fileapi::IsolatedFileUtil()) {
FilePath home_path;
if (PathService::Get(base::DIR_HOME, &home_path))
AddLocalMountPoint(home_path.AppendASCII("Downloads"));
@@ -62,17 +60,6 @@ CrosMountPointProvider::CrosMountPointProvider(
CrosMountPointProvider::~CrosMountPointProvider() {
}
-bool CrosMountPointProvider::GetRootForVirtualPath(
- const FilePath& virtual_path, FilePath* root_path) {
- const MountPoint* mount_point = GetMountPoint(virtual_path);
- if (!mount_point)
- return false;
-
- DCHECK(root_path);
- *root_path = mount_point->local_root_path;
- return true;
-}
-
void CrosMountPointProvider::ValidateFileSystemRoot(
const GURL& origin_url,
fileapi::FileSystemType type,
@@ -89,17 +76,24 @@ FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
const FilePath& virtual_path,
bool create) {
DCHECK(type == fileapi::kFileSystemTypeExternal);
+ fileapi::FileSystemURL url(origin_url, type, virtual_path);
+ if (!url.is_valid())
+ return FilePath();
+
FilePath root_path;
- if (!GetRootForVirtualPath(virtual_path, &root_path))
+ if (!isolated_context()->GetRegisteredPath(url.filesystem_id(), &root_path))
return FilePath();
- return root_path;
+ return root_path.DirName();
}
bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url,
fileapi::FileSystemType type,
const FilePath& virtual_path) {
- if (type != fileapi::kFileSystemTypeExternal)
+ // TODO(kinuko): this should call CanHandleURL() once
+ // http://crbug.com/142267 is fixed.
+ if (type != fileapi::kFileSystemTypeNativeLocal &&
+ type != fileapi::kFileSystemTypeDrive)
return false;
// Permit access to mount points from internal WebUI.
@@ -135,42 +129,43 @@ void CrosMountPointProvider::DeleteFileSystem(
}
bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) {
- base::AutoLock locker(mount_point_map_lock_);
- MountPointMap::const_iterator iter = mount_point_map_.find(
- mount_point.BaseName().value());
- DCHECK(iter == mount_point_map_.end() ||
- iter->second.local_root_path == mount_point.DirName());
- return iter != mount_point_map_.end();
+ std::string mount_name = mount_point.BaseName().AsUTF8Unsafe();
+ FilePath path;
+ const bool valid = isolated_context()->GetRegisteredPath(mount_name, &path);
+ return valid && path == mount_point;
}
void 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_);
- mount_point_map_.erase(mount_point.BaseName().value());
- mount_point_map_.insert(std::make_pair(
- mount_point.BaseName().value(),
- MountPoint(mount_point.BaseName(),
- mount_point.DirName(),
- LOCAL,
- NULL)));
+ local_to_virtual_map_[mount_point] = mount_point.BaseName();
}
void 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,
+ fileapi::kFileSystemTypeDrive,
+ mount_point);
base::AutoLock locker(mount_point_map_lock_);
- mount_point_map_.erase(mount_point.BaseName().value());
- mount_point_map_.insert(std::make_pair(
- mount_point.BaseName().value(),
- MountPoint(mount_point.BaseName(),
- mount_point.DirName(),
- REMOTE,
- remote_proxy)));
+ remote_proxy_map_[mount_name] = remote_proxy;
+ local_to_virtual_map_[mount_point] = mount_point.BaseName();
}
void CrosMountPointProvider::RemoveMountPoint(const FilePath& mount_point) {
+ std::string mount_name = mount_point.BaseName().AsUTF8Unsafe();
+ isolated_context()->RevokeFileSystem(mount_name);
base::AutoLock locker(mount_point_map_lock_);
- mount_point_map_.erase(mount_point.BaseName().value());
+ remote_proxy_map_.erase(mount_name);
+ local_to_virtual_map_.erase(mount_point);
}
void CrosMountPointProvider::GrantFullAccessToExtension(
@@ -178,10 +173,11 @@ void CrosMountPointProvider::GrantFullAccessToExtension(
DCHECK(special_storage_policy_->IsFileHandler(extension_id));
if (!special_storage_policy_->IsFileHandler(extension_id))
return;
- for (MountPointMap::const_iterator iter = mount_point_map_.begin();
- iter != mount_point_map_.end();
- ++iter) {
- GrantFileAccessToExtension(extension_id, FilePath(iter->first));
+ std::vector<fileapi::IsolatedContext::FileInfo> files =
+ isolated_context()->GetExternalMountPoints();
+ for (size_t i = 0; i < files.size(); ++i) {
+ GrantFileAccessToExtension(extension_id,
+ FilePath::FromUTF8Unsafe(files[i].name));
}
}
@@ -200,56 +196,41 @@ void CrosMountPointProvider::RevokeAccessForExtension(
}
std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const {
+ std::vector<fileapi::IsolatedContext::FileInfo> files =
+ isolated_context()->GetExternalMountPoints();
std::vector<FilePath> root_dirs;
- for (MountPointMap::const_iterator iter = mount_point_map_.begin();
- iter != mount_point_map_.end();
- ++iter) {
- root_dirs.push_back(iter->second.local_root_path.Append(iter->first));
- }
+ for (size_t i = 0; i < files.size(); ++i)
+ root_dirs.push_back(files[i].path);
return root_dirs;
}
fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
fileapi::FileSystemType type) {
+ DCHECK(type == fileapi::kFileSystemTypeNativeLocal);
return local_file_util_.get();
}
FilePath CrosMountPointProvider::GetPathForPermissionsCheck(
const FilePath& virtual_path) const {
- const MountPoint* mount_point = GetMountPoint(virtual_path);
- if (!mount_point)
- return FilePath();
-
- FilePath root_path = mount_point->local_root_path;
-
- return root_path.Append(virtual_path);
-}
-
-const CrosMountPointProvider::MountPoint*
-CrosMountPointProvider::GetMountPoint(const FilePath& virtual_path) const {
- std::vector<FilePath::StringType> components;
- virtual_path.GetComponents(&components);
- if (components.empty())
- return NULL;
-
- base::AutoLock locker(
- const_cast<CrosMountPointProvider*>(this)->mount_point_map_lock_);
- // Check if this root mount point is exposed by this provider.
- MountPointMap::const_iterator iter = mount_point_map_.find(components[0]);
- if (iter == mount_point_map_.end())
- return NULL;
-
- return &(iter->second);
+ return virtual_path;
}
fileapi::FileSystemOperationInterface*
CrosMountPointProvider::CreateFileSystemOperation(
const fileapi::FileSystemURL& url,
fileapi::FileSystemContext* context) const {
- const MountPoint* mount_point = GetMountPoint(url.path());
- if (mount_point && mount_point->location == REMOTE)
- return new chromeos::RemoteFileSystemOperation(mount_point->remote_proxy);
+ if (url.type() == fileapi::kFileSystemTypeDrive) {
+ base::AutoLock locker(mount_point_map_lock_);
+ RemoteProxyMap::const_iterator found = remote_proxy_map_.find(
+ url.filesystem_id());
+ // TODO(kinuko): we should handle not-found case gracefully.
+ // http://crbug.com/141617
+ if (found != remote_proxy_map_.end()) {
+ return new chromeos::RemoteFileSystemOperation(found->second);
+ }
+ }
+ DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
new fileapi::FileSystemOperationContext(context));
return new fileapi::LocalFileSystemOperation(context,
@@ -272,33 +253,36 @@ fileapi::FileStreamWriter* CrosMountPointProvider::CreateFileStreamWriter(
fileapi::FileSystemContext* context) const {
if (!url.is_valid())
return NULL;
- const MountPoint* mount_point = GetMountPoint(url.path());
- if (!mount_point)
- return NULL;
- if (mount_point->location == REMOTE) {
- return new fileapi::RemoteFileStreamWriter(mount_point->remote_proxy,
- url,
- offset);
+ 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 NULL;
+ return new fileapi::RemoteFileStreamWriter(found->second, url, offset);
}
- FilePath root_path = mount_point->local_root_path;
- return new fileapi::LocalFileStreamWriter(
- root_path.Append(url.path()), offset);
+
+ DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
+ return new fileapi::LocalFileStreamWriter(url.path(), offset);
}
bool CrosMountPointProvider::GetVirtualPath(const FilePath& filesystem_path,
FilePath* virtual_path) {
- for (MountPointMap::const_iterator iter = mount_point_map_.begin();
- iter != mount_point_map_.end();
- ++iter) {
- FilePath mount_prefix = iter->second.local_root_path.Append(iter->first);
- *virtual_path = FilePath(iter->first);
- if (mount_prefix == filesystem_path) {
- return true;
- } else if (mount_prefix.AppendRelativePath(filesystem_path, virtual_path)) {
- return true;
- }
+ 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 false;
+ return iter->first.DirName().AppendRelativePath(
+ filesystem_path, virtual_path);
+}
+
+fileapi::IsolatedContext* CrosMountPointProvider::isolated_context() const {
+ return fileapi::IsolatedContext::GetInstance();
}
} // namespace chromeos
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.h b/webkit/chromeos/fileapi/cros_mount_point_provider.h
index a7c410b..a9e0650 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.h
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.h
@@ -11,13 +11,16 @@
#include "base/compiler_specific.h"
#include "base/file_path.h"
+#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
-#include "webkit/fileapi/local_file_util.h"
+#include "webkit/fileapi/fileapi_export.h"
#include "webkit/quota/special_storage_policy.h"
namespace fileapi {
class FileSystemFileUtil;
+class IsolatedContext;
+class LocalFileUtil;
}
namespace chromeos {
@@ -25,24 +28,21 @@ namespace chromeos {
class FileAccessPermissions;
// An interface to provide local filesystem paths.
-class CrosMountPointProvider
+class FILEAPI_EXPORT CrosMountPointProvider
: public fileapi::ExternalFileSystemMountPointProvider {
public:
using fileapi::FileSystemMountPointProvider::ValidateFileSystemCallback;
using fileapi::FileSystemMountPointProvider::DeleteFileSystemCallback;
- // Mount point file system location enum.
- enum FileSystemLocation {
- // File system that is locally mounted by the underlying OS.
- LOCAL,
- // File system that is remotely hosted on the net.
- REMOTE,
- };
-
CrosMountPointProvider(
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy);
virtual ~CrosMountPointProvider();
+ // Returns true if CrosMountpointProvider can handle |url|, i.e. its
+ // file system type matches with what this provider supports.
+ // This could be called on any threads.
+ static bool CanHandleURL(const fileapi::FileSystemURL& url);
+
// fileapi::FileSystemMountPointProvider overrides.
virtual void ValidateFileSystemRoot(
const GURL& origin_url,
@@ -99,39 +99,19 @@ class CrosMountPointProvider
FilePath* virtual_path) OVERRIDE;
private:
- // Representation of a mount point exposed by this external mount point
- // provider.
- struct MountPoint {
- MountPoint(const FilePath& web_path,
- const FilePath& local_path,
- FileSystemLocation loc,
- fileapi::RemoteFileSystemProxyInterface* proxy);
- virtual ~MountPoint();
- // Virtual web path, relative to external root in filesystem URLs.
- // For example, in "filesystem://.../external/foo/bar/" this path would
- // map to "foo/bar/".
- const FilePath web_root_path;
- // Parent directory for the exposed file system path. For example,
- // mount point that exposes "/media/removable" would have this
- // root path as "/media".
- const FilePath local_root_path;
- // File system location.
- const FileSystemLocation location;
- // Remote file system proxy for remote mount points.
- scoped_refptr<fileapi::RemoteFileSystemProxyInterface> remote_proxy;
- };
-
- typedef std::map<std::string, MountPoint> MountPointMap;
-
- // Gives the real file system's |root_path| for given |virtual_path|. Returns
- // false when |virtual_path| cannot be mapped to the real file system.
- bool GetRootForVirtualPath(const FilePath& virtual_path, FilePath* root_path);
- // Returns mount point info for a given |virtual_path|, NULL if the path is
- // not part of the mounted file systems exposed through this provider.
- const MountPoint* GetMountPoint(const FilePath& virtual_path) const;
-
- base::Lock mount_point_map_lock_;
- MountPointMap mount_point_map_;
+ 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_;
+
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
scoped_ptr<FileAccessPermissions> file_access_permissions_;
scoped_ptr<fileapi::LocalFileUtil> local_file_util_;
diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc
index d76ad78..0d62a08 100644
--- a/webkit/fileapi/file_system_context.cc
+++ b/webkit/fileapi/file_system_context.cc
@@ -113,12 +113,19 @@ FileSystemMountPointProvider* FileSystemContext::GetMountPointProvider(
case kFileSystemTypePersistent:
return sandbox_provider_.get();
case kFileSystemTypeExternal:
+ case kFileSystemTypeDrive:
return external_provider_.get();
case kFileSystemTypeIsolated:
case kFileSystemTypeDragged:
case kFileSystemTypeNativeMedia:
case kFileSystemTypeDeviceMedia:
return isolated_provider_.get();
+ case kFileSystemTypeNativeLocal:
+#if defined(OS_CHROMEOS)
+ return external_provider_.get();
+#else
+ return isolated_provider_.get();
+#endif
default:
if (provider_map_.find(type) != provider_map_.end())
return provider_map_.find(type)->second;
diff --git a/webkit/fileapi/file_system_mount_point_provider.h b/webkit/fileapi/file_system_mount_point_provider.h
index fbc7b58..ffbe60d 100644
--- a/webkit/fileapi/file_system_mount_point_provider.h
+++ b/webkit/fileapi/file_system_mount_point_provider.h
@@ -126,14 +126,14 @@ class ExternalFileSystemMountPointProvider
// provider. This list is used to set appropriate child process file access
// permissions.
virtual std::vector<FilePath> GetRootDirectories() const = 0;
- // Grant access to all external file system from extension identified with
+ // Grants access to all external file system from extension identified with
// |extension_id|.
virtual void GrantFullAccessToExtension(const std::string& extension_id) = 0;
// Grants access to |virtual_path| from |origin_url|.
virtual void GrantFileAccessToExtension(
const std::string& extension_id,
const FilePath& virtual_path) = 0;
- // Revoke file access from extension identified with |extension_id|.
+ // Revokes file access from extension identified with |extension_id|.
virtual void RevokeAccessForExtension(
const std::string& extension_id) = 0;
// Checks if a given |mount_point| already exists.
@@ -144,7 +144,7 @@ class ExternalFileSystemMountPointProvider
virtual void AddRemoteMountPoint(
const FilePath& mount_point,
RemoteFileSystemProxyInterface* remote_proxy) = 0;
- // Remove a mount point.
+ // Removes a mount point.
virtual void RemoveMountPoint(const FilePath& mount_point) = 0;
// Gets virtual path by known filesystem path. Returns false when filesystem
// path is not exposed by this provider.
diff --git a/webkit/fileapi/file_system_types.h b/webkit/fileapi/file_system_types.h
index 4816781..936c81f 100644
--- a/webkit/fileapi/file_system_types.h
+++ b/webkit/fileapi/file_system_types.h
@@ -34,8 +34,16 @@ enum FileSystemType {
// Should be used only for testing.
kFileSystemTypeTest = 100,
- // Internal filesystem types, which are not exposed to WebKit but are
- // accessible via Isolated file system.
+ // Following file system types are internal and they are not exposed to
+ // WebKit, but are accessible via IsolatedContext.
+
+ // Indicates a transient, isolated file system for a native local path.
+ // TODO(kinuko): Rename all kFileSystemTypeIsolated used as internal type
+ // with this one.
+ kFileSystemTypeNativeLocal,
+
+ // Indicates a transient, isolated file system for dragged files (which could
+ // contain multiple dragged paths in the virtual root).
kFileSystemTypeDragged,
// Indicates media filesystem which we can access with same manner to
@@ -45,6 +53,21 @@ enum FileSystemType {
// Indicates media filesystem to which we need special protocol to access,
// such as MTP or PTP.
kFileSystemTypeDeviceMedia,
+
+ // Indicates a Drive filesystem which provides access to Google Drive.
+ kFileSystemTypeDrive,
+};
+
+enum FileSystemMountType {
+ kFileSystemMountTypeUnknown = -1,
+
+ // For kFileSystemTypeIsolated file systems. URLs for this type of
+ // file system is cracked via IsolatedContext.
+ kFileSystemMountTypeIsolated = kFileSystemTypeIsolated,
+
+ // For kFileSystemTypeIsolated file systems. URLs for this type of
+ // file system is cracked via IsolatedContext.
+ kFileSystemMountTypeExternal = kFileSystemTypeExternal,
};
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_url.cc b/webkit/fileapi/file_system_url.cc
index ab0c2d8..f5247a0 100644
--- a/webkit/fileapi/file_system_url.cc
+++ b/webkit/fileapi/file_system_url.cc
@@ -11,11 +11,14 @@
namespace fileapi {
FileSystemURL::FileSystemURL()
- : type_(kFileSystemTypeUnknown), is_valid_(false) {}
+ : type_(kFileSystemTypeUnknown),
+ mount_type_(kFileSystemMountTypeUnknown),
+ is_valid_(false) {}
FileSystemURL::FileSystemURL(const GURL& url)
- : type_(kFileSystemTypeUnknown) {
- is_valid_ = CrackFileSystemURL(url, &origin_, &type_, &path_);
+ : type_(kFileSystemTypeUnknown),
+ mount_type_(kFileSystemMountTypeUnknown) {
+ is_valid_ = CrackFileSystemURL(url, &origin_, &type_, &virtual_path_);
MayCrackIsolatedPath();
}
@@ -25,7 +28,7 @@ FileSystemURL::FileSystemURL(
const FilePath& path)
: origin_(origin),
type_(type),
- path_(path),
+ virtual_path_(path),
is_valid_(true) {
MayCrackIsolatedPath();
}
@@ -47,16 +50,19 @@ bool FileSystemURL::operator==(const FileSystemURL& that) const {
return origin_ == that.origin_ &&
type_ == that.type_ &&
path_ == that.path_ &&
+ virtual_path_ == that.virtual_path_ &&
filesystem_id_ == that.filesystem_id_ &&
is_valid_ == that.is_valid_;
}
void FileSystemURL::MayCrackIsolatedPath() {
- if (is_valid_ && type_ == kFileSystemTypeIsolated) {
+ path_ = virtual_path_;
+ if (is_valid_ && IsolatedContext::IsIsolatedType(type_)) {
+ mount_type_ = static_cast<FileSystemMountType>(type_);
// If the type is isolated, crack the path further to get the 'real'
// filesystem type and path.
is_valid_ = IsolatedContext::GetInstance()->CrackIsolatedPath(
- path_, &filesystem_id_, &type_, &path_);
+ virtual_path_, &filesystem_id_, &type_, &path_);
}
}
diff --git a/webkit/fileapi/file_system_url.h b/webkit/fileapi/file_system_url.h
index 1d1d579..238965f 100644
--- a/webkit/fileapi/file_system_url.h
+++ b/webkit/fileapi/file_system_url.h
@@ -17,6 +17,31 @@ namespace fileapi {
// A class representing a filesystem URL which consists of origin URL,
// type and an internal path used inside the filesystem.
+//
+// When a FileSystemURL instance is created for regular sandbox file systems
+// each accessor method would return following values:
+//
+// Example: For a URL 'filesystem:http://foo.com/temporary/foo/bar':
+// origin() returns 'http://foo.com',
+// type() returns kFileSystemTypeTemporary,
+// path() and virtual_path() return 'foo/bar', and
+// filesystem_id() returns an empty string.
+//
+// path() and virtual_path() usually return the same value, but they
+// have different values if an instance is created for Isolated or External
+// FileSystem URL, for which we may mount different paths from its exposed
+// virtual paths.
+//
+// Example: Assume a path '/media/removable' is mounted at mount name
+// 'mount_name' with type kFileSystemTypeFoo as an external file system.
+// For a URL 'filesystem:http://bar.com/external/mount_name/foo/bar':
+// origin() returns 'http://bar.com',
+// type() returns the kFileSystemTypeFoo,
+// path() returns '/media/removable/foo/bar',
+// virtual_path() returns 'mount_name/foo/bar',
+// filesystem_id() returns 'mount_name', and
+// mount_type() returns kFileSystemMountTypeExternal.
+//
class FILEAPI_EXPORT FileSystemURL {
public:
FileSystemURL();
@@ -26,16 +51,31 @@ class FILEAPI_EXPORT FileSystemURL {
const FilePath& internal_path);
~FileSystemURL();
+ // Returns true if this instance represents a valid FileSystem URL.
bool is_valid() const { return is_valid_; }
+
+ // Returns the origin part of this URL. See the class comment for details.
const GURL& origin() const { return origin_; }
+
+ // Returns the type part of this URL. See the class comment for details.
FileSystemType type() const { return type_; }
- // TODO(kinuko): this must be std::string.
+ // Returns the path part of this URL. See the class comment for details.
+ // TODO(kinuko): this must return std::string.
const FilePath& path() const { return path_; }
- // For isolated filesystem.
+ // Returns the original path part of this URL.
+ // See the class comment for details.
+ // TODO(kinuko): this must return std::string.
+ const FilePath& virtual_path() const { return virtual_path_; }
+
+ // Returns the filesystem ID/name for isolated/external file system URLs.
+ // See the class comment for details.
const std::string& filesystem_id() const { return filesystem_id_; }
+ // Returns the mount type of this URL for isolated/external file system URLs.
+ FileSystemMountType mount_type() const { return mount_type_; }
+
std::string spec() const;
// Returns a new FileSystemURL with the given path.
@@ -50,7 +90,11 @@ class FILEAPI_EXPORT FileSystemURL {
GURL origin_;
FileSystemType type_;
FilePath path_;
- std::string filesystem_id_; // For isolated filesystem.
+
+ // For isolated filesystem.
+ std::string filesystem_id_;
+ FilePath virtual_path_;
+ FileSystemMountType mount_type_;
bool is_valid_;
};
diff --git a/webkit/fileapi/file_system_util.cc b/webkit/fileapi/file_system_util.cc
index d77d7f3..55c98a6 100644
--- a/webkit/fileapi/file_system_util.cc
+++ b/webkit/fileapi/file_system_util.cc
@@ -155,10 +155,13 @@ GURL GetFileSystemRootURI(const GURL& origin_url, FileSystemType type) {
case kFileSystemTypeTest:
url += (kTestDir + 1); // We don't want the leading slash.
return GURL(url + "/");
- case kFileSystemTypeUnknown:
+ // Internal types are always pointed via isolated or external URLs.
+ case kFileSystemTypeDeviceMedia:
case kFileSystemTypeDragged:
+ case kFileSystemTypeDrive:
+ case kFileSystemTypeNativeLocal:
case kFileSystemTypeNativeMedia:
- case kFileSystemTypeDeviceMedia:
+ case kFileSystemTypeUnknown:
NOTREACHED();
}
NOTREACHED();
diff --git a/webkit/fileapi/isolated_context.cc b/webkit/fileapi/isolated_context.cc
index 6398e42..a625693 100644
--- a/webkit/fileapi/isolated_context.cc
+++ b/webkit/fileapi/isolated_context.cc
@@ -46,19 +46,12 @@ bool IsSinglePathIsolatedFileSystem(FileSystemType type) {
case kFileSystemTypeDragged:
return false;
- // Regular file systems.
- case kFileSystemTypeIsolated:
- case kFileSystemTypeNativeMedia:
- case kFileSystemTypeDeviceMedia:
- case kFileSystemTypeTemporary:
- case kFileSystemTypePersistent:
- case kFileSystemTypeExternal:
- case kFileSystemTypeTest:
- return true;
-
case kFileSystemTypeUnknown:
NOTREACHED();
return true;
+
+ default:
+ return true;
}
NOTREACHED();
return true;
@@ -112,9 +105,60 @@ bool IsolatedContext::FileInfoSet::AddPathWithName(
//--------------------------------------------------------------------------
+class IsolatedContext::Instance {
+ public:
+ typedef FileSystemMountType 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);
+
+ // 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();
+
+ 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_; }
+ int ref_counts() const { return ref_counts_; }
+
+ void AddRef() { ++ref_counts_; }
+ void RemoveRef() { --ref_counts_; }
+
+ bool ResolvePathForName(const std::string& name, FilePath* path) const;
+
+ // Returns true if the instance is a single-path instance.
+ bool IsSinglePathInstance() const;
+
+ private:
+ const MountType mount_type_;
+ const FileSystemType type_;
+
+ // For single-path instance.
+ const FileInfo file_info_;
+
+ // For multiple-path instance (e.g. dragged file system).
+ const std::set<FileInfo> files_;
+
+ // Reference counts. Note that an isolated filesystem is created with ref==0
+ // and will get deleted when the ref count reaches <=0.
+ int ref_counts_;
+
+ DISALLOW_COPY_AND_ASSIGN(Instance);
+};
+
IsolatedContext::Instance::Instance(FileSystemType type,
const FileInfo& file_info)
- : type_(type),
+ : mount_type_(kFileSystemMountTypeIsolated),
+ type_(type),
file_info_(file_info),
ref_counts_(0) {
DCHECK(IsSinglePathIsolatedFileSystem(type_));
@@ -122,12 +166,22 @@ IsolatedContext::Instance::Instance(FileSystemType type,
IsolatedContext::Instance::Instance(FileSystemType type,
const std::set<FileInfo>& files)
- : type_(type),
+ : mount_type_(kFileSystemMountTypeIsolated),
+ type_(type),
files_(files),
ref_counts_(0) {
DCHECK(!IsSinglePathIsolatedFileSystem(type_));
}
+IsolatedContext::Instance::Instance(FileSystemType type,
+ const FilePath& path)
+ : mount_type_(kFileSystemMountTypeExternal),
+ type_(type),
+ file_info_(FileInfo("", path)),
+ ref_counts_(0) {
+ DCHECK(IsSinglePathIsolatedFileSystem(type_));
+}
+
IsolatedContext::Instance::~Instance() {}
bool IsolatedContext::Instance::ResolvePathForName(const std::string& name,
@@ -155,6 +209,11 @@ IsolatedContext* IsolatedContext::GetInstance() {
return g_isolated_context.Pointer();
}
+// static
+bool IsolatedContext::IsIsolatedType(FileSystemType type) {
+ return type == kFileSystemTypeIsolated || type == kFileSystemTypeExternal;
+}
+
std::string IsolatedContext::RegisterDraggedFileSystem(
const FileInfoSet& files) {
base::AutoLock locker(lock_);
@@ -186,6 +245,33 @@ std::string IsolatedContext::RegisterFileSystemForPath(
return filesystem_id;
}
+#if defined(OS_CHROMEOS)
+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() == kFileSystemMountTypeExternal)
+ files.push_back(FileInfo(iter->first, iter->second->file_info().path));
+ }
+ return files;
+}
+#endif
+
bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
base::AutoLock locker(lock_);
return UnregisterFileSystem(filesystem_id);
@@ -225,51 +311,69 @@ void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
Instance* instance = found->second;
DCHECK(instance->ref_counts() > 0);
instance->RemoveRef();
- if (instance->ref_counts() == 0) {
+ if (instance->ref_counts() == 0 &&
+ instance->mount_type() != kFileSystemMountTypeExternal) {
bool deleted = UnregisterFileSystem(filesystem_id);
DCHECK(deleted);
}
}
bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path,
- std::string* filesystem_id,
+ std::string* id_or_name,
FileSystemType* type,
FilePath* path) const {
- DCHECK(filesystem_id);
+ DCHECK(id_or_name);
DCHECK(path);
// This should not contain any '..' references.
if (virtual_path.ReferencesParent())
return false;
- // The virtual_path should comprise <filesystem_id> and <relative_path> parts.
+ // The virtual_path should comprise <id_or_name> and <relative_path> parts.
std::vector<FilePath::StringType> components;
virtual_path.GetComponents(&components);
if (components.size() < 1)
return false;
-
- base::AutoLock locker(lock_);
- std::string fsid = FilePath(components[0]).MaybeAsASCII();
+ std::vector<FilePath::StringType>::iterator component_iter =
+ components.begin();
+ std::string fsid = FilePath(*component_iter++).MaybeAsASCII();
if (fsid.empty())
return false;
- IDToInstance::const_iterator found_instance = instance_map_.find(fsid);
- if (found_instance == instance_map_.end())
- return false;
- *filesystem_id = fsid;
- if (type)
- *type = found_instance->second->type();
- if (components.size() == 1) {
- path->clear();
- return true;
- }
- // components[1] should be a name of the registered paths.
+
FilePath cracked_path;
- std::string name = FilePath(components[1]).AsUTF8Unsafe();
- if (!found_instance->second->ResolvePathForName(name, &cracked_path))
- return false;
+ {
+ base::AutoLock locker(lock_);
+ IDToInstance::const_iterator found_instance = instance_map_.find(fsid);
+ if (found_instance == instance_map_.end())
+ return false;
+ *id_or_name = fsid;
+ const Instance* instance = found_instance->second;
+ if (type)
+ *type = instance->type();
+ switch (instance->mount_type()) {
+ case kFileSystemMountTypeIsolated: {
+ 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 kFileSystemMountTypeExternal:
+ cracked_path = instance->file_info().path;
+ break;
+ case kFileSystemMountTypeUnknown:
+ NOTREACHED();
+ break;
+ }
+ }
- for (size_t i = 2; i < components.size(); ++i)
- cracked_path = cracked_path.Append(components[i]);
+ for (; component_iter != components.end(); ++component_iter)
+ cracked_path = cracked_path.Append(*component_iter);
*path = cracked_path;
return true;
}
diff --git a/webkit/fileapi/isolated_context.h b/webkit/fileapi/isolated_context.h
index 3888dfe..418462f 100644
--- a/webkit/fileapi/isolated_context.h
+++ b/webkit/fileapi/isolated_context.h
@@ -20,11 +20,38 @@
namespace fileapi {
-// Manages isolated filename namespaces. A namespace is simply defined as a
-// set of file paths and corresponding filesystem ID. This context class is
-// a singleton and access to the context is thread-safe (protected with a
-// lock).
+// 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:
+//
+// 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 FILEAPI_EXPORT IsolatedContext {
public:
struct FILEAPI_EXPORT FileInfo {
@@ -68,6 +95,11 @@ class FILEAPI_EXPORT IsolatedContext {
// The instance is lazily created per browser process.
static IsolatedContext* GetInstance();
+ // Returns true if the given filesystem type is managed by IsolatedContext
+ // (i.e. if the given |type| is Isolated or External).
+ // TODO(kinuko): needs a better function name.
+ static bool IsIsolatedType(FileSystemType type);
+
// Registers a new isolated filesystem with the given FileInfoSet |files|
// and returns the new filesystem_id. The files are registered with their
// register_name as their keys so that later we can resolve the full paths
@@ -101,7 +133,30 @@ class FILEAPI_EXPORT IsolatedContext {
const FilePath& path,
std::string* register_name);
- // Revokes the filesystem |filesystem_id|
+#if defined(OS_CHROMEOS)
+ // 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;
+#endif
+
+ // Revokes the filesystem |filesystem_id|.
// Returns false if the |filesystem_id| is not (no longer) registered.
bool RevokeFileSystem(const std::string& filesystem_id);
@@ -124,19 +179,21 @@ class FILEAPI_EXPORT IsolatedContext {
// (e.g. by RevokeFileSystemByPath).
void RemoveReference(const std::string& filesystem_id);
- // Cracks the given |virtual_path| (which should look like
- // "/<filesystem_id>/<registered_name>/<relative_path>") and populates
- // the |filesystem_id| and |path| if the embedded <filesystem_id>
- // is registered to this context. |root_path| is also populated to have
- // the registered root (toplevel) file info for the |virtual_path|.
+ // 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 filesystem_id
+ // 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 |virtual_path| has no
- // <relative_path> part (i.e. pointing to the virtual root).
+ // 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* filesystem_id,
+ std::string* id_or_name,
FileSystemType* type,
FilePath* path) const;
@@ -160,49 +217,8 @@ class FILEAPI_EXPORT IsolatedContext {
private:
friend struct base::DefaultLazyInstanceTraits<IsolatedContext>;
- // Represents each isolated file system instance.
- class Instance {
- public:
- // For a single-path 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);
-
- // For a multi-paths 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);
-
- ~Instance();
-
- FileSystemType type() const { return type_; }
- const FileInfo& file_info() const { return file_info_; }
- const std::set<FileInfo>& files() const { return files_; }
- int ref_counts() const { return ref_counts_; }
-
- void AddRef() { ++ref_counts_; }
- void RemoveRef() { --ref_counts_; }
-
- bool ResolvePathForName(const std::string& name, FilePath* path) const;
-
- // Returns true if the instance is a single-path instance.
- bool IsSinglePathInstance() const;
-
- private:
- const FileSystemType type_;
-
- // For single-path instance.
- const FileInfo file_info_;
-
- // For multiple-path instance (e.g. dragged file system).
- const std::set<FileInfo> files_;
-
- // Reference counts. Note that an isolated filesystem is created with ref==0
- // and will get deleted when the ref count reaches <=0.
- int ref_counts_;
-
- DISALLOW_COPY_AND_ASSIGN(Instance);
- };
+ // Represents each file system instance (defined in the .cc).
+ class Instance;
typedef std::map<std::string, Instance*> IDToInstance;
diff --git a/webkit/fileapi/isolated_mount_point_provider.cc b/webkit/fileapi/isolated_mount_point_provider.cc
index a54f8c7..63c6d09df 100644
--- a/webkit/fileapi/isolated_mount_point_provider.cc
+++ b/webkit/fileapi/isolated_mount_point_provider.cc
@@ -103,6 +103,7 @@ FileSystemFileUtil* IsolatedMountPointProvider::GetFileUtil(
FileSystemType type) {
switch (type) {
case kFileSystemTypeIsolated:
+ case kFileSystemTypeNativeLocal:
return isolated_file_util_.get();
case kFileSystemTypeDragged:
return dragged_file_util_.get();
@@ -113,11 +114,7 @@ FileSystemFileUtil* IsolatedMountPointProvider::GetFileUtil(
return device_media_file_util_.get();
#endif
- case kFileSystemTypeTemporary:
- case kFileSystemTypePersistent:
- case kFileSystemTypeExternal:
- case kFileSystemTypeTest:
- case kFileSystemTypeUnknown:
+ default:
NOTREACHED();
}
return NULL;
@@ -126,8 +123,7 @@ FileSystemFileUtil* IsolatedMountPointProvider::GetFileUtil(
FilePath IsolatedMountPointProvider::GetPathForPermissionsCheck(
const FilePath& virtual_path) const {
// For isolated filesystems we only check per-filesystem permissions.
- NOTREACHED();
- return virtual_path;
+ return FilePath();
}
FileSystemOperationInterface*
diff --git a/webkit/fileapi/local_file_system_operation.cc b/webkit/fileapi/local_file_system_operation.cc
index 2f5a5e7..a0f73b8 100644
--- a/webkit/fileapi/local_file_system_operation.cc
+++ b/webkit/fileapi/local_file_system_operation.cc
@@ -722,7 +722,8 @@ base::PlatformFileError LocalFileSystemOperation::SetUp(
return base::PLATFORM_FILE_ERROR_INVALID_URL;
if (!file_system_context()->GetMountPointProvider(
- url.type())->IsAccessAllowed(url.origin(), url.type(), url.path()))
+ url.type())->IsAccessAllowed(url.origin(), url.type(),
+ url.virtual_path()))
return base::PLATFORM_FILE_ERROR_SECURITY;
DCHECK(file_util);