Home | History | Annotate | Download | only in fileapi
      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 STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_
      6 #define STORAGE_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 "storage/browser/fileapi/file_system_url.h"
     19 #include "storage/browser/fileapi/open_file_system_mode.h"
     20 #include "storage/browser/fileapi/plugin_private_file_system_backend.h"
     21 #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
     22 #include "storage/browser/fileapi/task_runner_bound_observer_list.h"
     23 #include "storage/browser/storage_browser_export.h"
     24 #include "storage/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   // At most |max_bytes_to_read| can be fetched from the file stream reader.
    256   scoped_ptr<storage::FileStreamReader> CreateFileStreamReader(
    257       const FileSystemURL& url,
    258       int64 offset,
    259       int64 max_bytes_to_read,
    260       const base::Time& expected_modification_time);
    261 
    262   // Creates new FileStreamWriter instance to write into a file pointed by
    263   // |url| from |offset|.
    264   scoped_ptr<FileStreamWriter> CreateFileStreamWriter(
    265       const FileSystemURL& url,
    266       int64 offset);
    267 
    268   // Creates a new FileSystemOperationRunner.
    269   scoped_ptr<FileSystemOperationRunner> CreateFileSystemOperationRunner();
    270 
    271   base::SequencedTaskRunner* default_file_task_runner() {
    272     return default_file_task_runner_.get();
    273   }
    274 
    275   FileSystemOperationRunner* operation_runner() {
    276     return operation_runner_.get();
    277   }
    278 
    279   const base::FilePath& partition_path() const { return partition_path_; }
    280 
    281   // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from |url|.
    282   FileSystemURL CrackURL(const GURL& url) const;
    283   // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from method
    284   // arguments.
    285   FileSystemURL CreateCrackedFileSystemURL(const GURL& origin,
    286                                            FileSystemType type,
    287                                            const base::FilePath& path) const;
    288 
    289 #if defined(OS_CHROMEOS)
    290   // Used only on ChromeOS for now.
    291   void EnableTemporaryFileSystemInIncognito();
    292 #endif
    293 
    294   SandboxFileSystemBackendDelegate* sandbox_delegate() {
    295     return sandbox_delegate_.get();
    296   }
    297 
    298   // Returns true if the requested url is ok to be served.
    299   // (E.g. this returns false if the context is created for incognito mode)
    300   bool CanServeURLRequest(const FileSystemURL& url) const;
    301 
    302   // Returns true if a file in the file system should be flushed for each write
    303   // completion.
    304   bool ShouldFlushOnWriteCompletion(FileSystemType type) const;
    305 
    306   // This must be used to open 'plugin private' filesystem.
    307   // See "plugin_private_file_system_backend.h" for more details.
    308   void OpenPluginPrivateFileSystem(
    309       const GURL& origin_url,
    310       FileSystemType type,
    311       const std::string& filesystem_id,
    312       const std::string& plugin_id,
    313       OpenFileSystemMode mode,
    314       const StatusCallback& callback);
    315 
    316  private:
    317   typedef std::map<FileSystemType, FileSystemBackend*>
    318       FileSystemBackendMap;
    319 
    320   // For CreateFileSystemOperation.
    321   friend class FileSystemOperationRunner;
    322 
    323   // For sandbox_backend().
    324   friend class content::SandboxFileSystemTestHelper;
    325 
    326   // For plugin_private_backend().
    327   friend class content::PluginPrivateFileSystemBackendTest;
    328 
    329   // Deleters.
    330   friend struct DefaultContextDeleter;
    331   friend class base::DeleteHelper<FileSystemContext>;
    332   friend class base::RefCountedThreadSafe<FileSystemContext,
    333                                           DefaultContextDeleter>;
    334   ~FileSystemContext();
    335 
    336   void DeleteOnCorrectThread() const;
    337 
    338   // Creates a new FileSystemOperation instance by getting an appropriate
    339   // FileSystemBackend for |url| and calling the backend's corresponding
    340   // CreateFileSystemOperation method.
    341   // The resolved FileSystemBackend could perform further specialization
    342   // depending on the filesystem type pointed by the |url|.
    343   //
    344   // Called by FileSystemOperationRunner.
    345   FileSystemOperation* CreateFileSystemOperation(
    346       const FileSystemURL& url,
    347       base::File::Error* error_code);
    348 
    349   // For non-cracked isolated and external mount points, returns a FileSystemURL
    350   // created by cracking |url|. The url is cracked using MountPoints registered
    351   // as |url_crackers_|. If the url cannot be cracked, returns invalid
    352   // FileSystemURL.
    353   //
    354   // If the original url does not point to an isolated or external filesystem,
    355   // returns the original url, without attempting to crack it.
    356   FileSystemURL CrackFileSystemURL(const FileSystemURL& url) const;
    357 
    358   // For initial backend_map construction. This must be called only from
    359   // the constructor.
    360   void RegisterBackend(FileSystemBackend* backend);
    361 
    362   void DidOpenFileSystemForResolveURL(
    363       const FileSystemURL& url,
    364       const ResolveURLCallback& callback,
    365       const GURL& filesystem_root,
    366       const std::string& filesystem_name,
    367       base::File::Error error);
    368 
    369   // Returns a FileSystemBackend, used only by test code.
    370   SandboxFileSystemBackend* sandbox_backend() const {
    371     return sandbox_backend_.get();
    372   }
    373 
    374   // Used only by test code.
    375   PluginPrivateFileSystemBackend* plugin_private_backend() const {
    376     return plugin_private_backend_.get();
    377   }
    378 
    379   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
    380   scoped_refptr<base::SequencedTaskRunner> default_file_task_runner_;
    381 
    382   scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
    383 
    384   scoped_ptr<SandboxFileSystemBackendDelegate> sandbox_delegate_;
    385 
    386   // Regular file system backends.
    387   scoped_ptr<SandboxFileSystemBackend> sandbox_backend_;
    388   scoped_ptr<IsolatedFileSystemBackend> isolated_backend_;
    389 
    390   // Additional file system backends.
    391   scoped_ptr<PluginPrivateFileSystemBackend> plugin_private_backend_;
    392   ScopedVector<FileSystemBackend> additional_backends_;
    393 
    394   std::vector<URLRequestAutoMountHandler> auto_mount_handlers_;
    395 
    396   // Registered file system backends.
    397   // The map must be constructed in the constructor since it can be accessed
    398   // on multiple threads.
    399   // This map itself doesn't retain each backend's ownership; ownerships
    400   // of the backends are held by additional_backends_ or other scoped_ptr
    401   // backend fields.
    402   FileSystemBackendMap backend_map_;
    403 
    404   // External mount points visible in the file system context (excluding system
    405   // external mount points).
    406   scoped_refptr<ExternalMountPoints> external_mount_points_;
    407 
    408   // MountPoints used to crack FileSystemURLs. The MountPoints are ordered
    409   // in order they should try to crack a FileSystemURL.
    410   std::vector<MountPoints*> url_crackers_;
    411 
    412   // The base path of the storage partition for this context.
    413   const base::FilePath partition_path_;
    414 
    415   bool is_incognito_;
    416 
    417   scoped_ptr<FileSystemOperationRunner> operation_runner_;
    418 
    419   DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext);
    420 };
    421 
    422 struct DefaultContextDeleter {
    423   static void Destruct(const FileSystemContext* context) {
    424     context->DeleteOnCorrectThread();
    425   }
    426 };
    427 
    428 }  // namespace storage
    429 
    430 #endif  // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_
    431