OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_ | 5 #include "storage/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/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 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 | |
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 AccessObserverList* GetAccessObservers(FileSystemType type) const; | |
180 | |
181 // Returns all registered filesystem types. | |
182 void GetFileSystemTypes(std::vector<FileSystemType>* types) const; | |
183 | |
184 // Returns a FileSystemBackend instance for external filesystem | |
185 // type, which is used only by chromeos for now. This is equivalent to | |
186 // calling GetFileSystemBackend(kFileSystemTypeExternal). | |
187 ExternalFileSystemBackend* external_backend() const; | |
188 | |
189 // Used for OpenFileSystem. | |
190 typedef base::Callback<void(const GURL& root, | |
191 const std::string& name, | |
192 base::File::Error result)> | |
193 OpenFileSystemCallback; | |
194 | |
195 // Used for ResolveURL. | |
196 enum ResolvedEntryType { | |
197 RESOLVED_ENTRY_FILE, | |
198 RESOLVED_ENTRY_DIRECTORY, | |
199 RESOLVED_ENTRY_NOT_FOUND, | |
200 }; | |
201 typedef base::Callback<void(base::File::Error result, | |
202 const FileSystemInfo& info, | |
203 const base::FilePath& file_path, | |
204 ResolvedEntryType type)> ResolveURLCallback; | |
205 | |
206 // Used for DeleteFileSystem and OpenPluginPrivateFileSystem. | |
207 typedef base::Callback<void(base::File::Error result)> StatusCallback; | |
208 | |
209 // Opens the filesystem for the given |origin_url| and |type|, and dispatches | |
210 // |callback| on completion. | |
211 // If |create| is true this may actually set up a filesystem instance | |
212 // (e.g. by creating the root directory or initializing the database | |
213 // entry etc). | |
214 void OpenFileSystem( | |
215 const GURL& origin_url, | |
216 FileSystemType type, | |
217 OpenFileSystemMode mode, | |
218 const OpenFileSystemCallback& callback); | |
219 | |
220 // Opens the filesystem for the given |url| as read-only, if the filesystem | |
221 // backend referred by the URL allows opening by resolveURL. Otherwise it | |
222 // fails with FILE_ERROR_SECURITY. The entry pointed by the URL can be | |
223 // absent; in that case RESOLVED_ENTRY_NOT_FOUND type is returned to the | |
224 // callback for indicating the absence. Can be called from any thread with | |
225 // a message loop. |callback| is invoked on the caller thread. | |
226 void ResolveURL( | |
227 const FileSystemURL& url, | |
228 const ResolveURLCallback& callback); | |
229 | |
230 // Attempts to mount the filesystem needed to satisfy |url_request| made | |
231 // from |storage_domain|. If an appropriate file system is not found, | |
232 // callback will return an error. | |
233 void AttemptAutoMountForURLRequest(const net::URLRequest* url_request, | |
234 const std::string& storage_domain, | |
235 const StatusCallback& callback); | |
236 | |
237 // Deletes the filesystem for the given |origin_url| and |type|. This should | |
238 // be called on the IO thread. | |
239 void DeleteFileSystem( | |
240 const GURL& origin_url, | |
241 FileSystemType type, | |
242 const StatusCallback& callback); | |
243 | |
244 // Creates new FileStreamReader instance to read a file pointed by the given | |
245 // filesystem URL |url| starting from |offset|. |expected_modification_time| | |
246 // specifies the expected last modification if the value is non-null, the | |
247 // reader will check the underlying file's actual modification time to see if | |
248 // the file has been modified, and if it does any succeeding read operations | |
249 // should fail with ERR_UPLOAD_FILE_CHANGED error. | |
250 // This method internally cracks the |url|, get an appropriate | |
251 // FileSystemBackend for the URL and call the backend's CreateFileReader. | |
252 // The resolved FileSystemBackend could perform further specialization | |
253 // depending on the filesystem type pointed by the |url|. | |
254 scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( | |
255 const FileSystemURL& url, | |
256 int64 offset, | |
257 const base::Time& expected_modification_time); | |
258 | |
259 // Creates new FileStreamWriter instance to write into a file pointed by | |
260 // |url| from |offset|. | |
261 scoped_ptr<FileStreamWriter> CreateFileStreamWriter( | |
262 const FileSystemURL& url, | |
263 int64 offset); | |
264 | |
265 // Creates a new FileSystemOperationRunner. | |
266 scoped_ptr<FileSystemOperationRunner> CreateFileSystemOperationRunner(); | |
267 | |
268 base::SequencedTaskRunner* default_file_task_runner() { | |
269 return default_file_task_runner_.get(); | |
270 } | |
271 | |
272 FileSystemOperationRunner* operation_runner() { | |
273 return operation_runner_.get(); | |
274 } | |
275 | |
276 const base::FilePath& partition_path() const { return partition_path_; } | |
277 | |
278 // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from |url|. | |
279 FileSystemURL CrackURL(const GURL& url) const; | |
280 // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from method | |
281 // arguments. | |
282 FileSystemURL CreateCrackedFileSystemURL(const GURL& origin, | |
283 FileSystemType type, | |
284 const base::FilePath& path) const; | |
285 | |
286 #if defined(OS_CHROMEOS) | |
287 // Used only on ChromeOS for now. | |
288 void EnableTemporaryFileSystemInIncognito(); | |
289 #endif | |
290 | |
291 SandboxFileSystemBackendDelegate* sandbox_delegate() { | |
292 return sandbox_delegate_.get(); | |
293 } | |
294 | |
295 // Returns true if the requested url is ok to be served. | |
296 // (E.g. this returns false if the context is created for incognito mode) | |
297 bool CanServeURLRequest(const FileSystemURL& url) const; | |
298 | |
299 // Returns true if a file in the file system should be flushed for each write | |
300 // completion. | |
301 bool ShouldFlushOnWriteCompletion(FileSystemType type) const; | |
302 | |
303 // This must be used to open 'plugin private' filesystem. | |
304 // See "plugin_private_file_system_backend.h" for more details. | |
305 void OpenPluginPrivateFileSystem( | |
306 const GURL& origin_url, | |
307 FileSystemType type, | |
308 const std::string& filesystem_id, | |
309 const std::string& plugin_id, | |
310 OpenFileSystemMode mode, | |
311 const StatusCallback& callback); | |
312 | |
313 private: | |
314 typedef std::map<FileSystemType, FileSystemBackend*> | |
315 FileSystemBackendMap; | |
316 | |
317 // For CreateFileSystemOperation. | |
318 friend class FileSystemOperationRunner; | |
319 | |
320 // For sandbox_backend(). | |
321 friend class content::SandboxFileSystemTestHelper; | |
322 | |
323 // For plugin_private_backend(). | |
324 friend class content::PluginPrivateFileSystemBackendTest; | |
325 | |
326 // Deleters. | |
327 friend struct DefaultContextDeleter; | |
328 friend class base::DeleteHelper<FileSystemContext>; | |
329 friend class base::RefCountedThreadSafe<FileSystemContext, | |
330 DefaultContextDeleter>; | |
331 ~FileSystemContext(); | |
332 | |
333 void DeleteOnCorrectThread() const; | |
334 | |
335 // Creates a new FileSystemOperation instance by getting an appropriate | |
336 // FileSystemBackend for |url| and calling the backend's corresponding | |
337 // CreateFileSystemOperation method. | |
338 // The resolved FileSystemBackend could perform further specialization | |
339 // depending on the filesystem type pointed by the |url|. | |
340 // | |
341 // Called by FileSystemOperationRunner. | |
342 FileSystemOperation* CreateFileSystemOperation( | |
343 const FileSystemURL& url, | |
344 base::File::Error* error_code); | |
345 | |
346 // For non-cracked isolated and external mount points, returns a FileSystemURL | |
347 // created by cracking |url|. The url is cracked using MountPoints registered | |
348 // as |url_crackers_|. If the url cannot be cracked, returns invalid | |
349 // FileSystemURL. | |
350 // | |
351 // If the original url does not point to an isolated or external filesystem, | |
352 // returns the original url, without attempting to crack it. | |
353 FileSystemURL CrackFileSystemURL(const FileSystemURL& url) const; | |
354 | |
355 // For initial backend_map construction. This must be called only from | |
356 // the constructor. | |
357 void RegisterBackend(FileSystemBackend* backend); | |
358 | |
359 void DidOpenFileSystemForResolveURL( | |
360 const FileSystemURL& url, | |
361 const ResolveURLCallback& callback, | |
362 const GURL& filesystem_root, | |
363 const std::string& filesystem_name, | |
364 base::File::Error error); | |
365 | |
366 // Returns a FileSystemBackend, used only by test code. | |
367 SandboxFileSystemBackend* sandbox_backend() const { | |
368 return sandbox_backend_.get(); | |
369 } | |
370 | |
371 // Used only by test code. | |
372 PluginPrivateFileSystemBackend* plugin_private_backend() const { | |
373 return plugin_private_backend_.get(); | |
374 } | |
375 | |
376 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; | |
377 scoped_refptr<base::SequencedTaskRunner> default_file_task_runner_; | |
378 | |
379 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_; | |
380 | |
381 scoped_ptr<SandboxFileSystemBackendDelegate> sandbox_delegate_; | |
382 | |
383 // Regular file system backends. | |
384 scoped_ptr<SandboxFileSystemBackend> sandbox_backend_; | |
385 scoped_ptr<IsolatedFileSystemBackend> isolated_backend_; | |
386 | |
387 // Additional file system backends. | |
388 scoped_ptr<PluginPrivateFileSystemBackend> plugin_private_backend_; | |
389 ScopedVector<FileSystemBackend> additional_backends_; | |
390 | |
391 std::vector<URLRequestAutoMountHandler> auto_mount_handlers_; | |
392 | |
393 // Registered file system backends. | |
394 // The map must be constructed in the constructor since it can be accessed | |
395 // on multiple threads. | |
396 // This map itself doesn't retain each backend's ownership; ownerships | |
397 // of the backends are held by additional_backends_ or other scoped_ptr | |
398 // backend fields. | |
399 FileSystemBackendMap backend_map_; | |
400 | |
401 // External mount points visible in the file system context (excluding system | |
402 // external mount points). | |
403 scoped_refptr<ExternalMountPoints> external_mount_points_; | |
404 | |
405 // MountPoints used to crack FileSystemURLs. The MountPoints are ordered | |
406 // in order they should try to crack a FileSystemURL. | |
407 std::vector<MountPoints*> url_crackers_; | |
408 | |
409 // The base path of the storage partition for this context. | |
410 const base::FilePath partition_path_; | |
411 | |
412 bool is_incognito_; | |
413 | |
414 scoped_ptr<FileSystemOperationRunner> operation_runner_; | |
415 | |
416 DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext); | |
417 }; | |
418 | |
419 struct DefaultContextDeleter { | |
420 static void Destruct(const FileSystemContext* context) { | |
421 context->DeleteOnCorrectThread(); | |
422 } | |
423 }; | |
424 | |
425 } // namespace storage | |
426 | |
427 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_CONTEXT_H_ | |
OLD | NEW |