1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WEBKIT_BROWSER_FILEAPI_EXTERNAL_MOUNT_POINTS_H_ 6 #define WEBKIT_BROWSER_FILEAPI_EXTERNAL_MOUNT_POINTS_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/memory/ref_counted.h" 13 #include "base/synchronization/lock.h" 14 #include "webkit/browser/fileapi/mount_points.h" 15 #include "webkit/browser/webkit_storage_browser_export.h" 16 #include "webkit/common/fileapi/file_system_types.h" 17 18 namespace base { 19 class FilePath; 20 } 21 22 namespace fileapi { 23 class FileSystemURL; 24 } 25 26 namespace fileapi { 27 28 // Manages external filesystem namespaces that are identified by 'mount name' 29 // and are persisted until RevokeFileSystem is called. 30 // Files in an external filesystem are identified by a filesystem URL like: 31 // 32 // filesystem:<origin>/external/<mount_name>/relative/path 33 // 34 class WEBKIT_STORAGE_BROWSER_EXPORT ExternalMountPoints 35 : public base::RefCountedThreadSafe<ExternalMountPoints>, 36 public MountPoints { 37 public: 38 static ExternalMountPoints* GetSystemInstance(); 39 static scoped_refptr<ExternalMountPoints> CreateRefCounted(); 40 41 // Registers a new named external filesystem. 42 // The |path| is registered as the root path of the mount point which 43 // is identified by a URL "filesystem:.../external/mount_name". 44 // 45 // For example, if the path "/media/removable" is registered with 46 // the mount_name "removable", a filesystem URL like 47 // "filesystem:.../external/removable/a/b" will be resolved as 48 // "/media/removable/a/b". 49 // 50 // The |mount_name| should NOT contain a path separator '/'. 51 // Returns false if the given name is already registered. 52 // 53 // Overlapping mount points in a single MountPoints instance are not allowed. 54 // Adding mount point whose path overlaps with an existing mount point will 55 // fail. 56 // 57 // If not empty, |path| must be absolute. It is allowed for the path to be 58 // empty, but |GetVirtualPath| will not work for those mount points. 59 // 60 // An external file system registered by this method can be revoked 61 // by calling RevokeFileSystem with |mount_name|. 62 bool RegisterFileSystem(const std::string& mount_name, 63 FileSystemType type, 64 const base::FilePath& path); 65 66 // MountPoints overrides. 67 virtual bool HandlesFileSystemMountType(FileSystemType type) const OVERRIDE; 68 virtual bool RevokeFileSystem(const std::string& mount_name) OVERRIDE; 69 virtual bool GetRegisteredPath(const std::string& mount_name, 70 base::FilePath* path) const OVERRIDE; 71 virtual bool CrackVirtualPath(const base::FilePath& virtual_path, 72 std::string* mount_name, 73 FileSystemType* type, 74 base::FilePath* path) const OVERRIDE; 75 virtual FileSystemURL CrackURL(const GURL& url) const OVERRIDE; 76 virtual FileSystemURL CreateCrackedFileSystemURL( 77 const GURL& origin, 78 FileSystemType type, 79 const base::FilePath& path) const OVERRIDE; 80 81 // Returns a list of registered MountPointInfos (of <mount_name, path>). 82 void AddMountPointInfosTo(std::vector<MountPointInfo>* mount_points) const; 83 84 // Converts a path on a registered file system to virtual path relative to the 85 // file system root. E.g. if 'Downloads' file system is mapped to 86 // '/usr/local/home/Downloads', and |absolute| path is set to 87 // '/usr/local/home/Downloads/foo', the method will set |virtual_path| to 88 // 'Downloads/foo'. 89 // Returns false if the path cannot be resolved (e.g. if the path is not 90 // part of any registered filesystem). 91 // 92 // Returned virtual_path will have normalized path separators. 93 bool GetVirtualPath(const base::FilePath& absolute_path, 94 base::FilePath* virtual_path) const; 95 96 // Returns the virtual root path that looks like /<mount_name>. 97 base::FilePath CreateVirtualRootPath(const std::string& mount_name) const; 98 99 FileSystemURL CreateExternalFileSystemURL( 100 const GURL& origin, 101 const std::string& mount_name, 102 const base::FilePath& path) const; 103 104 private: 105 friend class base::RefCountedThreadSafe<ExternalMountPoints>; 106 107 // Represents each file system instance (defined in the .cc). 108 class Instance; 109 110 typedef std::map<std::string, Instance*> NameToInstance; 111 112 // Reverse map from registered path to its corresponding mount name. 113 typedef std::map<base::FilePath, std::string> PathToName; 114 115 // Use |GetSystemInstance| of |CreateRefCounted| to get an instance. 116 ExternalMountPoints(); 117 virtual ~ExternalMountPoints(); 118 119 // MountPoint overrides. 120 virtual FileSystemURL CrackFileSystemURL( 121 const FileSystemURL& url) const OVERRIDE; 122 123 // Performs sanity checks on the new mount point. 124 // Checks the following: 125 // - there is no registered mount point with mount_name 126 // - path does not contain a reference to a parent 127 // - path is absolute 128 // - path does not overlap with an existing mount point path. 129 // 130 // |lock_| should be taken before calling this method. 131 bool ValidateNewMountPoint(const std::string& mount_name, 132 const base::FilePath& path); 133 134 // This lock needs to be obtained when accessing the instance_map_. 135 mutable base::Lock lock_; 136 137 NameToInstance instance_map_; 138 PathToName path_to_name_map_; 139 140 DISALLOW_COPY_AND_ASSIGN(ExternalMountPoints); 141 }; 142 143 // Registers a scoped external filesystem which gets revoked when it scopes out. 144 class WEBKIT_STORAGE_BROWSER_EXPORT ScopedExternalFileSystem { 145 public: 146 ScopedExternalFileSystem(const std::string& mount_name, 147 FileSystemType type, 148 const base::FilePath& path); 149 ~ScopedExternalFileSystem(); 150 151 base::FilePath GetVirtualRootPath() const; 152 153 private: 154 const std::string mount_name_; 155 }; 156 157 } // namespace fileapi 158 159 #endif // WEBKIT_BROWSER_FILEAPI_EXTERNAL_MOUNT_POINTS_H_ 160