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. 4 5 #ifndef WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_ 6 #define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_ 7 8 #include <vector> 9 10 #include "base/callback.h" 11 #include "base/files/file_path.h" 12 #include "base/platform_file.h" 13 #include "base/process/process.h" 14 #include "webkit/common/fileapi/directory_entry.h" 15 16 namespace base { 17 class Time; 18 } 19 20 namespace net { 21 class URLRequest; 22 } 23 24 namespace webkit_blob { 25 class ShareableFileReference; 26 } 27 28 class GURL; 29 30 namespace fileapi { 31 32 class FileSystemURL; 33 class FileWriterDelegate; 34 class FileSystemOperationImpl; 35 36 // The interface class for FileSystemOperation implementations. 37 // 38 // This interface defines file system operations required to implement 39 // "File API: Directories and System" 40 // http://www.w3.org/TR/file-system-api/ 41 // 42 // DESIGN NOTES 43 // 44 // This class is designed to 45 // 46 // 1) Serve one-time file system operation per instance. Only one 47 // method(CreateFile, CreateDirectory, Copy, Move, DirectoryExists, 48 // GetMetadata, ReadDirectory and Remove) may be called during the 49 // lifetime of this object and it should be called no more than once. 50 // 51 // 2) Deliver the results of operations to the client via the callback function 52 // passed as the last parameter of the method. 53 // 54 // Note that it is valid to delete an operation while it is running. 55 // The callback will NOT be fired if the operation is deleted before 56 // it gets called. 57 class FileSystemOperation { 58 public: 59 virtual ~FileSystemOperation() {} 60 61 // Used for CreateFile(), etc. |result| is the return code of the operation. 62 typedef base::Callback<void(base::PlatformFileError result)> StatusCallback; 63 64 // Used for GetMetadata(). |result| is the return code of the operation, 65 // |file_info| is the obtained file info. 66 typedef base::Callback< 67 void(base::PlatformFileError result, 68 const base::PlatformFileInfo& file_info)> GetMetadataCallback; 69 70 // Used for OpenFile(). |result| is the return code of the operation. 71 // |on_close_callback| will be called after the file is closed in the child 72 // process. It can be null, if no operation is needed on closing a file. 73 typedef base::Callback< 74 void(base::PlatformFileError result, 75 base::PlatformFile file, 76 const base::Closure& on_close_callback, 77 base::ProcessHandle peer_handle)> OpenFileCallback; 78 79 // Used for ReadDirectoryCallback. 80 typedef std::vector<DirectoryEntry> FileEntryList; 81 82 // Used for ReadDirectory(). |result| is the return code of the operation, 83 // |file_list| is the list of files read, and |has_more| is true if some files 84 // are yet to be read. 85 typedef base::Callback< 86 void(base::PlatformFileError result, 87 const FileEntryList& file_list, 88 bool has_more)> ReadDirectoryCallback; 89 90 // Used for CreateSnapshotFile(). (Please see the comment at 91 // CreateSnapshotFile() below for how the method is called) 92 // |result| is the return code of the operation. 93 // |file_info| is the metadata of the snapshot file created. 94 // |platform_path| is the path to the snapshot file created. 95 // 96 // The snapshot file could simply be of the local file pointed by the given 97 // filesystem URL in local filesystem cases; remote filesystems 98 // may want to download the file into a temporary snapshot file and then 99 // return the metadata of the temporary file. 100 // 101 // |file_ref| is used to manage the lifetime of the returned 102 // snapshot file. It can be set to let the chromium backend take 103 // care of the life time of the snapshot file. Otherwise (if the returned 104 // file does not require any handling) the implementation can just 105 // return NULL. In a more complex case, the implementaiton can manage 106 // the lifetime of the snapshot file on its own (e.g. by its cache system) 107 // but also can be notified via the reference when the file becomes no 108 // longer necessary in the javascript world. 109 // Please see the comment for ShareableFileReference for details. 110 // 111 typedef base::Callback< 112 void(base::PlatformFileError result, 113 const base::PlatformFileInfo& file_info, 114 const base::FilePath& platform_path, 115 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref)> 116 SnapshotFileCallback; 117 118 // Used for Write(). 119 typedef base::Callback<void(base::PlatformFileError result, 120 int64 bytes, 121 bool complete)> WriteCallback; 122 123 // Creates a file at |path|. If |exclusive| is true, an error is raised 124 // in case a file is already present at the URL. 125 virtual void CreateFile(const FileSystemURL& path, 126 bool exclusive, 127 const StatusCallback& callback) = 0; 128 129 // Creates a directory at |path|. If |exclusive| is true, an error is 130 // raised in case a directory is already present at the URL. If 131 // |recursive| is true, create parent directories as needed just like 132 // mkdir -p does. 133 virtual void CreateDirectory(const FileSystemURL& path, 134 bool exclusive, 135 bool recursive, 136 const StatusCallback& callback) = 0; 137 138 // Copies a file or directory from |src_path| to |dest_path|. If 139 // |src_path| is a directory, the contents of |src_path| are copied to 140 // |dest_path| recursively. A new file or directory is created at 141 // |dest_path| as needed. 142 virtual void Copy(const FileSystemURL& src_path, 143 const FileSystemURL& dest_path, 144 const StatusCallback& callback) = 0; 145 146 // Moves a file or directory from |src_path| to |dest_path|. A new file 147 // or directory is created at |dest_path| as needed. 148 virtual void Move(const FileSystemURL& src_path, 149 const FileSystemURL& dest_path, 150 const StatusCallback& callback) = 0; 151 152 // Checks if a directory is present at |path|. 153 virtual void DirectoryExists(const FileSystemURL& path, 154 const StatusCallback& callback) = 0; 155 156 // Checks if a file is present at |path|. 157 virtual void FileExists(const FileSystemURL& path, 158 const StatusCallback& callback) = 0; 159 160 // Gets the metadata of a file or directory at |path|. 161 virtual void GetMetadata(const FileSystemURL& path, 162 const GetMetadataCallback& callback) = 0; 163 164 // Reads contents of a directory at |path|. 165 virtual void ReadDirectory(const FileSystemURL& path, 166 const ReadDirectoryCallback& callback) = 0; 167 168 // Removes a file or directory at |path|. If |recursive| is true, remove 169 // all files and directories under the directory at |path| recursively. 170 virtual void Remove(const FileSystemURL& path, bool recursive, 171 const StatusCallback& callback) = 0; 172 173 // Writes the data read from |blob_request| using |writer_delegate|. 174 virtual void Write( 175 const FileSystemURL& url, 176 scoped_ptr<FileWriterDelegate> writer_delegate, 177 scoped_ptr<net::URLRequest> blob_request, 178 const WriteCallback& callback) = 0; 179 180 // Truncates a file at |path| to |length|. If |length| is larger than 181 // the original file size, the file will be extended, and the extended 182 // part is filled with null bytes. 183 virtual void Truncate(const FileSystemURL& path, int64 length, 184 const StatusCallback& callback) = 0; 185 186 // Tries to cancel the current operation [we support cancelling write or 187 // truncate only]. Reports failure for the current operation, then reports 188 // success for the cancel operation itself via the |cancel_dispatcher|. 189 // 190 // E.g. a typical cancel implementation would look like: 191 // 192 // virtual void SomeOperationImpl::Cancel( 193 // const StatusCallback& cancel_callback) { 194 // // Abort the current inflight operation first. 195 // ... 196 // 197 // // Dispatch ABORT error for the current operation by invoking 198 // // the callback function for the ongoing operation, 199 // operation_callback.Run(base::PLATFORM_FILE_ERROR_ABORT, ...); 200 // 201 // // Dispatch 'success' for the cancel (or dispatch appropriate 202 // // error code with DidFail() if the cancel has somehow failed). 203 // cancel_callback.Run(base::PLATFORM_FILE_OK); 204 // } 205 // 206 // Note that, for reporting failure, the callback function passed to a 207 // cancellable operations are kept around with the operation instance 208 // (as |operation_callback_| in the code example). 209 virtual void Cancel(const StatusCallback& cancel_callback) = 0; 210 211 // Modifies timestamps of a file or directory at |path| with 212 // |last_access_time| and |last_modified_time|. The function DOES NOT 213 // create a file unlike 'touch' command on Linux. 214 // 215 // This function is used only by Pepper as of writing. 216 virtual void TouchFile(const FileSystemURL& path, 217 const base::Time& last_access_time, 218 const base::Time& last_modified_time, 219 const StatusCallback& callback) = 0; 220 221 // Opens a file at |path| with |file_flags|, where flags are OR'ed 222 // values of base::PlatformFileFlags. 223 // 224 // |peer_handle| is the process handle of a pepper plugin process, which 225 // is necessary for underlying IPC calls with Pepper plugins. 226 // 227 // This function is used only by Pepper as of writing. 228 virtual void OpenFile(const FileSystemURL& path, 229 int file_flags, 230 base::ProcessHandle peer_handle, 231 const OpenFileCallback& callback) = 0; 232 233 // For downcasting to FileSystemOperationImpl. 234 // TODO(kinuko): this hack should go away once appropriate upload-stream 235 // handling based on element types is supported. 236 virtual FileSystemOperationImpl* AsFileSystemOperationImpl() = 0; 237 238 // Creates a local snapshot file for a given |path| and returns the 239 // metadata and platform path of the snapshot file via |callback|. 240 // In local filesystem cases the implementation may simply return 241 // the metadata of the file itself (as well as GetMetadata does), 242 // while in remote filesystem case the backend may want to download the file 243 // into a temporary snapshot file and return the metadata of the 244 // temporary file. Or if the implementaiton already has the local cache 245 // data for |path| it can simply return the path to the cache. 246 virtual void CreateSnapshotFile(const FileSystemURL& path, 247 const SnapshotFileCallback& callback) = 0; 248 249 protected: 250 // Used only for internal assertions. 251 enum OperationType { 252 kOperationNone, 253 kOperationCreateFile, 254 kOperationCreateDirectory, 255 kOperationCreateSnapshotFile, 256 kOperationCopy, 257 kOperationCopyInForeignFile, 258 kOperationMove, 259 kOperationDirectoryExists, 260 kOperationFileExists, 261 kOperationGetMetadata, 262 kOperationReadDirectory, 263 kOperationRemove, 264 kOperationWrite, 265 kOperationTruncate, 266 kOperationTouchFile, 267 kOperationOpenFile, 268 kOperationCloseFile, 269 kOperationGetLocalPath, 270 kOperationCancel, 271 }; 272 }; 273 274 } // namespace fileapi 275 276 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_H_ 277