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 STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_
6 #define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_
10 #include "base/callback.h"
11 #include "base/files/file.h"
12 #include "base/files/file_path.h"
13 #include "base/process/process.h"
14 #include "storage/browser/fileapi/file_system_operation_context.h"
15 #include "storage/browser/storage_browser_export.h"
16 #include "storage/common/fileapi/directory_entry.h"
27 class ShareableFileReference
;
34 class FileSystemContext
;
36 class FileWriterDelegate
;
38 // The interface class for FileSystemOperation implementations.
40 // This interface defines file system operations required to implement
41 // "File API: Directories and System"
42 // http://www.w3.org/TR/file-system-api/
46 // This class is designed to
48 // 1) Serve one-time file system operation per instance. Only one
49 // method(CreateFile, CreateDirectory, Copy, Move, DirectoryExists,
50 // GetMetadata, ReadDirectory and Remove) may be called during the
51 // lifetime of this object and it should be called no more than once.
53 // 2) Deliver the results of operations to the client via the callback function
54 // passed as the last parameter of the method.
56 // Note that it is valid to delete an operation while it is running.
57 // The callback will NOT be fired if the operation is deleted before
59 class FileSystemOperation
{
61 STORAGE_EXPORT
static FileSystemOperation
* Create(
62 const FileSystemURL
& url
,
63 FileSystemContext
* file_system_context
,
64 scoped_ptr
<FileSystemOperationContext
> operation_context
);
66 virtual ~FileSystemOperation() {}
68 // Used for CreateFile(), etc. |result| is the return code of the operation.
69 typedef base::Callback
<void(base::File::Error result
)> StatusCallback
;
71 // Used for GetMetadata(). |result| is the return code of the operation,
72 // |file_info| is the obtained file info.
73 typedef base::Callback
<
74 void(base::File::Error result
,
75 const base::File::Info
& file_info
)> GetMetadataCallback
;
77 // Used for OpenFile(). |on_close_callback| will be called after the file is
78 // closed in the child process. It can be null, if no operation is needed on
80 typedef base::Callback
<
82 const base::Closure
& on_close_callback
)> OpenFileCallback
;
84 // Used for ReadDirectoryCallback.
85 typedef std::vector
<DirectoryEntry
> FileEntryList
;
87 // Used for ReadDirectory(). |result| is the return code of the operation,
88 // |file_list| is the list of files read, and |has_more| is true if some files
89 // are yet to be read.
90 typedef base::Callback
<
91 void(base::File::Error result
,
92 const FileEntryList
& file_list
,
93 bool has_more
)> ReadDirectoryCallback
;
95 // Used for CreateSnapshotFile(). (Please see the comment at
96 // CreateSnapshotFile() below for how the method is called)
97 // |result| is the return code of the operation.
98 // |file_info| is the metadata of the snapshot file created.
99 // |platform_path| is the path to the snapshot file created.
101 // The snapshot file could simply be of the local file pointed by the given
102 // filesystem URL in local filesystem cases; remote filesystems
103 // may want to download the file into a temporary snapshot file and then
104 // return the metadata of the temporary file.
106 // |file_ref| is used to manage the lifetime of the returned
107 // snapshot file. It can be set to let the chromium backend take
108 // care of the life time of the snapshot file. Otherwise (if the returned
109 // file does not require any handling) the implementation can just
110 // return NULL. In a more complex case, the implementaiton can manage
111 // the lifetime of the snapshot file on its own (e.g. by its cache system)
112 // but also can be notified via the reference when the file becomes no
113 // longer necessary in the javascript world.
114 // Please see the comment for ShareableFileReference for details.
116 typedef base::Callback
<
117 void(base::File::Error result
,
118 const base::File::Info
& file_info
,
119 const base::FilePath
& platform_path
,
120 const scoped_refptr
<storage::ShareableFileReference
>& file_ref
)>
121 SnapshotFileCallback
;
123 // Used to specify how recursive operation delegate behaves for errors.
124 // With ERROR_BEHAVIOR_ABORT, it stops following operation when it fails an
126 // With ERROR_BEHAVIOR_SKIP, it continues following operation even when it
127 // fails some of the operations.
128 enum ErrorBehavior
{ ERROR_BEHAVIOR_ABORT
, ERROR_BEHAVIOR_SKIP
};
130 // Used for progress update callback for Copy().
132 // BEGIN_COPY_ENTRY is fired for each copy creation beginning (for both
133 // file and directory).
134 // The |source_url| is the URL of the source entry. |size| should not be
137 // END_COPY_ENTRY is fired for each copy creation finishing (for both
138 // file and directory).
139 // The |source_url| is the URL of the source entry. The |destination_url| is
140 // the URL of the destination entry. |size| should not be used.
142 // PROGRESS is fired periodically during file copying (not fired for
144 // The |source_url| is the URL of the source file. |size| is the number
145 // of cumulative copied bytes for the currently copied file.
146 // Both at beginning and ending of file copying, PROGRESS event should be
147 // called. At beginning, |size| should be 0. At ending, |size| should be
148 // the size of the file.
150 // Here is an example callback sequence of recursive copy. Suppose
151 // there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes), and trying to
152 // copy a to x recursively, then the progress update sequence will be:
154 // BEGIN_COPY_ENTRY a (starting create "a" directory in x/).
155 // END_COPY_ENTRY a x/a (creating "a" directory in x/ is finished).
157 // BEGIN_COPY_ENTRY a/b (starting create "b" directory in x/a).
158 // END_COPY_ENTRY a/b x/a/b (creating "b" directory in x/a/ is finished).
160 // BEGIN_COPY_ENTRY a/b/c.txt (starting to copy "c.txt" in x/a/b/).
161 // PROGRESS a/b/c.txt 0 (The first PROGRESS's |size| should be 0).
162 // PROGRESS a/b/c.txt 10
164 // PROGRESS a/b/c.txt 90
165 // PROGRESS a/b/c.txt 100 (The last PROGRESS's |size| should be the size of
167 // END_COPY_ENTRY a/b/c.txt x/a/b/c.txt (copying "c.txt" is finished).
169 // BEGIN_COPY_ENTRY a/b/d.txt (starting to copy "d.txt" in x/a/b).
170 // PROGRESS a/b/d.txt 0 (The first PROGRESS's |size| should be 0).
171 // PROGRESS a/b/d.txt 10
173 // PROGRESS a/b/d.txt 190
174 // PROGRESS a/b/d.txt 200 (The last PROGRESS's |size| should be the size of
176 // END_COPY_ENTRY a/b/d.txt x/a/b/d.txt (copy "d.txt" is finished).
178 // Note that event sequence of a/b/c.txt and a/b/d.txt can be interlaced,
179 // because they can be done in parallel. Also PROGRESS events are optional,
180 // so they may not be appeared.
181 // All the progress callback invocation should be done before StatusCallback
182 // given to the Copy is called. Especially if an error is found before first
183 // progres callback invocation, the progress callback may NOT invoked for the
186 // Note for future extension. Currently this callback is only supported on
187 // Copy(). We can extend this to Move(), because Move() is sometimes
188 // implemented as "copy then delete."
189 // In more precise, Move() usually can be implemented either 1) by updating
190 // the metadata of resource (e.g. root of moving directory tree), or 2) by
191 // copying directory tree and them removing the source tree.
192 // For 1)'s case, we can simply add BEGIN_MOVE_ENTRY and END_MOVE_ENTRY
193 // for root directory.
194 // For 2)'s case, we can add BEGIN_DELETE_ENTRY and END_DELETE_ENTRY for each
196 // For both cases, we probably won't need to use PROGRESS event because
197 // these operations should be done quickly (at least much faster than copying
199 enum CopyProgressType
{
205 typedef base::Callback
<void(CopyProgressType type
,
206 const FileSystemURL
& source_url
,
207 const FileSystemURL
& destination_url
,
209 CopyProgressCallback
;
211 // Used for CopyFileLocal() to report progress update.
212 // |size| is the cumulative copied bytes for the copy.
213 // At the beginning the progress callback should be called with |size| = 0,
214 // and also at the ending the progress callback should be called with |size|
215 // set to the copied file size.
216 typedef base::Callback
<void(int64 size
)> CopyFileProgressCallback
;
218 // The option for copy or move operation.
219 enum CopyOrMoveOption
{
220 // No additional operation.
223 // Preserves last modified time if possible. If the operation to update
224 // last modified time is not supported on the file system for the
225 // destination file, this option would be simply ignored (i.e. Copy would
226 // be successfully done without preserving last modified time).
227 OPTION_PRESERVE_LAST_MODIFIED
,
231 typedef base::Callback
<void(base::File::Error result
,
233 bool complete
)> WriteCallback
;
235 // Creates a file at |path|. If |exclusive| is true, an error is raised
236 // in case a file is already present at the URL.
237 virtual void CreateFile(const FileSystemURL
& path
,
239 const StatusCallback
& callback
) = 0;
241 // Creates a directory at |path|. If |exclusive| is true, an error is
242 // raised in case a directory is already present at the URL. If
243 // |recursive| is true, create parent directories as needed just like
245 virtual void CreateDirectory(const FileSystemURL
& path
,
248 const StatusCallback
& callback
) = 0;
250 // Copies a file or directory from |src_path| to |dest_path|. If
251 // |src_path| is a directory, the contents of |src_path| are copied to
252 // |dest_path| recursively. A new file or directory is created at
253 // |dest_path| as needed.
254 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
255 // comment for details.
256 // |error_behavior| specifies whether this continues operation after it
257 // failed an operation or not.
258 // |progress_callback| is periodically called to report the progress
259 // update. See also the comment of CopyProgressCallback. This callback is
262 // For recursive case this internally creates new FileSystemOperations and
264 // - ReadDirectory, CopyFileLocal and CreateDirectory
265 // for same-filesystem case, or
266 // - ReadDirectory and CreateSnapshotFile on source filesystem and
267 // CopyInForeignFile and CreateDirectory on dest filesystem
268 // for cross-filesystem case.
270 virtual void Copy(const FileSystemURL
& src_path
,
271 const FileSystemURL
& dest_path
,
272 CopyOrMoveOption option
,
273 ErrorBehavior error_behavior
,
274 const CopyProgressCallback
& progress_callback
,
275 const StatusCallback
& callback
) = 0;
277 // Moves a file or directory from |src_path| to |dest_path|. A new file
278 // or directory is created at |dest_path| as needed.
279 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
280 // comment for details.
282 // For recursive case this internally creates new FileSystemOperations and
284 // - ReadDirectory, MoveFileLocal, CreateDirectory and Remove
285 // for same-filesystem case, or
286 // - ReadDirectory, CreateSnapshotFile and Remove on source filesystem and
287 // CopyInForeignFile and CreateDirectory on dest filesystem
288 // for cross-filesystem case.
290 virtual void Move(const FileSystemURL
& src_path
,
291 const FileSystemURL
& dest_path
,
292 CopyOrMoveOption option
,
293 const StatusCallback
& callback
) = 0;
295 // Checks if a directory is present at |path|.
296 virtual void DirectoryExists(const FileSystemURL
& path
,
297 const StatusCallback
& callback
) = 0;
299 // Checks if a file is present at |path|.
300 virtual void FileExists(const FileSystemURL
& path
,
301 const StatusCallback
& callback
) = 0;
303 // Gets the metadata of a file or directory at |path|.
304 virtual void GetMetadata(const FileSystemURL
& path
,
305 const GetMetadataCallback
& callback
) = 0;
307 // Reads contents of a directory at |path|.
308 virtual void ReadDirectory(const FileSystemURL
& path
,
309 const ReadDirectoryCallback
& callback
) = 0;
311 // Removes a file or directory at |path|. If |recursive| is true, remove
312 // all files and directories under the directory at |path| recursively.
313 virtual void Remove(const FileSystemURL
& path
, bool recursive
,
314 const StatusCallback
& callback
) = 0;
316 // Writes the data read from |blob_request| using |writer_delegate|.
318 const FileSystemURL
& url
,
319 scoped_ptr
<FileWriterDelegate
> writer_delegate
,
320 scoped_ptr
<net::URLRequest
> blob_request
,
321 const WriteCallback
& callback
) = 0;
323 // Truncates a file at |path| to |length|. If |length| is larger than
324 // the original file size, the file will be extended, and the extended
325 // part is filled with null bytes.
326 virtual void Truncate(const FileSystemURL
& path
, int64 length
,
327 const StatusCallback
& callback
) = 0;
329 // Tries to cancel the current operation [we support cancelling write or
330 // truncate only]. Reports failure for the current operation, then reports
331 // success for the cancel operation itself via the |cancel_dispatcher|.
333 // E.g. a typical cancel implementation would look like:
335 // virtual void SomeOperationImpl::Cancel(
336 // const StatusCallback& cancel_callback) {
337 // // Abort the current inflight operation first.
340 // // Dispatch ABORT error for the current operation by invoking
341 // // the callback function for the ongoing operation,
342 // operation_callback.Run(base::File::FILE_ERROR_ABORT, ...);
344 // // Dispatch 'success' for the cancel (or dispatch appropriate
345 // // error code with DidFail() if the cancel has somehow failed).
346 // cancel_callback.Run(base::File::FILE_OK);
349 // Note that, for reporting failure, the callback function passed to a
350 // cancellable operations are kept around with the operation instance
351 // (as |operation_callback_| in the code example).
352 virtual void Cancel(const StatusCallback
& cancel_callback
) = 0;
354 // Modifies timestamps of a file or directory at |path| with
355 // |last_access_time| and |last_modified_time|. The function DOES NOT
356 // create a file unlike 'touch' command on Linux.
358 // This function is used only by Pepper as of writing.
359 virtual void TouchFile(const FileSystemURL
& path
,
360 const base::Time
& last_access_time
,
361 const base::Time
& last_modified_time
,
362 const StatusCallback
& callback
) = 0;
364 // Opens a file at |path| with |file_flags|, where flags are OR'ed
365 // values of base::File::Flags.
367 // This function is used only by Pepper as of writing.
368 virtual void OpenFile(const FileSystemURL
& path
,
370 const OpenFileCallback
& callback
) = 0;
372 // Creates a local snapshot file for a given |path| and returns the
373 // metadata and platform path of the snapshot file via |callback|.
374 // In local filesystem cases the implementation may simply return
375 // the metadata of the file itself (as well as GetMetadata does),
376 // while in remote filesystem case the backend may want to download the file
377 // into a temporary snapshot file and return the metadata of the
378 // temporary file. Or if the implementaiton already has the local cache
379 // data for |path| it can simply return the path to the cache.
380 virtual void CreateSnapshotFile(const FileSystemURL
& path
,
381 const SnapshotFileCallback
& callback
) = 0;
383 // Copies in a single file from a different filesystem.
386 // - File::FILE_ERROR_NOT_FOUND if |src_file_path|
387 // or the parent directory of |dest_url| does not exist.
388 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
390 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
391 // its parent path is a file.
393 virtual void CopyInForeignFile(const base::FilePath
& src_local_disk_path
,
394 const FileSystemURL
& dest_url
,
395 const StatusCallback
& callback
) = 0;
397 // Removes a single file.
400 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
401 // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file.
403 virtual void RemoveFile(const FileSystemURL
& url
,
404 const StatusCallback
& callback
) = 0;
406 // Removes a single empty directory.
409 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
410 // - File::FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory.
411 // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty.
413 virtual void RemoveDirectory(const FileSystemURL
& url
,
414 const StatusCallback
& callback
) = 0;
416 // Copies a file from |src_url| to |dest_url|.
417 // This must be called for files that belong to the same filesystem
418 // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
419 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
420 // comment for details.
421 // |progress_callback| is periodically called to report the progress
422 // update. See also the comment of CopyFileProgressCallback. This callback is
426 // - File::FILE_ERROR_NOT_FOUND if |src_url|
427 // or the parent directory of |dest_url| does not exist.
428 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
429 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
431 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
432 // its parent path is a file.
434 virtual void CopyFileLocal(const FileSystemURL
& src_url
,
435 const FileSystemURL
& dest_url
,
436 CopyOrMoveOption option
,
437 const CopyFileProgressCallback
& progress_callback
,
438 const StatusCallback
& callback
) = 0;
440 // Moves a local file from |src_url| to |dest_url|.
441 // This must be called for files that belong to the same filesystem
442 // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
443 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
444 // comment for details.
447 // - File::FILE_ERROR_NOT_FOUND if |src_url|
448 // or the parent directory of |dest_url| does not exist.
449 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
450 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
452 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
453 // its parent path is a file.
455 virtual void MoveFileLocal(const FileSystemURL
& src_url
,
456 const FileSystemURL
& dest_url
,
457 CopyOrMoveOption option
,
458 const StatusCallback
& callback
) = 0;
460 // Synchronously gets the platform path for the given |url|.
461 // This may fail if the given |url|'s filesystem type is neither
462 // temporary nor persistent.
463 // In such a case, base::File::FILE_ERROR_INVALID_OPERATION will be
465 virtual base::File::Error
SyncGetPlatformPath(
466 const FileSystemURL
& url
,
467 base::FilePath
* platform_path
) = 0;
470 // Used only for internal assertions.
473 kOperationCreateFile
,
474 kOperationCreateDirectory
,
475 kOperationCreateSnapshotFile
,
477 kOperationCopyInForeignFile
,
479 kOperationDirectoryExists
,
480 kOperationFileExists
,
481 kOperationGetMetadata
,
482 kOperationReadDirectory
,
489 kOperationGetLocalPath
,
494 } // namespace storage
496 #endif // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_