1 // Copyright 2013 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 STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_
6 #define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_
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 "storage/browser/blob/blob_data_handle.h"
17 #include "storage/browser/fileapi/file_system_operation.h"
18 #include "storage/browser/fileapi/file_system_url.h"
19 #include "storage/browser/storage_browser_export.h"
22 class URLRequestContext
;
28 class FileSystemContext
;
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
> {
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
;
51 typedef int OperationID
;
53 virtual ~FileSystemOperationRunner();
55 // Cancels all inflight operations.
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
,
62 const StatusCallback
& callback
);
64 OperationID
CreateDirectory(const FileSystemURL
& url
,
67 const StatusCallback
& callback
);
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
75 OperationID
Copy(const FileSystemURL
& src_url
,
76 const FileSystemURL
& dest_url
,
77 CopyOrMoveOption option
,
78 const CopyProgressCallback
& progress_callback
,
79 const StatusCallback
& callback
);
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
);
89 // Checks if a directory is present at |url|.
90 OperationID
DirectoryExists(const FileSystemURL
& url
,
91 const StatusCallback
& callback
);
93 // Checks if a file is present at |url|.
94 OperationID
FileExists(const FileSystemURL
& url
,
95 const StatusCallback
& callback
);
97 // Gets the metadata of a file or directory at |url|.
98 OperationID
GetMetadata(const FileSystemURL
& url
,
99 const GetMetadataCallback
& callback
);
101 // Reads contents of a directory at |url|.
102 OperationID
ReadDirectory(const FileSystemURL
& url
,
103 const ReadDirectoryCallback
& callback
);
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
);
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
,
116 const WriteCallback
& callback
);
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
);
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
);
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.
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
);
139 // Opens a file at |url| with |file_flags|, where flags are OR'ed
140 // values of base::PlatformFileFlags.
142 // |peer_handle| is the process handle of a pepper plugin process, which
143 // is necessary for underlying IPC calls with Pepper plugins.
145 // This function is used only by Pepper as of writing.
146 OperationID
OpenFile(const FileSystemURL
& url
,
148 const OpenFileCallback
& callback
);
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
);
161 // Copies in a single file from a different filesystem.
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
168 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
169 // its parent path is a file.
171 OperationID
CopyInForeignFile(const base::FilePath
& src_local_disk_path
,
172 const FileSystemURL
& dest_url
,
173 const StatusCallback
& callback
);
175 // Removes a single file.
178 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
179 // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file.
181 OperationID
RemoveFile(const FileSystemURL
& url
,
182 const StatusCallback
& callback
);
184 // Removes a single empty directory.
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.
191 OperationID
RemoveDirectory(const FileSystemURL
& url
,
192 const StatusCallback
& callback
);
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
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
206 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
207 // its parent path is a file.
209 OperationID
CopyFileLocal(const FileSystemURL
& src_url
,
210 const FileSystemURL
& dest_url
,
211 CopyOrMoveOption option
,
212 const CopyFileProgressCallback
& progress_callback
,
213 const StatusCallback
& callback
);
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.
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
226 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
227 // its parent path is a file.
229 OperationID
MoveFileLocal(const FileSystemURL
& src_url
,
230 const FileSystemURL
& dest_url
,
231 CopyOrMoveOption option
,
232 const StatusCallback
& callback
);
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
);
241 class BeginOperationScoper
;
243 struct OperationHandle
{
245 base::WeakPtr
<BeginOperationScoper
> scope
;
251 friend class FileSystemContext
;
252 explicit FileSystemOperationRunner(FileSystemContext
* file_system_context
);
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
,
266 void DidWrite(const OperationHandle
& handle
,
267 const WriteCallback
& callback
,
268 base::File::Error rv
,
272 const OperationHandle
& handle
,
273 const OpenFileCallback
& callback
,
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
);
285 const OperationHandle
& handle
,
286 const CopyProgressCallback
& callback
,
287 FileSystemOperation::CopyProgressType type
,
288 const FileSystemURL
& source_url
,
289 const FileSystemURL
& dest_url
,
292 void PrepareForWrite(OperationID id
, const FileSystemURL
& url
);
293 void PrepareForRead(OperationID id
, const FileSystemURL
& url
);
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
);
300 // Not owned; file_system_context owns this.
301 FileSystemContext
* file_system_context_
;
303 // IDMap<FileSystemOperation, IDMapOwnPointer> operations_;
304 IDMap
<FileSystemOperation
, IDMapOwnPointer
> operations_
;
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_
;
311 // Operations that are finished but not yet fire their callbacks.
312 std::set
<OperationID
> finished_operations_
;
314 // Callbacks for stray cancels whose target operation is already finished.
315 std::map
<OperationID
, StatusCallback
> stray_cancel_callbacks_
;
317 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner
);
320 } // namespace storage
322 #endif // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_