| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ | 5 #ifndef WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ |
| 6 #define WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ | 6 #define WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/file_path.h" | 14 #include "base/file_path.h" |
| 15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 18 #include "webkit/fileapi/file_system_types.h" | 18 #include "webkit/fileapi/file_system_types.h" |
| 19 #include "webkit/fileapi/fileapi_export.h" | 19 #include "webkit/fileapi/fileapi_export.h" |
| 20 | 20 |
| 21 namespace fileapi { | 21 namespace fileapi { |
| 22 | 22 |
| 23 // Manages isolated filename namespaces. A namespace is simply defined as a | 23 // Manages isolated filesystem namespaces. |
| 24 // set of file paths and corresponding filesystem ID. This context class is | 24 // This context class is a singleton and access to the context is |
| 25 // a singleton and access to the context is thread-safe (protected with a | 25 // thread-safe (protected with a lock). |
| 26 // lock). | 26 // |
| 27 // There are two types of filesystems managed by this context: |
| 28 // isolated and external. |
| 29 // The former is transient while the latter is persistent. |
| 30 // |
| 31 // * Transient isolated file systems have no name and are identified by |
| 32 // string 'filesystem ID', which usually just looks like random value. |
| 33 // This type of filesystem can be created on the fly and may go away |
| 34 // when it has no references from renderers. |
| 35 // Files in an isolated filesystem are registered with corresponding names |
| 36 // and identified by a filesystem URL like: |
| 37 // |
| 38 // filesystem:<origin>/isolated/<filesystem_id>/<name>/relative/path |
| 39 // |
| 40 // * Persistent external file systems are identified by 'mount name' |
| 41 // and are persisted until RevokeFileSystem is called. |
| 42 // Files in an external filesystem are identified by a filesystem URL like: |
| 43 // |
| 44 // filesystem:<origin>/external/<mount_name>/relative/path |
| 45 // |
| 46 // A filesystem instance is represented by IsolatedContext::Instance, and |
| 47 // managed as a map instance_map_ which maps from filesystem ID (or name) |
| 48 // to the instance. |
| 49 // |
| 27 // Some methods of this class are virtual just for mocking. | 50 // Some methods of this class are virtual just for mocking. |
| 51 // |
| 52 // TODO(kinuko): This should have a better name since this handles both |
| 53 // isolated and external file systems. |
| 54 // |
| 28 class FILEAPI_EXPORT IsolatedContext { | 55 class FILEAPI_EXPORT IsolatedContext { |
| 29 public: | 56 public: |
| 30 struct FILEAPI_EXPORT FileInfo { | 57 struct FILEAPI_EXPORT FileInfo { |
| 31 FileInfo(); | 58 FileInfo(); |
| 32 FileInfo(const std::string& name, const FilePath& path); | 59 FileInfo(const std::string& name, const FilePath& path); |
| 33 | 60 |
| 34 // The name to be used to register the file. The registered file can | 61 // The name to be used to register the file. The registered file can |
| 35 // be referred by a virtual path /<filesystem_id>/<name>. | 62 // be referred by a virtual path /<filesystem_id>/<name>. |
| 36 // The name should NOT contain a path separator '/'. | 63 // The name should NOT contain a path separator '/'. |
| 37 std::string name; | 64 std::string name; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 61 | 88 |
| 62 const std::set<FileInfo>& fileset() const { return fileset_; } | 89 const std::set<FileInfo>& fileset() const { return fileset_; } |
| 63 | 90 |
| 64 private: | 91 private: |
| 65 std::set<FileInfo> fileset_; | 92 std::set<FileInfo> fileset_; |
| 66 }; | 93 }; |
| 67 | 94 |
| 68 // The instance is lazily created per browser process. | 95 // The instance is lazily created per browser process. |
| 69 static IsolatedContext* GetInstance(); | 96 static IsolatedContext* GetInstance(); |
| 70 | 97 |
| 98 // Returns true if the given filesystem type is managed by IsolatedContext |
| 99 // (i.e. if the given |type| is Isolated or External). |
| 100 // TODO(kinuko): needs a better function name. |
| 101 static bool IsIsolatedType(FileSystemType type); |
| 102 |
| 71 // Registers a new isolated filesystem with the given FileInfoSet |files| | 103 // Registers a new isolated filesystem with the given FileInfoSet |files| |
| 72 // and returns the new filesystem_id. The files are registered with their | 104 // and returns the new filesystem_id. The files are registered with their |
| 73 // register_name as their keys so that later we can resolve the full paths | 105 // register_name as their keys so that later we can resolve the full paths |
| 74 // for the given name. We only expose the name and the ID for the | 106 // for the given name. We only expose the name and the ID for the |
| 75 // newly created filesystem to the renderer for the sake of security. | 107 // newly created filesystem to the renderer for the sake of security. |
| 76 // | 108 // |
| 77 // The renderer will be sending filesystem requests with a virtual path like | 109 // The renderer will be sending filesystem requests with a virtual path like |
| 78 // '/<filesystem_id>/<registered_name>/<relative_path_from_the_dropped_path>' | 110 // '/<filesystem_id>/<registered_name>/<relative_path_from_the_dropped_path>' |
| 79 // for which we could crack in the browser process by calling | 111 // for which we could crack in the browser process by calling |
| 80 // CrackIsolatedPath to get the full path. | 112 // CrackIsolatedPath to get the full path. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 94 // Registers a new isolated filesystem for a given |path| of filesystem | 126 // Registers a new isolated filesystem for a given |path| of filesystem |
| 95 // |type| filesystem and returns a new filesystem ID. | 127 // |type| filesystem and returns a new filesystem ID. |
| 96 // |path| must be an absolute path which has no parent references ('..'). | 128 // |path| must be an absolute path which has no parent references ('..'). |
| 97 // If |register_name| is non-null and has non-empty string the path is | 129 // If |register_name| is non-null and has non-empty string the path is |
| 98 // registered as the given |register_name|, otherwise it is populated | 130 // registered as the given |register_name|, otherwise it is populated |
| 99 // with the name internally assigned to the path. | 131 // with the name internally assigned to the path. |
| 100 std::string RegisterFileSystemForPath(FileSystemType type, | 132 std::string RegisterFileSystemForPath(FileSystemType type, |
| 101 const FilePath& path, | 133 const FilePath& path, |
| 102 std::string* register_name); | 134 std::string* register_name); |
| 103 | 135 |
| 104 // Revokes the filesystem |filesystem_id| | 136 #if defined(OS_CHROMEOS) |
| 137 // Registers a new named external filesystem. |
| 138 // The |path| is registered as the root path of the mount point which |
| 139 // is identified by a URL "filesystem:.../external/mount_name". |
| 140 // |
| 141 // For example, if the path "/media/removable" is registered with |
| 142 // the mount_name "removable", a filesystem URL like |
| 143 // "filesystem:.../external/removable/a/b" will be resolved as |
| 144 // "/media/removable/a/b". |
| 145 // |
| 146 // The |mount_name| should NOT contain a path separator '/'. |
| 147 // Returns false if the given name is already registered. |
| 148 // |
| 149 // An external file system registered by this method can be revoked |
| 150 // by calling RevokeFileSystem with |mount_name|. |
| 151 bool RegisterExternalFileSystem(const std::string& mount_name, |
| 152 FileSystemType type, |
| 153 const FilePath& path); |
| 154 |
| 155 // Returns a set of FilePath (of <mount_name, path>) registered as external. |
| 156 std::vector<FileInfo> GetExternalMountPoints() const; |
| 157 #endif |
| 158 |
| 159 // Revokes the filesystem |filesystem_id|. |
| 105 // Returns false if the |filesystem_id| is not (no longer) registered. | 160 // Returns false if the |filesystem_id| is not (no longer) registered. |
| 106 bool RevokeFileSystem(const std::string& filesystem_id); | 161 bool RevokeFileSystem(const std::string& filesystem_id); |
| 107 | 162 |
| 108 // Revokes all filesystem(s) registered for the given path. | 163 // Revokes all filesystem(s) registered for the given path. |
| 109 // This is assumed to be called when the registered path becomes | 164 // This is assumed to be called when the registered path becomes |
| 110 // globally invalid, e.g. when a device for the path is detached. | 165 // globally invalid, e.g. when a device for the path is detached. |
| 111 // | 166 // |
| 112 // Note that this revokes the filesystem no matter how many references it has. | 167 // Note that this revokes the filesystem no matter how many references it has. |
| 113 // It is ok to call this for the path that has no associated filesystems. | 168 // It is ok to call this for the path that has no associated filesystems. |
| 114 // Note that this only works for the filesystems registered by | 169 // Note that this only works for the filesystems registered by |
| 115 // |RegisterFileSystemForPath|. | 170 // |RegisterFileSystemForPath|. |
| 116 void RevokeFileSystemByPath(const FilePath& path); | 171 void RevokeFileSystemByPath(const FilePath& path); |
| 117 | 172 |
| 118 // Adds a reference to a filesystem specified by the given filesystem_id. | 173 // Adds a reference to a filesystem specified by the given filesystem_id. |
| 119 void AddReference(const std::string& filesystem_id); | 174 void AddReference(const std::string& filesystem_id); |
| 120 | 175 |
| 121 // Removes a reference to a filesystem specified by the given filesystem_id. | 176 // Removes a reference to a filesystem specified by the given filesystem_id. |
| 122 // If the reference count reaches 0 the isolated context gets destroyed. | 177 // If the reference count reaches 0 the isolated context gets destroyed. |
| 123 // It is ok to call this on the filesystem that has been already deleted | 178 // It is ok to call this on the filesystem that has been already deleted |
| 124 // (e.g. by RevokeFileSystemByPath). | 179 // (e.g. by RevokeFileSystemByPath). |
| 125 void RemoveReference(const std::string& filesystem_id); | 180 void RemoveReference(const std::string& filesystem_id); |
| 126 | 181 |
| 127 // Cracks the given |virtual_path| (which should look like | 182 // Cracks the given |virtual_path| (which is the path part of a filesystem URL |
| 128 // "/<filesystem_id>/<registered_name>/<relative_path>") and populates | 183 // without '/isolated' or '/external' prefix) and populates the |
| 129 // the |filesystem_id| and |path| if the embedded <filesystem_id> | 184 // |id_or_name|, |type|, and |path| if the <id_or_name> part embedded in |
| 130 // is registered to this context. |root_path| is also populated to have | 185 // the |virtual_path| (i.e. the first component of the |virtual_path|) is a |
| 131 // the registered root (toplevel) file info for the |virtual_path|. | 186 // valid registered filesystem ID or mount name for an isolated or external |
| 187 // filesystem. |
| 132 // | 188 // |
| 133 // Returns false if the given virtual_path or the cracked filesystem_id | 189 // Returns false if the given virtual_path or the cracked id_or_name |
| 134 // is not valid. | 190 // is not valid. |
| 135 // | 191 // |
| 136 // Note that |path| is set to empty paths if |virtual_path| has no | 192 // Note that |path| is set to empty paths if the filesystem type is isolated |
| 137 // <relative_path> part (i.e. pointing to the virtual root). | 193 // and |virtual_path| has no <relative_path> part (i.e. pointing to the |
| 194 // virtual root). |
| 138 bool CrackIsolatedPath(const FilePath& virtual_path, | 195 bool CrackIsolatedPath(const FilePath& virtual_path, |
| 139 std::string* filesystem_id, | 196 std::string* id_or_name, |
| 140 FileSystemType* type, | 197 FileSystemType* type, |
| 141 FilePath* path) const; | 198 FilePath* path) const; |
| 142 | 199 |
| 143 // Returns a set of dragged FileInfo's registered for the |filesystem_id|. | 200 // Returns a set of dragged FileInfo's registered for the |filesystem_id|. |
| 144 // The filesystem_id must be pointing to a dragged file system | 201 // The filesystem_id must be pointing to a dragged file system |
| 145 // (i.e. must be the one registered by RegisterDraggedFileSystem). | 202 // (i.e. must be the one registered by RegisterDraggedFileSystem). |
| 146 // Returns false if the |filesystem_id| is not valid. | 203 // Returns false if the |filesystem_id| is not valid. |
| 147 bool GetDraggedFileInfo(const std::string& filesystem_id, | 204 bool GetDraggedFileInfo(const std::string& filesystem_id, |
| 148 std::vector<FileInfo>* files) const; | 205 std::vector<FileInfo>* files) const; |
| 149 | 206 |
| 150 // Returns the file path registered for the |filesystem_id|. | 207 // Returns the file path registered for the |filesystem_id|. |
| 151 // The filesystem_id must NOT be pointing to a dragged file system | 208 // The filesystem_id must NOT be pointing to a dragged file system |
| 152 // (i.e. must be the one registered by RegisterFileSystemForPath). | 209 // (i.e. must be the one registered by RegisterFileSystemForPath). |
| 153 // Returns false if the |filesystem_id| is not valid. | 210 // Returns false if the |filesystem_id| is not valid. |
| 154 bool GetRegisteredPath(const std::string& filesystem_id, | 211 bool GetRegisteredPath(const std::string& filesystem_id, |
| 155 FilePath* path) const; | 212 FilePath* path) const; |
| 156 | 213 |
| 157 // Returns the virtual root path that looks like /<filesystem_id>. | 214 // Returns the virtual root path that looks like /<filesystem_id>. |
| 158 FilePath CreateVirtualRootPath(const std::string& filesystem_id) const; | 215 FilePath CreateVirtualRootPath(const std::string& filesystem_id) const; |
| 159 | 216 |
| 160 private: | 217 private: |
| 161 friend struct base::DefaultLazyInstanceTraits<IsolatedContext>; | 218 friend struct base::DefaultLazyInstanceTraits<IsolatedContext>; |
| 162 | 219 |
| 163 // Represents each isolated file system instance. | 220 // Represents each file system instance (defined in the .cc). |
| 164 class Instance { | 221 class Instance; |
| 165 public: | |
| 166 // For a single-path file system, which could be registered by | |
| 167 // IsolatedContext::RegisterFileSystemForPath(). | |
| 168 // Most of isolated file system contexts should be of this type. | |
| 169 Instance(FileSystemType type, const FileInfo& file_info); | |
| 170 | |
| 171 // For a multi-paths file system. As of writing only file system | |
| 172 // type which could have multi-paths is Dragged file system, and | |
| 173 // could be registered by IsolatedContext::RegisterDraggedFileSystem(). | |
| 174 Instance(FileSystemType type, const std::set<FileInfo>& files); | |
| 175 | |
| 176 ~Instance(); | |
| 177 | |
| 178 FileSystemType type() const { return type_; } | |
| 179 const FileInfo& file_info() const { return file_info_; } | |
| 180 const std::set<FileInfo>& files() const { return files_; } | |
| 181 int ref_counts() const { return ref_counts_; } | |
| 182 | |
| 183 void AddRef() { ++ref_counts_; } | |
| 184 void RemoveRef() { --ref_counts_; } | |
| 185 | |
| 186 bool ResolvePathForName(const std::string& name, FilePath* path) const; | |
| 187 | |
| 188 // Returns true if the instance is a single-path instance. | |
| 189 bool IsSinglePathInstance() const; | |
| 190 | |
| 191 private: | |
| 192 const FileSystemType type_; | |
| 193 | |
| 194 // For single-path instance. | |
| 195 const FileInfo file_info_; | |
| 196 | |
| 197 // For multiple-path instance (e.g. dragged file system). | |
| 198 const std::set<FileInfo> files_; | |
| 199 | |
| 200 // Reference counts. Note that an isolated filesystem is created with ref==0 | |
| 201 // and will get deleted when the ref count reaches <=0. | |
| 202 int ref_counts_; | |
| 203 | |
| 204 DISALLOW_COPY_AND_ASSIGN(Instance); | |
| 205 }; | |
| 206 | 222 |
| 207 typedef std::map<std::string, Instance*> IDToInstance; | 223 typedef std::map<std::string, Instance*> IDToInstance; |
| 208 | 224 |
| 209 // Reverse map from registered path to IDs. | 225 // Reverse map from registered path to IDs. |
| 210 typedef std::map<FilePath, std::set<std::string> > PathToID; | 226 typedef std::map<FilePath, std::set<std::string> > PathToID; |
| 211 | 227 |
| 212 // Obtain an instance of this class via GetInstance(). | 228 // Obtain an instance of this class via GetInstance(). |
| 213 IsolatedContext(); | 229 IsolatedContext(); |
| 214 ~IsolatedContext(); | 230 ~IsolatedContext(); |
| 215 | 231 |
| 216 // Unregisters a file system of given |filesystem_id|. Must be called with | 232 // Unregisters a file system of given |filesystem_id|. Must be called with |
| 217 // lock_ held. Returns true if the file system is unregistered. | 233 // lock_ held. Returns true if the file system is unregistered. |
| 218 bool UnregisterFileSystem(const std::string& filesystem_id); | 234 bool UnregisterFileSystem(const std::string& filesystem_id); |
| 219 | 235 |
| 220 // Returns a new filesystem_id. Called with lock. | 236 // Returns a new filesystem_id. Called with lock. |
| 221 std::string GetNewFileSystemId() const; | 237 std::string GetNewFileSystemId() const; |
| 222 | 238 |
| 223 // This lock needs to be obtained when accessing the instance_map_. | 239 // This lock needs to be obtained when accessing the instance_map_. |
| 224 mutable base::Lock lock_; | 240 mutable base::Lock lock_; |
| 225 | 241 |
| 226 IDToInstance instance_map_; | 242 IDToInstance instance_map_; |
| 227 PathToID path_to_id_map_; | 243 PathToID path_to_id_map_; |
| 228 | 244 |
| 229 DISALLOW_COPY_AND_ASSIGN(IsolatedContext); | 245 DISALLOW_COPY_AND_ASSIGN(IsolatedContext); |
| 230 }; | 246 }; |
| 231 | 247 |
| 232 } // namespace fileapi | 248 } // namespace fileapi |
| 233 | 249 |
| 234 #endif // WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ | 250 #endif // WEBKIT_FILEAPI_ISOLATED_CONTEXT_H_ |
| OLD | NEW |