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