• 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 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 
quota_manager_proxy()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 
default_file_task_runner()271   base::SequencedTaskRunner* default_file_task_runner() {
272     return default_file_task_runner_.get();
273   }
274 
operation_runner()275   FileSystemOperationRunner* operation_runner() {
276     return operation_runner_.get();
277   }
278 
partition_path()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 
sandbox_delegate()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.
sandbox_backend()370   SandboxFileSystemBackend* sandbox_backend() const {
371     return sandbox_backend_.get();
372   }
373 
374   // Used only by test code.
plugin_private_backend()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 {
DestructDefaultContextDeleter423   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