Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Unified Diff: webkit/fileapi/external_mount_points.cc

Issue 11648027: Extract external file systems handling from isolated context. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webkit/fileapi/external_mount_points.cc
diff --git a/webkit/fileapi/external_mount_points.cc b/webkit/fileapi/external_mount_points.cc
new file mode 100644
index 0000000000000000000000000000000000000000..38e65fc463ffec8f15f95d3a99567c00caed690b
--- /dev/null
+++ b/webkit/fileapi/external_mount_points.cc
@@ -0,0 +1,286 @@
+// Copyright (c) 2012 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 fileapi {
+
+static base::LazyInstance<scoped_refptr<ExternalMountPoints> >::Leaky
+ g_external_mount_points = LAZY_INSTANCE_INITIALIZER;
+
+class ExternalMountPoints::Instance {
+ public:
+ // |remote_proxy| is allowed only for drive file system.
+ 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),
+ remote_proxy_(proxy) {
+ DCHECK(!proxy || (kFileSystemTypeDrive == type_));
+}
+
+ExternalMountPoints::Instance::~Instance() {}
+
+//--------------------------------------------------------------------------
+
+// static
+ExternalMountPoints* ExternalMountPoints::GetSystemInstance() {
+ if (!g_external_mount_points.Pointer()->get())
+ g_external_mount_points.Get() = new ExternalMountPoints(true);
+ return g_external_mount_points.Pointer()->get();
kinuko 2013/01/08 12:22:43 Hmm, this is not thread safe and we seem to be los
tbarzic 2013/01/09 01:26:34 Yeah, I was concerned about that too. I think the
+}
+
+// static
+scoped_refptr<ExternalMountPoints> ExternalMountPoints::CreateRefCounted() {
+ return new ExternalMountPoints(false);
+}
+
+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) {
+ base::AutoLock locker(lock_);
+
+ 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;
+}
+
+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::AppendMountPoints(
+ 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::CanCrackMountType(FileSystemType type) const {
+ return type == kFileSystemTypeExternal;
+}
+
+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::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(instance->path());
+ delete found->second;
+ instance_map_.erase(found);
+ return true;
+}
+
+FilePath ExternalMountPoints::CreateVirtualRootPath(
+ const std::string& mount_name) const {
+ return FilePath().AppendASCII(mount_name);
+}
+
+ExternalMountPoints::ExternalMountPoints(bool is_system_instance) {
kinuko 2013/01/08 12:22:43 Can we avoid using boolean here? (It's discouraged
tbarzic 2013/01/09 01:26:34 Done.
+#if defined(OS_CHROMEOS)
+ // Add default system mount points.
+ if (is_system_instance) {
+ RegisterFileSystem("archive",
+ kFileSystemTypeNativeLocal,
+ FilePath(FILE_PATH_LITERAL("/media/archive")));
+ RegisterFileSystem("removable",
+ kFileSystemTypeNativeLocal,
+ FilePath(FILE_PATH_LITERAL("/media/removable")));
+ RegisterFileSystem("oem",
+ 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)) {
+ RegisterFileSystem("Downloads",
+ kFileSystemTypeNativeLocal,
+ home_path.AppendASCII("Downloads"));
+ }
+ }
+#endif // defined(OS_CHROMEOS)
+}
+
+ExternalMountPoints::~ExternalMountPoints() {
+ STLDeleteContainerPairSecondPointers(instance_map_.begin(),
+ instance_map_.end());
+}
+
+bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name,
+ const FilePath& path) {
+ // 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);
+}
+
+bool ExternalMountPoints::GetVirtualPath(const FilePath& absolute_path,
+ FilePath* virtual_path) {
+ DCHECK(virtual_path);
+ base::AutoLock locker(lock_);
+ std::map<FilePath, std::string>::reverse_iterator iter(
+ path_to_name_map_.upper_bound(absolute_path));
+ if (iter == path_to_name_map_.rend())
+ return false;
+
+ *virtual_path = CreateVirtualRootPath(iter->second);
+ if (iter->first == absolute_path)
+ return true;
+ return iter->first.AppendRelativePath(absolute_path, virtual_path);
+}
+
+bool ExternalMountPoints::CrackExternalPath(const FilePath& virtual_path,
+ std::string* mount_name,
+ FileSystemType* type,
+ FilePath* path) const {
+ DCHECK(mount_name);
+ DCHECK(path);
+
+ // This should not contain any '..' references.
+ if (virtual_path.ReferencesParent())
+ return false;
+
+ // The virtual_path should comprise <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;
+}
+
+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

Powered by Google App Engine
This is Rietveld 408576698