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::ErrorBehavior ErrorBehavior
;
47 typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback
;
48 typedef FileSystemOperation::CopyFileProgressCallback
49 CopyFileProgressCallback
;
50 typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption
;
52 typedef int OperationID
;
54 virtual ~FileSystemOperationRunner();
56 // Cancels all inflight operations.
59 // Creates a file at |url|. If |exclusive| is true, an error is raised
60 // in case a file is already present at the URL.
61 OperationID
CreateFile(const FileSystemURL
& url
,
63 const StatusCallback
& callback
);
65 OperationID
CreateDirectory(const FileSystemURL
& url
,
68 const StatusCallback
& callback
);
70 // Copies a file or directory from |src_url| to |dest_url|. If
71 // |src_url| is a directory, the contents of |src_url| are copied to
72 // |dest_url| recursively. A new file or directory is created at
73 // |dest_url| as needed.
74 // For |option| and |progress_callback|, see file_system_operation.h for
76 OperationID
Copy(const FileSystemURL
& src_url
,
77 const FileSystemURL
& dest_url
,
78 CopyOrMoveOption option
,
79 ErrorBehavior error_behavior
,
80 const CopyProgressCallback
& progress_callback
,
81 const StatusCallback
& callback
);
83 // Moves a file or directory from |src_url| to |dest_url|. A new file
84 // or directory is created at |dest_url| as needed.
85 // For |option|, see file_system_operation.h for details.
86 OperationID
Move(const FileSystemURL
& src_url
,
87 const FileSystemURL
& dest_url
,
88 CopyOrMoveOption option
,
89 const StatusCallback
& callback
);
91 // Checks if a directory is present at |url|.
92 OperationID
DirectoryExists(const FileSystemURL
& url
,
93 const StatusCallback
& callback
);
95 // Checks if a file is present at |url|.
96 OperationID
FileExists(const FileSystemURL
& url
,
97 const StatusCallback
& callback
);
99 // Gets the metadata of a file or directory at |url|.
100 OperationID
GetMetadata(const FileSystemURL
& url
,
101 const GetMetadataCallback
& callback
);
103 // Reads contents of a directory at |url|.
104 OperationID
ReadDirectory(const FileSystemURL
& url
,
105 const ReadDirectoryCallback
& callback
);
107 // Removes a file or directory at |url|. If |recursive| is true, remove
108 // all files and directories under the directory at |url| recursively.
109 OperationID
Remove(const FileSystemURL
& url
, bool recursive
,
110 const StatusCallback
& callback
);
112 // Writes contents of |blob_url| to |url| at |offset|.
113 // |url_request_context| is used to read contents in |blob|.
114 OperationID
Write(const net::URLRequestContext
* url_request_context
,
115 const FileSystemURL
& url
,
116 scoped_ptr
<storage::BlobDataHandle
> blob
,
118 const WriteCallback
& callback
);
120 // Truncates a file at |url| to |length|. If |length| is larger than
121 // the original file size, the file will be extended, and the extended
122 // part is filled with null bytes.
123 OperationID
Truncate(const FileSystemURL
& url
, int64 length
,
124 const StatusCallback
& callback
);
126 // Tries to cancel the operation |id| [we support cancelling write or
127 // truncate only]. Reports failure for the current operation, then reports
128 // success for the cancel operation itself via the |callback|.
129 void Cancel(OperationID id
, const StatusCallback
& callback
);
131 // Modifies timestamps of a file or directory at |url| with
132 // |last_access_time| and |last_modified_time|. The function DOES NOT
133 // create a file unlike 'touch' command on Linux.
135 // This function is used only by Pepper as of writing.
136 OperationID
TouchFile(const FileSystemURL
& url
,
137 const base::Time
& last_access_time
,
138 const base::Time
& last_modified_time
,
139 const StatusCallback
& callback
);
141 // Opens a file at |url| with |file_flags|, where flags are OR'ed
142 // values of base::PlatformFileFlags.
144 // |peer_handle| is the process handle of a pepper plugin process, which
145 // is necessary for underlying IPC calls with Pepper plugins.
147 // This function is used only by Pepper as of writing.
148 OperationID
OpenFile(const FileSystemURL
& url
,
150 const OpenFileCallback
& callback
);
152 // Creates a local snapshot file for a given |url| and returns the
153 // metadata and platform url of the snapshot file via |callback|.
154 // In local filesystem cases the implementation may simply return
155 // the metadata of the file itself (as well as GetMetadata does),
156 // while in remote filesystem case the backend may want to download the file
157 // into a temporary snapshot file and return the metadata of the
158 // temporary file. Or if the implementaiton already has the local cache
159 // data for |url| it can simply return the url to the cache.
160 OperationID
CreateSnapshotFile(const FileSystemURL
& url
,
161 const SnapshotFileCallback
& callback
);
163 // Copies in a single file from a different filesystem.
166 // - File::FILE_ERROR_NOT_FOUND if |src_file_path|
167 // or the parent directory of |dest_url| does not exist.
168 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
170 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
171 // its parent path is a file.
173 OperationID
CopyInForeignFile(const base::FilePath
& src_local_disk_path
,
174 const FileSystemURL
& dest_url
,
175 const StatusCallback
& callback
);
177 // Removes a single file.
180 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
181 // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file.
183 OperationID
RemoveFile(const FileSystemURL
& url
,
184 const StatusCallback
& callback
);
186 // Removes a single empty directory.
189 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
190 // - File::FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory.
191 // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty.
193 OperationID
RemoveDirectory(const FileSystemURL
& url
,
194 const StatusCallback
& callback
);
196 // Copies a file from |src_url| to |dest_url|.
197 // This must be called for files that belong to the same filesystem
198 // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
199 // For |option| and |progress_callback|, see file_system_operation.h for
203 // - File::FILE_ERROR_NOT_FOUND if |src_url|
204 // or the parent directory of |dest_url| does not exist.
205 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
206 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
208 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
209 // its parent path is a file.
211 OperationID
CopyFileLocal(const FileSystemURL
& src_url
,
212 const FileSystemURL
& dest_url
,
213 CopyOrMoveOption option
,
214 const CopyFileProgressCallback
& progress_callback
,
215 const StatusCallback
& callback
);
217 // Moves a local file from |src_url| to |dest_url|.
218 // This must be called for files that belong to the same filesystem
219 // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
220 // For |option|, see file_system_operation.h for details.
223 // - File::FILE_ERROR_NOT_FOUND if |src_url|
224 // or the parent directory of |dest_url| does not exist.
225 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
226 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
228 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
229 // its parent path is a file.
231 OperationID
MoveFileLocal(const FileSystemURL
& src_url
,
232 const FileSystemURL
& dest_url
,
233 CopyOrMoveOption option
,
234 const StatusCallback
& callback
);
236 // This is called only by pepper plugin as of writing to synchronously get
237 // the underlying platform path to upload a file in the sandboxed filesystem
238 // (e.g. TEMPORARY or PERSISTENT).
239 base::File::Error
SyncGetPlatformPath(const FileSystemURL
& url
,
240 base::FilePath
* platform_path
);
243 class BeginOperationScoper
;
245 struct OperationHandle
{
247 base::WeakPtr
<BeginOperationScoper
> scope
;
253 friend class FileSystemContext
;
254 explicit FileSystemOperationRunner(FileSystemContext
* file_system_context
);
256 void DidFinish(const OperationHandle
& handle
,
257 const StatusCallback
& callback
,
258 base::File::Error rv
);
259 void DidGetMetadata(const OperationHandle
& handle
,
260 const GetMetadataCallback
& callback
,
261 base::File::Error rv
,
262 const base::File::Info
& file_info
);
263 void DidReadDirectory(const OperationHandle
& handle
,
264 const ReadDirectoryCallback
& callback
,
265 base::File::Error rv
,
266 const std::vector
<DirectoryEntry
>& entries
,
268 void DidWrite(const OperationHandle
& handle
,
269 const WriteCallback
& callback
,
270 base::File::Error rv
,
274 const OperationHandle
& handle
,
275 const OpenFileCallback
& callback
,
277 const base::Closure
& on_close_callback
);
278 void DidCreateSnapshot(
279 const OperationHandle
& handle
,
280 const SnapshotFileCallback
& callback
,
281 base::File::Error rv
,
282 const base::File::Info
& file_info
,
283 const base::FilePath
& platform_path
,
284 const scoped_refptr
<storage::ShareableFileReference
>& file_ref
);
287 const OperationHandle
& handle
,
288 const CopyProgressCallback
& callback
,
289 FileSystemOperation::CopyProgressType type
,
290 const FileSystemURL
& source_url
,
291 const FileSystemURL
& dest_url
,
294 void PrepareForWrite(OperationID id
, const FileSystemURL
& url
);
295 void PrepareForRead(OperationID id
, const FileSystemURL
& url
);
297 // These must be called at the beginning and end of any async operations.
298 OperationHandle
BeginOperation(FileSystemOperation
* operation
,
299 base::WeakPtr
<BeginOperationScoper
> scope
);
300 void FinishOperation(OperationID id
);
302 // Not owned; file_system_context owns this.
303 FileSystemContext
* file_system_context_
;
305 // IDMap<FileSystemOperation, IDMapOwnPointer> operations_;
306 IDMap
<FileSystemOperation
, IDMapOwnPointer
> operations_
;
308 // We keep track of the file to be modified by each operation so that
309 // we can notify observers when we're done.
310 typedef std::map
<OperationID
, FileSystemURLSet
> OperationToURLSet
;
311 OperationToURLSet write_target_urls_
;
313 // Operations that are finished but not yet fire their callbacks.
314 std::set
<OperationID
> finished_operations_
;
316 // Callbacks for stray cancels whose target operation is already finished.
317 std::map
<OperationID
, StatusCallback
> stray_cancel_callbacks_
;
319 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner
);
322 } // namespace storage
324 #endif // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_