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