OLD | NEW |
1 // Copyright 2013 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_OPERATION_RUNNER_H_ | 5 #include "storage/browser/fileapi/file_system_operation_runner.h" |
6 #define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_ | |
7 | |
8 #include <map> | |
9 #include <set> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/id_map.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/memory/weak_ptr.h" | |
16 #include "webkit/browser/blob/blob_data_handle.h" | |
17 #include "webkit/browser/fileapi/file_system_operation.h" | |
18 #include "webkit/browser/fileapi/file_system_url.h" | |
19 #include "webkit/browser/storage_browser_export.h" | |
20 | |
21 namespace net { | |
22 class URLRequestContext; | |
23 } | |
24 | |
25 namespace storage { | |
26 | |
27 class FileSystemURL; | |
28 class FileSystemContext; | |
29 | |
30 // A central interface for running FileSystem API operations. | |
31 // All operation methods take callback and returns OperationID, which is | |
32 // an integer value which can be used for cancelling an operation. | |
33 // All operation methods return kErrorOperationID if running (posting) an | |
34 // operation fails, in addition to dispatching the callback with an error | |
35 // code (therefore in most cases the caller does not need to check the | |
36 // returned operation ID). | |
37 class STORAGE_EXPORT FileSystemOperationRunner | |
38 : public base::SupportsWeakPtr<FileSystemOperationRunner> { | |
39 public: | |
40 typedef FileSystemOperation::GetMetadataCallback GetMetadataCallback; | |
41 typedef FileSystemOperation::ReadDirectoryCallback ReadDirectoryCallback; | |
42 typedef FileSystemOperation::SnapshotFileCallback SnapshotFileCallback; | |
43 typedef FileSystemOperation::StatusCallback StatusCallback; | |
44 typedef FileSystemOperation::WriteCallback WriteCallback; | |
45 typedef FileSystemOperation::OpenFileCallback OpenFileCallback; | |
46 typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback; | |
47 typedef FileSystemOperation::CopyFileProgressCallback | |
48 CopyFileProgressCallback; | |
49 typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption; | |
50 | |
51 typedef int OperationID; | |
52 | |
53 virtual ~FileSystemOperationRunner(); | |
54 | |
55 // Cancels all inflight operations. | |
56 void Shutdown(); | |
57 | |
58 // Creates a file at |url|. If |exclusive| is true, an error is raised | |
59 // in case a file is already present at the URL. | |
60 OperationID CreateFile(const FileSystemURL& url, | |
61 bool exclusive, | |
62 const StatusCallback& callback); | |
63 | |
64 OperationID CreateDirectory(const FileSystemURL& url, | |
65 bool exclusive, | |
66 bool recursive, | |
67 const StatusCallback& callback); | |
68 | |
69 // Copies a file or directory from |src_url| to |dest_url|. If | |
70 // |src_url| is a directory, the contents of |src_url| are copied to | |
71 // |dest_url| recursively. A new file or directory is created at | |
72 // |dest_url| as needed. | |
73 // For |option| and |progress_callback|, see file_system_operation.h for | |
74 // details. | |
75 OperationID Copy(const FileSystemURL& src_url, | |
76 const FileSystemURL& dest_url, | |
77 CopyOrMoveOption option, | |
78 const CopyProgressCallback& progress_callback, | |
79 const StatusCallback& callback); | |
80 | |
81 // Moves a file or directory from |src_url| to |dest_url|. A new file | |
82 // or directory is created at |dest_url| as needed. | |
83 // For |option|, see file_system_operation.h for details. | |
84 OperationID Move(const FileSystemURL& src_url, | |
85 const FileSystemURL& dest_url, | |
86 CopyOrMoveOption option, | |
87 const StatusCallback& callback); | |
88 | |
89 // Checks if a directory is present at |url|. | |
90 OperationID DirectoryExists(const FileSystemURL& url, | |
91 const StatusCallback& callback); | |
92 | |
93 // Checks if a file is present at |url|. | |
94 OperationID FileExists(const FileSystemURL& url, | |
95 const StatusCallback& callback); | |
96 | |
97 // Gets the metadata of a file or directory at |url|. | |
98 OperationID GetMetadata(const FileSystemURL& url, | |
99 const GetMetadataCallback& callback); | |
100 | |
101 // Reads contents of a directory at |url|. | |
102 OperationID ReadDirectory(const FileSystemURL& url, | |
103 const ReadDirectoryCallback& callback); | |
104 | |
105 // Removes a file or directory at |url|. If |recursive| is true, remove | |
106 // all files and directories under the directory at |url| recursively. | |
107 OperationID Remove(const FileSystemURL& url, bool recursive, | |
108 const StatusCallback& callback); | |
109 | |
110 // Writes contents of |blob_url| to |url| at |offset|. | |
111 // |url_request_context| is used to read contents in |blob|. | |
112 OperationID Write(const net::URLRequestContext* url_request_context, | |
113 const FileSystemURL& url, | |
114 scoped_ptr<storage::BlobDataHandle> blob, | |
115 int64 offset, | |
116 const WriteCallback& callback); | |
117 | |
118 // Truncates a file at |url| to |length|. If |length| is larger than | |
119 // the original file size, the file will be extended, and the extended | |
120 // part is filled with null bytes. | |
121 OperationID Truncate(const FileSystemURL& url, int64 length, | |
122 const StatusCallback& callback); | |
123 | |
124 // Tries to cancel the operation |id| [we support cancelling write or | |
125 // truncate only]. Reports failure for the current operation, then reports | |
126 // success for the cancel operation itself via the |callback|. | |
127 void Cancel(OperationID id, const StatusCallback& callback); | |
128 | |
129 // Modifies timestamps of a file or directory at |url| with | |
130 // |last_access_time| and |last_modified_time|. The function DOES NOT | |
131 // create a file unlike 'touch' command on Linux. | |
132 // | |
133 // This function is used only by Pepper as of writing. | |
134 OperationID TouchFile(const FileSystemURL& url, | |
135 const base::Time& last_access_time, | |
136 const base::Time& last_modified_time, | |
137 const StatusCallback& callback); | |
138 | |
139 // Opens a file at |url| with |file_flags|, where flags are OR'ed | |
140 // values of base::PlatformFileFlags. | |
141 // | |
142 // |peer_handle| is the process handle of a pepper plugin process, which | |
143 // is necessary for underlying IPC calls with Pepper plugins. | |
144 // | |
145 // This function is used only by Pepper as of writing. | |
146 OperationID OpenFile(const FileSystemURL& url, | |
147 int file_flags, | |
148 const OpenFileCallback& callback); | |
149 | |
150 // Creates a local snapshot file for a given |url| and returns the | |
151 // metadata and platform url of the snapshot file via |callback|. | |
152 // In local filesystem cases the implementation may simply return | |
153 // the metadata of the file itself (as well as GetMetadata does), | |
154 // while in remote filesystem case the backend may want to download the file | |
155 // into a temporary snapshot file and return the metadata of the | |
156 // temporary file. Or if the implementaiton already has the local cache | |
157 // data for |url| it can simply return the url to the cache. | |
158 OperationID CreateSnapshotFile(const FileSystemURL& url, | |
159 const SnapshotFileCallback& callback); | |
160 | |
161 // Copies in a single file from a different filesystem. | |
162 // | |
163 // This returns: | |
164 // - File::FILE_ERROR_NOT_FOUND if |src_file_path| | |
165 // or the parent directory of |dest_url| does not exist. | |
166 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and | |
167 // is not a file. | |
168 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and | |
169 // its parent path is a file. | |
170 // | |
171 OperationID CopyInForeignFile(const base::FilePath& src_local_disk_path, | |
172 const FileSystemURL& dest_url, | |
173 const StatusCallback& callback); | |
174 | |
175 // Removes a single file. | |
176 // | |
177 // This returns: | |
178 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist. | |
179 // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file. | |
180 // | |
181 OperationID RemoveFile(const FileSystemURL& url, | |
182 const StatusCallback& callback); | |
183 | |
184 // Removes a single empty directory. | |
185 // | |
186 // This returns: | |
187 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist. | |
188 // - File::FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory. | |
189 // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty. | |
190 // | |
191 OperationID RemoveDirectory(const FileSystemURL& url, | |
192 const StatusCallback& callback); | |
193 | |
194 // Copies a file from |src_url| to |dest_url|. | |
195 // This must be called for files that belong to the same filesystem | |
196 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). | |
197 // For |option| and |progress_callback|, see file_system_operation.h for | |
198 // details. | |
199 // | |
200 // This returns: | |
201 // - File::FILE_ERROR_NOT_FOUND if |src_url| | |
202 // or the parent directory of |dest_url| does not exist. | |
203 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. | |
204 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and | |
205 // is not a file. | |
206 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and | |
207 // its parent path is a file. | |
208 // | |
209 OperationID CopyFileLocal(const FileSystemURL& src_url, | |
210 const FileSystemURL& dest_url, | |
211 CopyOrMoveOption option, | |
212 const CopyFileProgressCallback& progress_callback, | |
213 const StatusCallback& callback); | |
214 | |
215 // Moves a local file from |src_url| to |dest_url|. | |
216 // This must be called for files that belong to the same filesystem | |
217 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). | |
218 // For |option|, see file_system_operation.h for details. | |
219 // | |
220 // This returns: | |
221 // - File::FILE_ERROR_NOT_FOUND if |src_url| | |
222 // or the parent directory of |dest_url| does not exist. | |
223 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. | |
224 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and | |
225 // is not a file. | |
226 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and | |
227 // its parent path is a file. | |
228 // | |
229 OperationID MoveFileLocal(const FileSystemURL& src_url, | |
230 const FileSystemURL& dest_url, | |
231 CopyOrMoveOption option, | |
232 const StatusCallback& callback); | |
233 | |
234 // This is called only by pepper plugin as of writing to synchronously get | |
235 // the underlying platform path to upload a file in the sandboxed filesystem | |
236 // (e.g. TEMPORARY or PERSISTENT). | |
237 base::File::Error SyncGetPlatformPath(const FileSystemURL& url, | |
238 base::FilePath* platform_path); | |
239 | |
240 private: | |
241 class BeginOperationScoper; | |
242 | |
243 struct OperationHandle { | |
244 OperationID id; | |
245 base::WeakPtr<BeginOperationScoper> scope; | |
246 | |
247 OperationHandle(); | |
248 ~OperationHandle(); | |
249 }; | |
250 | |
251 friend class FileSystemContext; | |
252 explicit FileSystemOperationRunner(FileSystemContext* file_system_context); | |
253 | |
254 void DidFinish(const OperationHandle& handle, | |
255 const StatusCallback& callback, | |
256 base::File::Error rv); | |
257 void DidGetMetadata(const OperationHandle& handle, | |
258 const GetMetadataCallback& callback, | |
259 base::File::Error rv, | |
260 const base::File::Info& file_info); | |
261 void DidReadDirectory(const OperationHandle& handle, | |
262 const ReadDirectoryCallback& callback, | |
263 base::File::Error rv, | |
264 const std::vector<DirectoryEntry>& entries, | |
265 bool has_more); | |
266 void DidWrite(const OperationHandle& handle, | |
267 const WriteCallback& callback, | |
268 base::File::Error rv, | |
269 int64 bytes, | |
270 bool complete); | |
271 void DidOpenFile( | |
272 const OperationHandle& handle, | |
273 const OpenFileCallback& callback, | |
274 base::File file, | |
275 const base::Closure& on_close_callback); | |
276 void DidCreateSnapshot( | |
277 const OperationHandle& handle, | |
278 const SnapshotFileCallback& callback, | |
279 base::File::Error rv, | |
280 const base::File::Info& file_info, | |
281 const base::FilePath& platform_path, | |
282 const scoped_refptr<storage::ShareableFileReference>& file_ref); | |
283 | |
284 void OnCopyProgress( | |
285 const OperationHandle& handle, | |
286 const CopyProgressCallback& callback, | |
287 FileSystemOperation::CopyProgressType type, | |
288 const FileSystemURL& source_url, | |
289 const FileSystemURL& dest_url, | |
290 int64 size); | |
291 | |
292 void PrepareForWrite(OperationID id, const FileSystemURL& url); | |
293 void PrepareForRead(OperationID id, const FileSystemURL& url); | |
294 | |
295 // These must be called at the beginning and end of any async operations. | |
296 OperationHandle BeginOperation(FileSystemOperation* operation, | |
297 base::WeakPtr<BeginOperationScoper> scope); | |
298 void FinishOperation(OperationID id); | |
299 | |
300 // Not owned; file_system_context owns this. | |
301 FileSystemContext* file_system_context_; | |
302 | |
303 // IDMap<FileSystemOperation, IDMapOwnPointer> operations_; | |
304 IDMap<FileSystemOperation, IDMapOwnPointer> operations_; | |
305 | |
306 // We keep track of the file to be modified by each operation so that | |
307 // we can notify observers when we're done. | |
308 typedef std::map<OperationID, FileSystemURLSet> OperationToURLSet; | |
309 OperationToURLSet write_target_urls_; | |
310 | |
311 // Operations that are finished but not yet fire their callbacks. | |
312 std::set<OperationID> finished_operations_; | |
313 | |
314 // Callbacks for stray cancels whose target operation is already finished. | |
315 std::map<OperationID, StatusCallback> stray_cancel_callbacks_; | |
316 | |
317 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner); | |
318 }; | |
319 | |
320 } // namespace storage | |
321 | |
322 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_ | |
OLD | NEW |