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 3 // found in the LICENSE file. 4 5 #ifndef WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_ 6 #define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_vector.h" 16 #include "base/platform_file.h" 17 #include "base/sequenced_task_runner_helpers.h" 18 #include "webkit/browser/fileapi/file_system_url.h" 19 #include "webkit/browser/fileapi/open_file_system_mode.h" 20 #include "webkit/browser/fileapi/sandbox_context.h" 21 #include "webkit/browser/fileapi/task_runner_bound_observer_list.h" 22 #include "webkit/browser/webkit_storage_browser_export.h" 23 #include "webkit/common/fileapi/file_system_types.h" 24 25 namespace base { 26 class FilePath; 27 class SequencedTaskRunner; 28 class SingleThreadTaskRunner; 29 } 30 31 namespace chrome { 32 class NativeMediaFileUtilTest; 33 } 34 35 namespace quota { 36 class QuotaManagerProxy; 37 class SpecialStoragePolicy; 38 } 39 40 namespace webkit_blob { 41 class BlobURLRequestJobTest; 42 class FileStreamReader; 43 } 44 45 namespace fileapi { 46 47 class AsyncFileUtil; 48 class CopyOrMoveFileValidatorFactory; 49 class ExternalFileSystemBackend; 50 class ExternalMountPoints; 51 class FileStreamWriter; 52 class FileSystemFileUtil; 53 class FileSystemBackend; 54 class FileSystemOperation; 55 class FileSystemOperationRunner; 56 class FileSystemOptions; 57 class FileSystemQuotaUtil; 58 class FileSystemURL; 59 class IsolatedFileSystemBackend; 60 class MountPoints; 61 class SandboxFileSystemBackend; 62 63 struct DefaultContextDeleter; 64 65 // This class keeps and provides a file system context for FileSystem API. 66 // An instance of this class is created and owned by profile. 67 class WEBKIT_STORAGE_BROWSER_EXPORT FileSystemContext 68 : public base::RefCountedThreadSafe<FileSystemContext, 69 DefaultContextDeleter> { 70 public: 71 // Returns file permission policy we should apply for the given |type|. 72 // The return value must be bitwise-or'd of FilePermissionPolicy. 73 // 74 // Note: if a part of a filesystem is returned via 'Isolated' mount point, 75 // its per-filesystem permission overrides the underlying filesystem's 76 // permission policy. 77 static int GetPermissionPolicy(FileSystemType type); 78 79 // file_task_runner is used as default TaskRunner. 80 // Unless a FileSystemBackend is overridden in CreateFileSystemOperation, 81 // it is used for all file operations and file related meta operations. 82 // The code assumes that file_task_runner->RunsTasksOnCurrentThread() 83 // returns false if the current task is not running on the thread that allows 84 // blocking file operations (like SequencedWorkerPool implementation does). 85 // 86 // |external_mount_points| contains non-system external mount points available 87 // in the context. If not NULL, it will be used during URL cracking. 88 // |external_mount_points| may be NULL only on platforms different from 89 // ChromeOS (i.e. platforms that don't use external_mount_point_provider). 90 // 91 // |additional_backends| are added to the internal backend map 92 // to serve filesystem requests for non-regular types. 93 // If none is given, this context only handles HTML5 Sandbox FileSystem 94 // and Drag-and-drop Isolated FileSystem requests. 95 FileSystemContext( 96 base::SingleThreadTaskRunner* io_task_runner, 97 base::SequencedTaskRunner* file_task_runner, 98 ExternalMountPoints* external_mount_points, 99 quota::SpecialStoragePolicy* special_storage_policy, 100 quota::QuotaManagerProxy* quota_manager_proxy, 101 ScopedVector<FileSystemBackend> additional_backends, 102 const base::FilePath& partition_path, 103 const FileSystemOptions& options); 104 105 bool DeleteDataForOriginOnFileThread(const GURL& origin_url); 106 107 quota::QuotaManagerProxy* quota_manager_proxy() const { 108 return quota_manager_proxy_.get(); 109 } 110 111 // Discards inflight operations in the operation runner. 112 void Shutdown(); 113 114 // Returns a quota util for a given filesystem type. This may 115 // return NULL if the type does not support the usage tracking or 116 // it is not a quota-managed storage. 117 FileSystemQuotaUtil* GetQuotaUtil(FileSystemType type) const; 118 119 // Returns the appropriate AsyncFileUtil instance for the given |type|. 120 AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) const; 121 122 // Returns the appropriate FileUtil instance for the given |type|. 123 // This may return NULL if it is given an invalid type or the filesystem 124 // does not support synchronous file operations. 125 FileSystemFileUtil* GetFileUtil(FileSystemType type) const; 126 127 // Returns the appropriate CopyOrMoveFileValidatorFactory for the given 128 // |type|. If |error_code| is PLATFORM_FILE_OK and the result is NULL, 129 // then no validator is required. 130 CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory( 131 FileSystemType type, base::PlatformFileError* error_code) const; 132 133 // Returns the file system backend instance for the given |type|. 134 // This may return NULL if it is given an invalid or unsupported filesystem 135 // type. 136 FileSystemBackend* GetFileSystemBackend( 137 FileSystemType type) const; 138 139 // Returns true for sandboxed filesystems. Currently this does 140 // the same as GetQuotaUtil(type) != NULL. (In an assumption that 141 // all sandboxed filesystems must cooperate with QuotaManager so that 142 // they can get deleted) 143 bool IsSandboxFileSystem(FileSystemType type) const; 144 145 // Returns observers for the given filesystem type. 146 const UpdateObserverList* GetUpdateObservers(FileSystemType type) const; 147 const AccessObserverList* GetAccessObservers(FileSystemType type) const; 148 149 // Returns all registered filesystem types. 150 void GetFileSystemTypes(std::vector<FileSystemType>* types) const; 151 152 // Returns a FileSystemBackend instance for external filesystem 153 // type, which is used only by chromeos for now. This is equivalent to 154 // calling GetFileSystemBackend(kFileSystemTypeExternal). 155 ExternalFileSystemBackend* external_backend() const; 156 157 // Used for OpenFileSystem. 158 typedef base::Callback<void(base::PlatformFileError result, 159 const std::string& name, 160 const GURL& root)> OpenFileSystemCallback; 161 162 // Used for DeleteFileSystem. 163 typedef base::Callback<void(base::PlatformFileError result)> 164 DeleteFileSystemCallback; 165 166 // Opens the filesystem for the given |origin_url| and |type|, and dispatches 167 // |callback| on completion. 168 // If |create| is true this may actually set up a filesystem instance 169 // (e.g. by creating the root directory or initializing the database 170 // entry etc). 171 void OpenFileSystem( 172 const GURL& origin_url, 173 FileSystemType type, 174 OpenFileSystemMode mode, 175 const OpenFileSystemCallback& callback); 176 177 // Deletes the filesystem for the given |origin_url| and |type|. This should 178 // be called on the IO Thread. 179 void DeleteFileSystem( 180 const GURL& origin_url, 181 FileSystemType type, 182 const DeleteFileSystemCallback& callback); 183 184 // Creates new FileStreamReader instance to read a file pointed by the given 185 // filesystem URL |url| starting from |offset|. |expected_modification_time| 186 // specifies the expected last modification if the value is non-null, the 187 // reader will check the underlying file's actual modification time to see if 188 // the file has been modified, and if it does any succeeding read operations 189 // should fail with ERR_UPLOAD_FILE_CHANGED error. 190 // This method internally cracks the |url|, get an appropriate 191 // FileSystemBackend for the URL and call the backend's CreateFileReader. 192 // The resolved FileSystemBackend could perform further specialization 193 // depending on the filesystem type pointed by the |url|. 194 scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader( 195 const FileSystemURL& url, 196 int64 offset, 197 const base::Time& expected_modification_time); 198 199 // Creates new FileStreamWriter instance to write into a file pointed by 200 // |url| from |offset|. 201 scoped_ptr<FileStreamWriter> CreateFileStreamWriter( 202 const FileSystemURL& url, 203 int64 offset); 204 205 // Creates a new FileSystemOperationRunner. 206 scoped_ptr<FileSystemOperationRunner> CreateFileSystemOperationRunner(); 207 208 base::SequencedTaskRunner* default_file_task_runner() { 209 return default_file_task_runner_.get(); 210 } 211 212 FileSystemOperationRunner* operation_runner() { 213 return operation_runner_.get(); 214 } 215 216 const base::FilePath& partition_path() const { return partition_path_; } 217 218 // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from |url|. 219 FileSystemURL CrackURL(const GURL& url) const; 220 // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from method 221 // arguments. 222 FileSystemURL CreateCrackedFileSystemURL(const GURL& origin, 223 FileSystemType type, 224 const base::FilePath& path) const; 225 226 #if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD) 227 // Used only on ChromeOS for now. 228 void EnableTemporaryFileSystemInIncognito(); 229 #endif 230 231 SandboxContext* sandbox_context() { return sandbox_context_.get(); } 232 233 private: 234 typedef std::map<FileSystemType, FileSystemBackend*> 235 FileSystemBackendMap; 236 237 // For CreateFileSystemOperation. 238 friend class FileSystemOperationRunner; 239 240 // For sandbox_backend(). 241 friend class SandboxFileSystemTestHelper; 242 243 // Deleters. 244 friend struct DefaultContextDeleter; 245 friend class base::DeleteHelper<FileSystemContext>; 246 friend class base::RefCountedThreadSafe<FileSystemContext, 247 DefaultContextDeleter>; 248 ~FileSystemContext(); 249 250 void DeleteOnCorrectThread() const; 251 252 // Creates a new FileSystemOperation instance by getting an appropriate 253 // FileSystemBackend for |url| and calling the backend's corresponding 254 // CreateFileSystemOperation method. 255 // The resolved FileSystemBackend could perform further specialization 256 // depending on the filesystem type pointed by the |url|. 257 // 258 // Called by FileSystemOperationRunner. 259 FileSystemOperation* CreateFileSystemOperation( 260 const FileSystemURL& url, 261 base::PlatformFileError* error_code); 262 263 // For non-cracked isolated and external mount points, returns a FileSystemURL 264 // created by cracking |url|. The url is cracked using MountPoints registered 265 // as |url_crackers_|. If the url cannot be cracked, returns invalid 266 // FileSystemURL. 267 // 268 // If the original url does not point to an isolated or external filesystem, 269 // returns the original url, without attempting to crack it. 270 FileSystemURL CrackFileSystemURL(const FileSystemURL& url) const; 271 272 // For initial backend_map construction. This must be called only from 273 // the constructor. 274 void RegisterBackend(FileSystemBackend* backend); 275 276 // Returns a FileSystemBackend, used only by test code. 277 SandboxFileSystemBackend* sandbox_backend() const { 278 return sandbox_backend_.get(); 279 } 280 281 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; 282 scoped_refptr<base::SequencedTaskRunner> default_file_task_runner_; 283 284 scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_; 285 286 scoped_ptr<SandboxContext> sandbox_context_; 287 288 // Regular file system backends. 289 scoped_ptr<SandboxFileSystemBackend> sandbox_backend_; 290 scoped_ptr<IsolatedFileSystemBackend> isolated_backend_; 291 292 // Additional file system backends. 293 ScopedVector<FileSystemBackend> additional_backends_; 294 295 // Registered file system backends. 296 // The map must be constructed in the constructor since it can be accessed 297 // on multiple threads. 298 // This map itself doesn't retain each backend's ownership; ownerships 299 // of the backends are held by additional_backends_ or other scoped_ptr 300 // backend fields. 301 FileSystemBackendMap backend_map_; 302 303 // External mount points visible in the file system context (excluding system 304 // external mount points). 305 scoped_refptr<ExternalMountPoints> external_mount_points_; 306 307 // MountPoints used to crack FileSystemURLs. The MountPoints are ordered 308 // in order they should try to crack a FileSystemURL. 309 std::vector<MountPoints*> url_crackers_; 310 311 // The base path of the storage partition for this context. 312 const base::FilePath partition_path_; 313 314 scoped_ptr<FileSystemOperationRunner> operation_runner_; 315 316 DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext); 317 }; 318 319 struct DefaultContextDeleter { 320 static void Destruct(const FileSystemContext* context) { 321 context->DeleteOnCorrectThread(); 322 } 323 }; 324 325 } // namespace fileapi 326 327 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_ 328