Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / webkit / browser / fileapi / file_system_context.h
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/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 "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 net {
42 class URLRequest;
43 }
44
45 namespace webkit_blob {
46 class BlobURLRequestJobTest;
47 class FileStreamReader;
48 }
49
50 namespace fileapi {
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
69 struct DefaultContextDeleter;
70 struct FileSystemInfo;
71
72 // An auto mount handler will attempt to mount the file system requested in
73 // |url_request|. If the URL is for this auto mount handler, it returns true
74 // and calls |callback| when the attempt is complete. If the auto mounter
75 // does not recognize the URL, it returns false and does not call |callback|.
76 // Called on the IO thread.
77 typedef base::Callback<bool(
78     const net::URLRequest* url_request,
79     const FileSystemURL& filesystem_url,
80     const std::string& storage_domain,
81     const base::Callback<void(base::File::Error result)>& callback)>
82         URLRequestAutoMountHandler;
83
84 // This class keeps and provides a file system context for FileSystem API.
85 // An instance of this class is created and owned by profile.
86 class WEBKIT_STORAGE_BROWSER_EXPORT FileSystemContext
87     : public base::RefCountedThreadSafe<FileSystemContext,
88                                         DefaultContextDeleter> {
89  public:
90   // Returns file permission policy we should apply for the given |type|.
91   // The return value must be bitwise-or'd of FilePermissionPolicy.
92   //
93   // Note: if a part of a filesystem is returned via 'Isolated' mount point,
94   // its per-filesystem permission overrides the underlying filesystem's
95   // permission policy.
96   static int GetPermissionPolicy(FileSystemType type);
97
98   // file_task_runner is used as default TaskRunner.
99   // Unless a FileSystemBackend is overridden in CreateFileSystemOperation,
100   // it is used for all file operations and file related meta operations.
101   // The code assumes that file_task_runner->RunsTasksOnCurrentThread()
102   // returns false if the current task is not running on the thread that allows
103   // blocking file operations (like SequencedWorkerPool implementation does).
104   //
105   // |external_mount_points| contains non-system external mount points available
106   // in the context. If not NULL, it will be used during URL cracking.
107   // |external_mount_points| may be NULL only on platforms different from
108   // ChromeOS (i.e. platforms that don't use external_mount_point_provider).
109   //
110   // |additional_backends| are added to the internal backend map
111   // to serve filesystem requests for non-regular types.
112   // If none is given, this context only handles HTML5 Sandbox FileSystem
113   // and Drag-and-drop Isolated FileSystem requests.
114   //
115   // |auto_mount_handlers| are used to resolve calls to
116   // AttemptAutoMountForURLRequest. Only external filesystems are auto mounted
117   // when a filesystem: URL request is made.
118   FileSystemContext(
119       base::SingleThreadTaskRunner* io_task_runner,
120       base::SequencedTaskRunner* file_task_runner,
121       ExternalMountPoints* external_mount_points,
122       quota::SpecialStoragePolicy* special_storage_policy,
123       quota::QuotaManagerProxy* quota_manager_proxy,
124       ScopedVector<FileSystemBackend> additional_backends,
125       const std::vector<URLRequestAutoMountHandler>& auto_mount_handlers,
126       const base::FilePath& partition_path,
127       const FileSystemOptions& options);
128
129   bool DeleteDataForOriginOnFileTaskRunner(const GURL& origin_url);
130
131   // Creates a new QuotaReservation for the given |origin_url| and |type|.
132   // Returns NULL if |type| does not support quota or reservation fails.
133   // This should be run on |default_file_task_runner_| and the returned value
134   // should be destroyed on the runner.
135   scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner(
136       const GURL& origin_url,
137       FileSystemType type);
138
139   quota::QuotaManagerProxy* quota_manager_proxy() const {
140     return quota_manager_proxy_.get();
141   }
142
143   // Discards inflight operations in the operation runner.
144   void Shutdown();
145
146   // Returns a quota util for a given filesystem type.  This may
147   // return NULL if the type does not support the usage tracking or
148   // it is not a quota-managed storage.
149   FileSystemQuotaUtil* GetQuotaUtil(FileSystemType type) const;
150
151   // Returns the appropriate AsyncFileUtil instance for the given |type|.
152   AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) const;
153
154   // Returns the appropriate CopyOrMoveFileValidatorFactory for the given
155   // |type|.  If |error_code| is PLATFORM_FILE_OK and the result is NULL,
156   // then no validator is required.
157   CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
158       FileSystemType type, base::File::Error* error_code) const;
159
160   // Returns the file system backend instance for the given |type|.
161   // This may return NULL if it is given an invalid or unsupported filesystem
162   // type.
163   FileSystemBackend* GetFileSystemBackend(
164       FileSystemType type) const;
165
166   // Returns true for sandboxed filesystems. Currently this does
167   // the same as GetQuotaUtil(type) != NULL. (In an assumption that
168   // all sandboxed filesystems must cooperate with QuotaManager so that
169   // they can get deleted)
170   bool IsSandboxFileSystem(FileSystemType type) const;
171
172   // Returns observers for the given filesystem type.
173   const UpdateObserverList* GetUpdateObservers(FileSystemType type) const;
174   const AccessObserverList* GetAccessObservers(FileSystemType type) const;
175
176   // Returns all registered filesystem types.
177   void GetFileSystemTypes(std::vector<FileSystemType>* types) const;
178
179   // Returns a FileSystemBackend instance for external filesystem
180   // type, which is used only by chromeos for now.  This is equivalent to
181   // calling GetFileSystemBackend(kFileSystemTypeExternal).
182   ExternalFileSystemBackend* external_backend() const;
183
184   // Used for OpenFileSystem.
185   typedef base::Callback<void(const GURL& root,
186                               const std::string& name,
187                               base::File::Error result)>
188       OpenFileSystemCallback;
189
190   // Used for ResolveURL.
191   enum ResolvedEntryType {
192     RESOLVED_ENTRY_FILE,
193     RESOLVED_ENTRY_DIRECTORY,
194     RESOLVED_ENTRY_NOT_FOUND,
195   };
196   typedef base::Callback<void(base::File::Error result,
197                               const FileSystemInfo& info,
198                               const base::FilePath& file_path,
199                               ResolvedEntryType type)> ResolveURLCallback;
200
201   // Used for DeleteFileSystem and OpenPluginPrivateFileSystem.
202   typedef base::Callback<void(base::File::Error result)> StatusCallback;
203
204   // Opens the filesystem for the given |origin_url| and |type|, and dispatches
205   // |callback| on completion.
206   // If |create| is true this may actually set up a filesystem instance
207   // (e.g. by creating the root directory or initializing the database
208   // entry etc).
209   void OpenFileSystem(
210       const GURL& origin_url,
211       FileSystemType type,
212       OpenFileSystemMode mode,
213       const OpenFileSystemCallback& callback);
214
215   // Opens the filesystem for the given |url| as read-only, if the filesystem
216   // backend referred by the URL allows opening by resolveURL. Otherwise it
217   // fails with FILE_ERROR_SECURITY. The entry pointed by the URL can be
218   // absent; in that case RESOLVED_ENTRY_NOT_FOUND type is returned to the
219   // callback for indicating the absence. Can be called from any thread with
220   // a message loop. |callback| is invoked on the caller thread.
221   void ResolveURL(
222       const FileSystemURL& url,
223       const ResolveURLCallback& callback);
224
225   // Attempts to mount the filesystem needed to satisfy |url_request| made
226   // from |storage_domain|. If an appropriate file system is not found,
227   // callback will return an error.
228   void AttemptAutoMountForURLRequest(const net::URLRequest* url_request,
229                                      const std::string& storage_domain,
230                                      const StatusCallback& callback);
231
232   // Deletes the filesystem for the given |origin_url| and |type|. This should
233   // be called on the IO thread.
234   void DeleteFileSystem(
235       const GURL& origin_url,
236       FileSystemType type,
237       const StatusCallback& callback);
238
239   // Creates new FileStreamReader instance to read a file pointed by the given
240   // filesystem URL |url| starting from |offset|. |expected_modification_time|
241   // specifies the expected last modification if the value is non-null, the
242   // reader will check the underlying file's actual modification time to see if
243   // the file has been modified, and if it does any succeeding read operations
244   // should fail with ERR_UPLOAD_FILE_CHANGED error.
245   // This method internally cracks the |url|, get an appropriate
246   // FileSystemBackend for the URL and call the backend's CreateFileReader.
247   // The resolved FileSystemBackend could perform further specialization
248   // depending on the filesystem type pointed by the |url|.
249   scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
250       const FileSystemURL& url,
251       int64 offset,
252       const base::Time& expected_modification_time);
253
254   // Creates new FileStreamWriter instance to write into a file pointed by
255   // |url| from |offset|.
256   scoped_ptr<FileStreamWriter> CreateFileStreamWriter(
257       const FileSystemURL& url,
258       int64 offset);
259
260   // Creates a new FileSystemOperationRunner.
261   scoped_ptr<FileSystemOperationRunner> CreateFileSystemOperationRunner();
262
263   base::SequencedTaskRunner* default_file_task_runner() {
264     return default_file_task_runner_.get();
265   }
266
267   FileSystemOperationRunner* operation_runner() {
268     return operation_runner_.get();
269   }
270
271   const base::FilePath& partition_path() const { return partition_path_; }
272
273   // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from |url|.
274   FileSystemURL CrackURL(const GURL& url) const;
275   // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from method
276   // arguments.
277   FileSystemURL CreateCrackedFileSystemURL(const GURL& origin,
278                                            FileSystemType type,
279                                            const base::FilePath& path) const;
280
281 #if defined(OS_CHROMEOS)
282   // Used only on ChromeOS for now.
283   void EnableTemporaryFileSystemInIncognito();
284 #endif
285
286   SandboxFileSystemBackendDelegate* sandbox_delegate() {
287     return sandbox_delegate_.get();
288   }
289
290   // Returns true if the requested url is ok to be served.
291   // (E.g. this returns false if the context is created for incognito mode)
292   bool CanServeURLRequest(const FileSystemURL& url) const;
293
294   // Returns true if a file in the file system should be flushed for each write
295   // completion.
296   bool ShouldFlushOnWriteCompletion(FileSystemType type) const;
297
298   // This must be used to open 'plugin private' filesystem.
299   // See "plugin_private_file_system_backend.h" for more details.
300   void OpenPluginPrivateFileSystem(
301       const GURL& origin_url,
302       FileSystemType type,
303       const std::string& filesystem_id,
304       const std::string& plugin_id,
305       OpenFileSystemMode mode,
306       const StatusCallback& callback);
307
308  private:
309   typedef std::map<FileSystemType, FileSystemBackend*>
310       FileSystemBackendMap;
311
312   // For CreateFileSystemOperation.
313   friend class FileSystemOperationRunner;
314
315   // For sandbox_backend().
316   friend class content::SandboxFileSystemTestHelper;
317
318   // For plugin_private_backend().
319   friend class content::PluginPrivateFileSystemBackendTest;
320
321   // Deleters.
322   friend struct DefaultContextDeleter;
323   friend class base::DeleteHelper<FileSystemContext>;
324   friend class base::RefCountedThreadSafe<FileSystemContext,
325                                           DefaultContextDeleter>;
326   ~FileSystemContext();
327
328   void DeleteOnCorrectThread() const;
329
330   // Creates a new FileSystemOperation instance by getting an appropriate
331   // FileSystemBackend for |url| and calling the backend's corresponding
332   // CreateFileSystemOperation method.
333   // The resolved FileSystemBackend could perform further specialization
334   // depending on the filesystem type pointed by the |url|.
335   //
336   // Called by FileSystemOperationRunner.
337   FileSystemOperation* CreateFileSystemOperation(
338       const FileSystemURL& url,
339       base::File::Error* error_code);
340
341   // For non-cracked isolated and external mount points, returns a FileSystemURL
342   // created by cracking |url|. The url is cracked using MountPoints registered
343   // as |url_crackers_|. If the url cannot be cracked, returns invalid
344   // FileSystemURL.
345   //
346   // If the original url does not point to an isolated or external filesystem,
347   // returns the original url, without attempting to crack it.
348   FileSystemURL CrackFileSystemURL(const FileSystemURL& url) const;
349
350   // For initial backend_map construction. This must be called only from
351   // the constructor.
352   void RegisterBackend(FileSystemBackend* backend);
353
354   void DidOpenFileSystemForResolveURL(
355       const FileSystemURL& url,
356       const ResolveURLCallback& callback,
357       const GURL& filesystem_root,
358       const std::string& filesystem_name,
359       base::File::Error error);
360
361   // Returns a FileSystemBackend, used only by test code.
362   SandboxFileSystemBackend* sandbox_backend() const {
363     return sandbox_backend_.get();
364   }
365
366   // Used only by test code.
367   PluginPrivateFileSystemBackend* plugin_private_backend() const {
368     return plugin_private_backend_.get();
369   }
370
371   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
372   scoped_refptr<base::SequencedTaskRunner> default_file_task_runner_;
373
374   scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
375
376   scoped_ptr<SandboxFileSystemBackendDelegate> sandbox_delegate_;
377
378   // Regular file system backends.
379   scoped_ptr<SandboxFileSystemBackend> sandbox_backend_;
380   scoped_ptr<IsolatedFileSystemBackend> isolated_backend_;
381
382   // Additional file system backends.
383   scoped_ptr<PluginPrivateFileSystemBackend> plugin_private_backend_;
384   ScopedVector<FileSystemBackend> additional_backends_;
385
386   std::vector<URLRequestAutoMountHandler> auto_mount_handlers_;
387
388   // Registered file system backends.
389   // The map must be constructed in the constructor since it can be accessed
390   // on multiple threads.
391   // This map itself doesn't retain each backend's ownership; ownerships
392   // of the backends are held by additional_backends_ or other scoped_ptr
393   // backend fields.
394   FileSystemBackendMap backend_map_;
395
396   // External mount points visible in the file system context (excluding system
397   // external mount points).
398   scoped_refptr<ExternalMountPoints> external_mount_points_;
399
400   // MountPoints used to crack FileSystemURLs. The MountPoints are ordered
401   // in order they should try to crack a FileSystemURL.
402   std::vector<MountPoints*> url_crackers_;
403
404   // The base path of the storage partition for this context.
405   const base::FilePath partition_path_;
406
407   bool is_incognito_;
408
409   scoped_ptr<FileSystemOperationRunner> operation_runner_;
410
411   DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext);
412 };
413
414 struct DefaultContextDeleter {
415   static void Destruct(const FileSystemContext* context) {
416     context->DeleteOnCorrectThread();
417   }
418 };
419
420 }  // namespace fileapi
421
422 #endif  // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_