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