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 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