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.
5 #ifndef WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_
6 #define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_
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"
28 class SequencedTaskRunner
;
29 class SingleThreadTaskRunner
;
33 class NativeMediaFileUtilTest
;
37 class QuotaManagerProxy
;
38 class SpecialStoragePolicy
;
45 namespace webkit_blob
{
46 class BlobURLRequestJobTest
;
47 class FileStreamReader
;
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
;
64 class IsolatedFileSystemBackend
;
66 class QuotaReservation
;
67 class SandboxFileSystemBackend
;
69 struct DefaultContextDeleter
;
70 struct FileSystemInfo
;
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
;
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
> {
90 // Returns file permission policy we should apply for the given |type|.
91 // The return value must be bitwise-or'd of FilePermissionPolicy.
93 // Note: if a part of a filesystem is returned via 'Isolated' mount point,
94 // its per-filesystem permission overrides the underlying filesystem's
96 static int GetPermissionPolicy(FileSystemType type
);
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).
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).
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.
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.
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
);
129 bool DeleteDataForOriginOnFileTaskRunner(const GURL
& origin_url
);
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
);
139 quota::QuotaManagerProxy
* quota_manager_proxy() const {
140 return quota_manager_proxy_
.get();
143 // Discards inflight operations in the operation runner.
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;
151 // Returns the appropriate AsyncFileUtil instance for the given |type|.
152 AsyncFileUtil
* GetAsyncFileUtil(FileSystemType type
) const;
154 // Returns the appropriate CopyOrMoveFileValidatorFactory for the given
155 // |type|. If |error_code| is File::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;
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
163 FileSystemBackend
* GetFileSystemBackend(
164 FileSystemType type
) const;
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;
172 // Returns observers for the given filesystem type.
173 const UpdateObserverList
* GetUpdateObservers(FileSystemType type
) const;
174 const AccessObserverList
* GetAccessObservers(FileSystemType type
) const;
176 // Returns all registered filesystem types.
177 void GetFileSystemTypes(std::vector
<FileSystemType
>* types
) const;
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;
184 // Used for OpenFileSystem.
185 typedef base::Callback
<void(const GURL
& root
,
186 const std::string
& name
,
187 base::File::Error result
)>
188 OpenFileSystemCallback
;
190 // Used for ResolveURL.
191 enum ResolvedEntryType
{
193 RESOLVED_ENTRY_DIRECTORY
,
194 RESOLVED_ENTRY_NOT_FOUND
,
196 typedef base::Callback
<void(base::File::Error result
,
197 const FileSystemInfo
& info
,
198 const base::FilePath
& file_path
,
199 ResolvedEntryType type
)> ResolveURLCallback
;
201 // Used for DeleteFileSystem and OpenPluginPrivateFileSystem.
202 typedef base::Callback
<void(base::File::Error result
)> StatusCallback
;
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
210 const GURL
& origin_url
,
212 OpenFileSystemMode mode
,
213 const OpenFileSystemCallback
& callback
);
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.
222 const FileSystemURL
& url
,
223 const ResolveURLCallback
& callback
);
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
);
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
,
237 const StatusCallback
& callback
);
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
,
252 const base::Time
& expected_modification_time
);
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
,
260 // Creates a new FileSystemOperationRunner.
261 scoped_ptr
<FileSystemOperationRunner
> CreateFileSystemOperationRunner();
263 base::SequencedTaskRunner
* default_file_task_runner() {
264 return default_file_task_runner_
.get();
267 FileSystemOperationRunner
* operation_runner() {
268 return operation_runner_
.get();
271 const base::FilePath
& partition_path() const { return partition_path_
; }
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
277 FileSystemURL
CreateCrackedFileSystemURL(const GURL
& origin
,
279 const base::FilePath
& path
) const;
281 #if defined(OS_CHROMEOS)
282 // Used only on ChromeOS for now.
283 void EnableTemporaryFileSystemInIncognito();
286 SandboxFileSystemBackendDelegate
* sandbox_delegate() {
287 return sandbox_delegate_
.get();
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;
294 // Returns true if a file in the file system should be flushed for each write
296 bool ShouldFlushOnWriteCompletion(FileSystemType type
) const;
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
,
303 const std::string
& filesystem_id
,
304 const std::string
& plugin_id
,
305 OpenFileSystemMode mode
,
306 const StatusCallback
& callback
);
309 typedef std::map
<FileSystemType
, FileSystemBackend
*>
310 FileSystemBackendMap
;
312 // For CreateFileSystemOperation.
313 friend class FileSystemOperationRunner
;
315 // For sandbox_backend().
316 friend class content::SandboxFileSystemTestHelper
;
318 // For plugin_private_backend().
319 friend class content::PluginPrivateFileSystemBackendTest
;
322 friend struct DefaultContextDeleter
;
323 friend class base::DeleteHelper
<FileSystemContext
>;
324 friend class base::RefCountedThreadSafe
<FileSystemContext
,
325 DefaultContextDeleter
>;
326 ~FileSystemContext();
328 void DeleteOnCorrectThread() const;
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|.
336 // Called by FileSystemOperationRunner.
337 FileSystemOperation
* CreateFileSystemOperation(
338 const FileSystemURL
& url
,
339 base::File::Error
* error_code
);
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
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;
350 // For initial backend_map construction. This must be called only from
352 void RegisterBackend(FileSystemBackend
* backend
);
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
);
361 // Returns a FileSystemBackend, used only by test code.
362 SandboxFileSystemBackend
* sandbox_backend() const {
363 return sandbox_backend_
.get();
366 // Used only by test code.
367 PluginPrivateFileSystemBackend
* plugin_private_backend() const {
368 return plugin_private_backend_
.get();
371 scoped_refptr
<base::SingleThreadTaskRunner
> io_task_runner_
;
372 scoped_refptr
<base::SequencedTaskRunner
> default_file_task_runner_
;
374 scoped_refptr
<quota::QuotaManagerProxy
> quota_manager_proxy_
;
376 scoped_ptr
<SandboxFileSystemBackendDelegate
> sandbox_delegate_
;
378 // Regular file system backends.
379 scoped_ptr
<SandboxFileSystemBackend
> sandbox_backend_
;
380 scoped_ptr
<IsolatedFileSystemBackend
> isolated_backend_
;
382 // Additional file system backends.
383 scoped_ptr
<PluginPrivateFileSystemBackend
> plugin_private_backend_
;
384 ScopedVector
<FileSystemBackend
> additional_backends_
;
386 std::vector
<URLRequestAutoMountHandler
> auto_mount_handlers_
;
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
394 FileSystemBackendMap backend_map_
;
396 // External mount points visible in the file system context (excluding system
397 // external mount points).
398 scoped_refptr
<ExternalMountPoints
> external_mount_points_
;
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_
;
404 // The base path of the storage partition for this context.
405 const base::FilePath partition_path_
;
409 scoped_ptr
<FileSystemOperationRunner
> operation_runner_
;
411 DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext
);
414 struct DefaultContextDeleter
{
415 static void Destruct(const FileSystemContext
* context
) {
416 context
->DeleteOnCorrectThread();
420 } // namespace fileapi
422 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_