• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
quota_manager_proxy()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 
default_file_task_runner()229   base::SequencedTaskRunner* default_file_task_runner() {
230     return default_file_task_runner_.get();
231   }
232 
operation_runner()233   FileSystemOperationRunner* operation_runner() {
234     return operation_runner_.get();
235   }
236 
partition_path()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 
sandbox_delegate()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.
sandbox_backend()324   SandboxFileSystemBackend* sandbox_backend() const {
325     return sandbox_backend_.get();
326   }
327 
328   // Used only by test code.
plugin_private_backend()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 {
DestructDefaultContextDeleter375   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