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 for progress update callback for Copy().
125 // BEGIN_COPY_ENTRY is fired for each copy creation beginning (for both
126 // file and directory).
127 // The |source_url| is the URL of the source entry. |size| should not be
130 // END_COPY_ENTRY is fired for each copy creation finishing (for both
131 // file and directory).
132 // The |source_url| is the URL of the source entry. The |destination_url| is
133 // the URL of the destination entry. |size| should not be used.
135 // PROGRESS is fired periodically during file copying (not fired for
137 // The |source_url| is the URL of the source file. |size| is the number
138 // of cumulative copied bytes for the currently copied file.
139 // Both at beginning and ending of file copying, PROGRESS event should be
140 // called. At beginning, |size| should be 0. At ending, |size| should be
141 // the size of the file.
143 // Here is an example callback sequence of recursive copy. Suppose
144 // there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes), and trying to
145 // copy a to x recursively, then the progress update sequence will be:
147 // BEGIN_COPY_ENTRY a (starting create "a" directory in x/).
148 // END_COPY_ENTRY a x/a (creating "a" directory in x/ is finished).
150 // BEGIN_COPY_ENTRY a/b (starting create "b" directory in x/a).
151 // END_COPY_ENTRY a/b x/a/b (creating "b" directory in x/a/ is finished).
153 // BEGIN_COPY_ENTRY a/b/c.txt (starting to copy "c.txt" in x/a/b/).
154 // PROGRESS a/b/c.txt 0 (The first PROGRESS's |size| should be 0).
155 // PROGRESS a/b/c.txt 10
157 // PROGRESS a/b/c.txt 90
158 // PROGRESS a/b/c.txt 100 (The last PROGRESS's |size| should be the size of
160 // END_COPY_ENTRY a/b/c.txt x/a/b/c.txt (copying "c.txt" is finished).
162 // BEGIN_COPY_ENTRY a/b/d.txt (starting to copy "d.txt" in x/a/b).
163 // PROGRESS a/b/d.txt 0 (The first PROGRESS's |size| should be 0).
164 // PROGRESS a/b/d.txt 10
166 // PROGRESS a/b/d.txt 190
167 // PROGRESS a/b/d.txt 200 (The last PROGRESS's |size| should be the size of
169 // END_COPY_ENTRY a/b/d.txt x/a/b/d.txt (copy "d.txt" is finished).
171 // Note that event sequence of a/b/c.txt and a/b/d.txt can be interlaced,
172 // because they can be done in parallel. Also PROGRESS events are optional,
173 // so they may not be appeared.
174 // All the progress callback invocation should be done before StatusCallback
175 // given to the Copy is called. Especially if an error is found before first
176 // progres callback invocation, the progress callback may NOT invoked for the
179 // Note for future extension. Currently this callback is only supported on
180 // Copy(). We can extend this to Move(), because Move() is sometimes
181 // implemented as "copy then delete."
182 // In more precise, Move() usually can be implemented either 1) by updating
183 // the metadata of resource (e.g. root of moving directory tree), or 2) by
184 // copying directory tree and them removing the source tree.
185 // For 1)'s case, we can simply add BEGIN_MOVE_ENTRY and END_MOVE_ENTRY
186 // for root directory.
187 // For 2)'s case, we can add BEGIN_DELETE_ENTRY and END_DELETE_ENTRY for each
189 // For both cases, we probably won't need to use PROGRESS event because
190 // these operations should be done quickly (at least much faster than copying
192 enum CopyProgressType
{
197 typedef base::Callback
<void(CopyProgressType type
,
198 const FileSystemURL
& source_url
,
199 const FileSystemURL
& destination_url
,
201 CopyProgressCallback
;
203 // Used for CopyFileLocal() to report progress update.
204 // |size| is the cumulative copied bytes for the copy.
205 // At the beginning the progress callback should be called with |size| = 0,
206 // and also at the ending the progress callback should be called with |size|
207 // set to the copied file size.
208 typedef base::Callback
<void(int64 size
)> CopyFileProgressCallback
;
210 // The option for copy or move operation.
211 enum CopyOrMoveOption
{
212 // No additional operation.
215 // Preserves last modified time if possible. If the operation to update
216 // last modified time is not supported on the file system for the
217 // destination file, this option would be simply ignored (i.e. Copy would
218 // be successfully done without preserving last modified time).
219 OPTION_PRESERVE_LAST_MODIFIED
,
223 typedef base::Callback
<void(base::File::Error result
,
225 bool complete
)> WriteCallback
;
227 // Creates a file at |path|. If |exclusive| is true, an error is raised
228 // in case a file is already present at the URL.
229 virtual void CreateFile(const FileSystemURL
& path
,
231 const StatusCallback
& callback
) = 0;
233 // Creates a directory at |path|. If |exclusive| is true, an error is
234 // raised in case a directory is already present at the URL. If
235 // |recursive| is true, create parent directories as needed just like
237 virtual void CreateDirectory(const FileSystemURL
& path
,
240 const StatusCallback
& callback
) = 0;
242 // Copies a file or directory from |src_path| to |dest_path|. If
243 // |src_path| is a directory, the contents of |src_path| are copied to
244 // |dest_path| recursively. A new file or directory is created at
245 // |dest_path| as needed.
246 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
247 // comment for details.
248 // |progress_callback| is periodically called to report the progress
249 // update. See also the comment of CopyProgressCallback. This callback is
252 // For recursive case this internally creates new FileSystemOperations and
254 // - ReadDirectory, CopyFileLocal and CreateDirectory
255 // for same-filesystem case, or
256 // - ReadDirectory and CreateSnapshotFile on source filesystem and
257 // CopyInForeignFile and CreateDirectory on dest filesystem
258 // for cross-filesystem case.
260 virtual void Copy(const FileSystemURL
& src_path
,
261 const FileSystemURL
& dest_path
,
262 CopyOrMoveOption option
,
263 const CopyProgressCallback
& progress_callback
,
264 const StatusCallback
& callback
) = 0;
266 // Moves a file or directory from |src_path| to |dest_path|. A new file
267 // or directory is created at |dest_path| as needed.
268 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
269 // comment for details.
271 // For recursive case this internally creates new FileSystemOperations and
273 // - ReadDirectory, MoveFileLocal, CreateDirectory and Remove
274 // for same-filesystem case, or
275 // - ReadDirectory, CreateSnapshotFile and Remove on source filesystem and
276 // CopyInForeignFile and CreateDirectory on dest filesystem
277 // for cross-filesystem case.
279 virtual void Move(const FileSystemURL
& src_path
,
280 const FileSystemURL
& dest_path
,
281 CopyOrMoveOption option
,
282 const StatusCallback
& callback
) = 0;
284 // Checks if a directory is present at |path|.
285 virtual void DirectoryExists(const FileSystemURL
& path
,
286 const StatusCallback
& callback
) = 0;
288 // Checks if a file is present at |path|.
289 virtual void FileExists(const FileSystemURL
& path
,
290 const StatusCallback
& callback
) = 0;
292 // Gets the metadata of a file or directory at |path|.
293 virtual void GetMetadata(const FileSystemURL
& path
,
294 const GetMetadataCallback
& callback
) = 0;
296 // Reads contents of a directory at |path|.
297 virtual void ReadDirectory(const FileSystemURL
& path
,
298 const ReadDirectoryCallback
& callback
) = 0;
300 // Removes a file or directory at |path|. If |recursive| is true, remove
301 // all files and directories under the directory at |path| recursively.
302 virtual void Remove(const FileSystemURL
& path
, bool recursive
,
303 const StatusCallback
& callback
) = 0;
305 // Writes the data read from |blob_request| using |writer_delegate|.
307 const FileSystemURL
& url
,
308 scoped_ptr
<FileWriterDelegate
> writer_delegate
,
309 scoped_ptr
<net::URLRequest
> blob_request
,
310 const WriteCallback
& callback
) = 0;
312 // Truncates a file at |path| to |length|. If |length| is larger than
313 // the original file size, the file will be extended, and the extended
314 // part is filled with null bytes.
315 virtual void Truncate(const FileSystemURL
& path
, int64 length
,
316 const StatusCallback
& callback
) = 0;
318 // Tries to cancel the current operation [we support cancelling write or
319 // truncate only]. Reports failure for the current operation, then reports
320 // success for the cancel operation itself via the |cancel_dispatcher|.
322 // E.g. a typical cancel implementation would look like:
324 // virtual void SomeOperationImpl::Cancel(
325 // const StatusCallback& cancel_callback) {
326 // // Abort the current inflight operation first.
329 // // Dispatch ABORT error for the current operation by invoking
330 // // the callback function for the ongoing operation,
331 // operation_callback.Run(base::File::FILE_ERROR_ABORT, ...);
333 // // Dispatch 'success' for the cancel (or dispatch appropriate
334 // // error code with DidFail() if the cancel has somehow failed).
335 // cancel_callback.Run(base::File::FILE_OK);
338 // Note that, for reporting failure, the callback function passed to a
339 // cancellable operations are kept around with the operation instance
340 // (as |operation_callback_| in the code example).
341 virtual void Cancel(const StatusCallback
& cancel_callback
) = 0;
343 // Modifies timestamps of a file or directory at |path| with
344 // |last_access_time| and |last_modified_time|. The function DOES NOT
345 // create a file unlike 'touch' command on Linux.
347 // This function is used only by Pepper as of writing.
348 virtual void TouchFile(const FileSystemURL
& path
,
349 const base::Time
& last_access_time
,
350 const base::Time
& last_modified_time
,
351 const StatusCallback
& callback
) = 0;
353 // Opens a file at |path| with |file_flags|, where flags are OR'ed
354 // values of base::File::Flags.
356 // This function is used only by Pepper as of writing.
357 virtual void OpenFile(const FileSystemURL
& path
,
359 const OpenFileCallback
& callback
) = 0;
361 // Creates a local snapshot file for a given |path| and returns the
362 // metadata and platform path of the snapshot file via |callback|.
363 // In local filesystem cases the implementation may simply return
364 // the metadata of the file itself (as well as GetMetadata does),
365 // while in remote filesystem case the backend may want to download the file
366 // into a temporary snapshot file and return the metadata of the
367 // temporary file. Or if the implementaiton already has the local cache
368 // data for |path| it can simply return the path to the cache.
369 virtual void CreateSnapshotFile(const FileSystemURL
& path
,
370 const SnapshotFileCallback
& callback
) = 0;
372 // Copies in a single file from a different filesystem.
375 // - File::FILE_ERROR_NOT_FOUND if |src_file_path|
376 // or the parent directory of |dest_url| does not exist.
377 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
379 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
380 // its parent path is a file.
382 virtual void CopyInForeignFile(const base::FilePath
& src_local_disk_path
,
383 const FileSystemURL
& dest_url
,
384 const StatusCallback
& callback
) = 0;
386 // Removes a single file.
389 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
390 // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file.
392 virtual void RemoveFile(const FileSystemURL
& url
,
393 const StatusCallback
& callback
) = 0;
395 // Removes a single empty directory.
398 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
399 // - File::FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory.
400 // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty.
402 virtual void RemoveDirectory(const FileSystemURL
& url
,
403 const StatusCallback
& callback
) = 0;
405 // Copies a file from |src_url| to |dest_url|.
406 // This must be called for files that belong to the same filesystem
407 // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
408 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
409 // comment for details.
410 // |progress_callback| is periodically called to report the progress
411 // update. See also the comment of CopyFileProgressCallback. This callback is
415 // - File::FILE_ERROR_NOT_FOUND if |src_url|
416 // or the parent directory of |dest_url| does not exist.
417 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
418 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
420 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
421 // its parent path is a file.
423 virtual void CopyFileLocal(const FileSystemURL
& src_url
,
424 const FileSystemURL
& dest_url
,
425 CopyOrMoveOption option
,
426 const CopyFileProgressCallback
& progress_callback
,
427 const StatusCallback
& callback
) = 0;
429 // Moves a local file from |src_url| to |dest_url|.
430 // This must be called for files that belong to the same filesystem
431 // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
432 // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
433 // comment for details.
436 // - File::FILE_ERROR_NOT_FOUND if |src_url|
437 // or the parent directory of |dest_url| does not exist.
438 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
439 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
441 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
442 // its parent path is a file.
444 virtual void MoveFileLocal(const FileSystemURL
& src_url
,
445 const FileSystemURL
& dest_url
,
446 CopyOrMoveOption option
,
447 const StatusCallback
& callback
) = 0;
449 // Synchronously gets the platform path for the given |url|.
450 // This may fail if the given |url|'s filesystem type is neither
451 // temporary nor persistent.
452 // In such a case, base::File::FILE_ERROR_INVALID_OPERATION will be
454 virtual base::File::Error
SyncGetPlatformPath(
455 const FileSystemURL
& url
,
456 base::FilePath
* platform_path
) = 0;
459 // Used only for internal assertions.
462 kOperationCreateFile
,
463 kOperationCreateDirectory
,
464 kOperationCreateSnapshotFile
,
466 kOperationCopyInForeignFile
,
468 kOperationDirectoryExists
,
469 kOperationFileExists
,
470 kOperationGetMetadata
,
471 kOperationReadDirectory
,
478 kOperationGetLocalPath
,
483 } // namespace storage
485 #endif // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_