blob: f1adc191a7e38593c7bcdd34adb4b865dba8f9aa [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_
#define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/platform_file.h"
#include "base/process/process.h"
#include "webkit/common/fileapi/directory_entry.h"
namespace base {
class Time;
}
namespace net {
class URLRequest;
}
namespace webkit_blob {
class ShareableFileReference;
}
class GURL;
namespace fileapi {
class FileSystemURL;
class FileWriterDelegate;
class FileSystemOperationImpl;
// The interface class for FileSystemOperation implementations.
//
// This interface defines file system operations required to implement
// "File API: Directories and System"
// http://www.w3.org/TR/file-system-api/
//
// DESIGN NOTES
//
// This class is designed to
//
// 1) Serve one-time file system operation per instance. Only one
// method(CreateFile, CreateDirectory, Copy, Move, DirectoryExists,
// GetMetadata, ReadDirectory and Remove) may be called during the
// lifetime of this object and it should be called no more than once.
//
// 2) Deliver the results of operations to the client via the callback function
// passed as the last parameter of the method.
//
// Note that it is valid to delete an operation while it is running.
// The callback will NOT be fired if the operation is deleted before
// it gets called.
class FileSystemOperation {
public:
virtual ~FileSystemOperation() {}
// Used for CreateFile(), etc. |result| is the return code of the operation.
typedef base::Callback<void(base::PlatformFileError result)> StatusCallback;
// Used for GetMetadata(). |result| is the return code of the operation,
// |file_info| is the obtained file info.
typedef base::Callback<
void(base::PlatformFileError result,
const base::PlatformFileInfo& file_info)> GetMetadataCallback;
// Used for OpenFile(). |result| is the return code of the operation.
// |on_close_callback| will be called after the file is closed in the child
// process. It can be null, if no operation is needed on closing a file.
typedef base::Callback<
void(base::PlatformFileError result,
base::PlatformFile file,
const base::Closure& on_close_callback,
base::ProcessHandle peer_handle)> OpenFileCallback;
// Used for ReadDirectoryCallback.
typedef std::vector<DirectoryEntry> FileEntryList;
// Used for ReadDirectory(). |result| is the return code of the operation,
// |file_list| is the list of files read, and |has_more| is true if some files
// are yet to be read.
typedef base::Callback<
void(base::PlatformFileError result,
const FileEntryList& file_list,
bool has_more)> ReadDirectoryCallback;
// Used for CreateSnapshotFile(). (Please see the comment at
// CreateSnapshotFile() below for how the method is called)
// |result| is the return code of the operation.
// |file_info| is the metadata of the snapshot file created.
// |platform_path| is the path to the snapshot file created.
//
// The snapshot file could simply be of the local file pointed by the given
// filesystem URL in local filesystem cases; remote filesystems
// may want to download the file into a temporary snapshot file and then
// return the metadata of the temporary file.
//
// |file_ref| is used to manage the lifetime of the returned
// snapshot file. It can be set to let the chromium backend take
// care of the life time of the snapshot file. Otherwise (if the returned
// file does not require any handling) the implementation can just
// return NULL. In a more complex case, the implementaiton can manage
// the lifetime of the snapshot file on its own (e.g. by its cache system)
// but also can be notified via the reference when the file becomes no
// longer necessary in the javascript world.
// Please see the comment for ShareableFileReference for details.
//
typedef base::Callback<
void(base::PlatformFileError result,
const base::PlatformFileInfo& file_info,
const base::FilePath& platform_path,
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref)>
SnapshotFileCallback;
// Used for Write().
typedef base::Callback<void(base::PlatformFileError result,
int64 bytes,
bool complete)> WriteCallback;
// Creates a file at |path|. If |exclusive| is true, an error is raised
// in case a file is already present at the URL.
virtual void CreateFile(const FileSystemURL& path,
bool exclusive,
const StatusCallback& callback) = 0;
// Creates a directory at |path|. If |exclusive| is true, an error is
// raised in case a directory is already present at the URL. If
// |recursive| is true, create parent directories as needed just like
// mkdir -p does.
virtual void CreateDirectory(const FileSystemURL& path,
bool exclusive,
bool recursive,
const StatusCallback& callback) = 0;
// Copies a file or directory from |src_path| to |dest_path|. If
// |src_path| is a directory, the contents of |src_path| are copied to
// |dest_path| recursively. A new file or directory is created at
// |dest_path| as needed.
virtual void Copy(const FileSystemURL& src_path,
const FileSystemURL& dest_path,
const StatusCallback& callback) = 0;
// Moves a file or directory from |src_path| to |dest_path|. A new file
// or directory is created at |dest_path| as needed.
virtual void Move(const FileSystemURL& src_path,
const FileSystemURL& dest_path,
const StatusCallback& callback) = 0;
// Checks if a directory is present at |path|.
virtual void DirectoryExists(const FileSystemURL& path,
const StatusCallback& callback) = 0;
// Checks if a file is present at |path|.
virtual void FileExists(const FileSystemURL& path,
const StatusCallback& callback) = 0;
// Gets the metadata of a file or directory at |path|.
virtual void GetMetadata(const FileSystemURL& path,
const GetMetadataCallback& callback) = 0;
// Reads contents of a directory at |path|.
virtual void ReadDirectory(const FileSystemURL& path,
const ReadDirectoryCallback& callback) = 0;
// Removes a file or directory at |path|. If |recursive| is true, remove
// all files and directories under the directory at |path| recursively.
virtual void Remove(const FileSystemURL& path, bool recursive,
const StatusCallback& callback) = 0;
// Writes the data read from |blob_request| using |writer_delegate|.
virtual void Write(
const FileSystemURL& url,
scoped_ptr<FileWriterDelegate> writer_delegate,
scoped_ptr<net::URLRequest> blob_request,
const WriteCallback& callback) = 0;
// Truncates a file at |path| to |length|. If |length| is larger than
// the original file size, the file will be extended, and the extended
// part is filled with null bytes.
virtual void Truncate(const FileSystemURL& path, int64 length,
const StatusCallback& callback) = 0;
// Tries to cancel the current operation [we support cancelling write or
// truncate only]. Reports failure for the current operation, then reports
// success for the cancel operation itself via the |cancel_dispatcher|.
//
// E.g. a typical cancel implementation would look like:
//
// virtual void SomeOperationImpl::Cancel(
// const StatusCallback& cancel_callback) {
// // Abort the current inflight operation first.
// ...
//
// // Dispatch ABORT error for the current operation by invoking
// // the callback function for the ongoing operation,
// operation_callback.Run(base::PLATFORM_FILE_ERROR_ABORT, ...);
//
// // Dispatch 'success' for the cancel (or dispatch appropriate
// // error code with DidFail() if the cancel has somehow failed).
// cancel_callback.Run(base::PLATFORM_FILE_OK);
// }
//
// Note that, for reporting failure, the callback function passed to a
// cancellable operations are kept around with the operation instance
// (as |operation_callback_| in the code example).
virtual void Cancel(const StatusCallback& cancel_callback) = 0;
// Modifies timestamps of a file or directory at |path| with
// |last_access_time| and |last_modified_time|. The function DOES NOT
// create a file unlike 'touch' command on Linux.
//
// This function is used only by Pepper as of writing.
virtual void TouchFile(const FileSystemURL& path,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback) = 0;
// Opens a file at |path| with |file_flags|, where flags are OR'ed
// values of base::PlatformFileFlags.
//
// |peer_handle| is the process handle of a pepper plugin process, which
// is necessary for underlying IPC calls with Pepper plugins.
//
// This function is used only by Pepper as of writing.
virtual void OpenFile(const FileSystemURL& path,
int file_flags,
base::ProcessHandle peer_handle,
const OpenFileCallback& callback) = 0;
// For downcasting to FileSystemOperationImpl.
// TODO(kinuko): this hack should go away once appropriate upload-stream
// handling based on element types is supported.
virtual FileSystemOperationImpl* AsFileSystemOperationImpl() = 0;
// Creates a local snapshot file for a given |path| and returns the
// metadata and platform path of the snapshot file via |callback|.
// In local filesystem cases the implementation may simply return
// the metadata of the file itself (as well as GetMetadata does),
// while in remote filesystem case the backend may want to download the file
// into a temporary snapshot file and return the metadata of the
// temporary file. Or if the implementaiton already has the local cache
// data for |path| it can simply return the path to the cache.
virtual void CreateSnapshotFile(const FileSystemURL& path,
const SnapshotFileCallback& callback) = 0;
protected:
// Used only for internal assertions.
enum OperationType {
kOperationNone,
kOperationCreateFile,
kOperationCreateDirectory,
kOperationCreateSnapshotFile,
kOperationCopy,
kOperationCopyInForeignFile,
kOperationMove,
kOperationDirectoryExists,
kOperationFileExists,
kOperationGetMetadata,
kOperationReadDirectory,
kOperationRemove,
kOperationWrite,
kOperationTruncate,
kOperationTouchFile,
kOperationOpenFile,
kOperationCloseFile,
kOperationGetLocalPath,
kOperationCancel,
};
};
} // namespace fileapi
#endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_