1 // Copyright (c) 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. 4 5 #ifndef WEBKIT_BROWSER_FILEAPI_ASYNC_FILE_UTIL_H_ 6 #define WEBKIT_BROWSER_FILEAPI_ASYNC_FILE_UTIL_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/callback_forward.h" 12 #include "base/files/file_util_proxy.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/platform_file.h" 15 #include "webkit/browser/fileapi/file_system_operation.h" 16 #include "webkit/browser/webkit_storage_browser_export.h" 17 #include "webkit/common/fileapi/directory_entry.h" 18 19 namespace base { 20 class Time; 21 } 22 23 namespace webkit_blob { 24 class ShareableFileReference; 25 } 26 27 namespace fileapi { 28 29 class FileSystemOperationContext; 30 class FileSystemURL; 31 32 // An interface which provides filesystem-specific file operations for 33 // FileSystemOperationImpl. 34 // 35 // Each filesystem which needs to be dispatched from FileSystemOperationImpl 36 // must implement this interface or a synchronous version of interface: 37 // FileSystemFileUtil. 38 // 39 // As far as an instance of this class is owned by a FileSystemBackend 40 // (which is owned by FileSystemContext), it's guaranteed that this instance's 41 // alive while FileSystemOperationContext given to each operation is kept 42 // alive. (Note that this instance might be freed on different thread 43 // from the thread it is created.) 44 // 45 // It is NOT valid to give null callback to this class, and implementors 46 // can assume that they don't get any null callbacks. 47 // 48 class AsyncFileUtil { 49 public: 50 typedef base::Callback< 51 void(base::PlatformFileError result)> StatusCallback; 52 53 // |on_close_callback| will be called after the |file| is closed in the 54 // child process. |on_close_callback|.is_null() can be true, if no operation 55 // is needed on closing the file. 56 typedef base::Callback< 57 void(base::PlatformFileError result, 58 base::PassPlatformFile file, 59 const base::Closure& on_close_callback)> CreateOrOpenCallback; 60 61 typedef base::Callback< 62 void(base::PlatformFileError result, 63 bool created)> EnsureFileExistsCallback; 64 65 typedef base::Callback< 66 void(base::PlatformFileError result, 67 const base::PlatformFileInfo& file_info)> GetFileInfoCallback; 68 69 typedef std::vector<DirectoryEntry> EntryList; 70 typedef base::Callback< 71 void(base::PlatformFileError result, 72 const EntryList& file_list, 73 bool has_more)> ReadDirectoryCallback; 74 75 typedef base::Callback< 76 void(base::PlatformFileError result, 77 const base::PlatformFileInfo& file_info, 78 const base::FilePath& platform_path, 79 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref)> 80 CreateSnapshotFileCallback; 81 82 83 typedef base::Callback<void(int64 size)> CopyFileProgressCallback; 84 85 typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption; 86 87 // Creates an AsyncFileUtil instance which performs file operations on 88 // local native file system. The created instance assumes 89 // FileSystemURL::path() has the target platform path. 90 WEBKIT_STORAGE_BROWSER_EXPORT static AsyncFileUtil* 91 CreateForLocalFileSystem(); 92 AsyncFileUtil()93 AsyncFileUtil() {} ~AsyncFileUtil()94 virtual ~AsyncFileUtil() {} 95 96 // Creates or opens a file with the given flags. 97 // If PLATFORM_FILE_CREATE is set in |file_flags| it always tries to create 98 // a new file at the given |url| and calls back with 99 // PLATFORM_FILE_ERROR_FILE_EXISTS if the |url| already exists. 100 // 101 // FileSystemOperationImpl::OpenFile calls this. 102 // This is used only by Pepper/NaCl File API. 103 // 104 virtual void CreateOrOpen( 105 scoped_ptr<FileSystemOperationContext> context, 106 const FileSystemURL& url, 107 int file_flags, 108 const CreateOrOpenCallback& callback) = 0; 109 110 // Ensures that the given |url| exist. This creates a empty new file 111 // at |url| if the |url| does not exist. 112 // 113 // FileSystemOperationImpl::CreateFile calls this. 114 // 115 // This reports following error code via |callback|: 116 // - PLATFORM_FILE_OK and created==true if a file has not existed and 117 // is created at |url|. 118 // - PLATFORM_FILE_OK and created==false if the file already exists. 119 // - Other error code (with created=false) if a file hasn't existed yet 120 // and there was an error while creating a new file. 121 // 122 virtual void EnsureFileExists( 123 scoped_ptr<FileSystemOperationContext> context, 124 const FileSystemURL& url, 125 const EnsureFileExistsCallback& callback) = 0; 126 127 // Creates directory at given url. 128 // 129 // FileSystemOperationImpl::CreateDirectory calls this. 130 // 131 // This reports following error code via |callback|: 132 // - PLATFORM_FILE_ERROR_NOT_FOUND if the |url|'s parent directory 133 // does not exist and |recursive| is false. 134 // - PLATFORM_FILE_ERROR_EXISTS if a directory already exists at |url| 135 // and |exclusive| is true. 136 // - PLATFORM_FILE_ERROR_EXISTS if a file already exists at |url| 137 // (regardless of |exclusive| value). 138 // - Other error code if it failed to create a directory. 139 // 140 virtual void CreateDirectory( 141 scoped_ptr<FileSystemOperationContext> context, 142 const FileSystemURL& url, 143 bool exclusive, 144 bool recursive, 145 const StatusCallback& callback) = 0; 146 147 // Retrieves the information about a file. 148 // 149 // FileSystemOperationImpl::GetMetadata calls this. 150 // 151 // This reports following error code via |callback|: 152 // - PLATFORM_FILE_ERROR_NOT_FOUND if the file doesn't exist. 153 // - Other error code if there was an error while retrieving the file info. 154 // 155 virtual void GetFileInfo( 156 scoped_ptr<FileSystemOperationContext> context, 157 const FileSystemURL& url, 158 const GetFileInfoCallback& callback) = 0; 159 160 // Reads contents of a directory at |path|. 161 // 162 // FileSystemOperationImpl::ReadDirectory calls this. 163 // 164 // Note that the |name| field of each entry in |file_list| 165 // returned by |callback| should have a base file name 166 // of the entry relative to the directory, but not an absolute path. 167 // 168 // (E.g. if ReadDirectory is called for a directory 169 // 'path/to/dir' and the directory has entries 'a' and 'b', 170 // the returned |file_list| should include entries whose names 171 // are 'a' and 'b', but not '/path/to/dir/a' and '/path/to/dir/b'.) 172 // 173 // This reports following error code via |callback|: 174 // - PLATFORM_FILE_ERROR_NOT_FOUND if the target directory doesn't exist. 175 // - PLATFORM_FILE_ERROR_NOT_A_DIRECTORY if an entry exists at |url| but 176 // is a file (not a directory). 177 // 178 virtual void ReadDirectory( 179 scoped_ptr<FileSystemOperationContext> context, 180 const FileSystemURL& url, 181 const ReadDirectoryCallback& callback) = 0; 182 183 // Modifies timestamps of a file or directory at |url| with 184 // |last_access_time| and |last_modified_time|. The function DOES NOT 185 // create a file unlike 'touch' command on Linux. 186 // 187 // FileSystemOperationImpl::TouchFile calls this. 188 // This is used only by Pepper/NaCl File API. 189 // 190 virtual void Touch( 191 scoped_ptr<FileSystemOperationContext> context, 192 const FileSystemURL& url, 193 const base::Time& last_access_time, 194 const base::Time& last_modified_time, 195 const StatusCallback& callback) = 0; 196 197 // Truncates a file at |path| to |length|. If |length| is larger than 198 // the original file size, the file will be extended, and the extended 199 // part is filled with null bytes. 200 // 201 // FileSystemOperationImpl::Truncate calls this. 202 // 203 // This reports following error code via |callback|: 204 // - PLATFORM_FILE_ERROR_NOT_FOUND if the file doesn't exist. 205 // 206 virtual void Truncate( 207 scoped_ptr<FileSystemOperationContext> context, 208 const FileSystemURL& url, 209 int64 length, 210 const StatusCallback& callback) = 0; 211 212 // Copies a file from |src_url| to |dest_url|. 213 // This must be called for files that belong to the same filesystem 214 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). 215 // |progress_callback| is a callback to report the progress update. 216 // See file_system_operations.h for details. This should be called on the 217 // same thread as where the method's called (IO thread). Calling this 218 // is optional. It is recommended to use this callback for heavier operations 219 // (such as file network downloading), so that, e.g., clients (UIs) can 220 // update its state to show progress to users. This may be a null callback. 221 // 222 // FileSystemOperationImpl::Copy calls this for same-filesystem copy case. 223 // 224 // This reports following error code via |callback|: 225 // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_url| 226 // or the parent directory of |dest_url| does not exist. 227 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. 228 // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and 229 // is not a file. 230 // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and 231 // its parent path is a file. 232 // 233 virtual void CopyFileLocal( 234 scoped_ptr<FileSystemOperationContext> context, 235 const FileSystemURL& src_url, 236 const FileSystemURL& dest_url, 237 CopyOrMoveOption option, 238 const CopyFileProgressCallback& progress_callback, 239 const StatusCallback& callback) = 0; 240 241 // Moves a local file from |src_url| to |dest_url|. 242 // This must be called for files that belong to the same filesystem 243 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). 244 // 245 // FileSystemOperationImpl::Move calls this for same-filesystem move case. 246 // 247 // This reports following error code via |callback|: 248 // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_url| 249 // or the parent directory of |dest_url| does not exist. 250 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. 251 // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and 252 // is not a file. 253 // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and 254 // its parent path is a file. 255 // 256 virtual void MoveFileLocal( 257 scoped_ptr<FileSystemOperationContext> context, 258 const FileSystemURL& src_url, 259 const FileSystemURL& dest_url, 260 CopyOrMoveOption option, 261 const StatusCallback& callback) = 0; 262 263 // Copies in a single file from a different filesystem. 264 // 265 // FileSystemOperationImpl::Copy or Move calls this for cross-filesystem 266 // cases. 267 // 268 // This reports following error code via |callback|: 269 // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_file_path| 270 // or the parent directory of |dest_url| does not exist. 271 // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and 272 // is not a file. 273 // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and 274 // its parent path is a file. 275 // 276 virtual void CopyInForeignFile( 277 scoped_ptr<FileSystemOperationContext> context, 278 const base::FilePath& src_file_path, 279 const FileSystemURL& dest_url, 280 const StatusCallback& callback) = 0; 281 282 // Deletes a single file. 283 // 284 // FileSystemOperationImpl::RemoveFile calls this. 285 // 286 // This reports following error code via |callback|: 287 // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist. 288 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |url| is not a file. 289 // 290 virtual void DeleteFile( 291 scoped_ptr<FileSystemOperationContext> context, 292 const FileSystemURL& url, 293 const StatusCallback& callback) = 0; 294 295 // Removes a single empty directory. 296 // 297 // FileSystemOperationImpl::RemoveDirectory calls this. 298 // 299 // This reports following error code via |callback|: 300 // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist. 301 // - PLATFORM_FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory. 302 // - PLATFORM_FILE_ERROR_NOT_EMPTY if |url| is not empty. 303 // 304 virtual void DeleteDirectory( 305 scoped_ptr<FileSystemOperationContext> context, 306 const FileSystemURL& url, 307 const StatusCallback& callback) = 0; 308 309 // Removes a single file or a single directory with its contents 310 // (i.e. files/subdirectories under the directory). 311 // 312 // FileSystemOperationImpl::Remove calls this. 313 // On some platforms, such as Chrome OS Drive File System, recursive file 314 // deletion can be implemented more efficiently than calling DeleteFile() and 315 // DeleteDirectory() for each files/directories. 316 // This method is optional, so if not supported, 317 // PLATFORM_ERROR_INVALID_OPERATION should be returned via |callback|. 318 // 319 // This reports following error code via |callback|: 320 // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist. 321 // - PLATFORM_ERROR_INVALID_OPERATION if this operation is not supported. 322 virtual void DeleteRecursively( 323 scoped_ptr<FileSystemOperationContext> context, 324 const FileSystemURL& url, 325 const StatusCallback& callback) = 0; 326 327 // Creates a local snapshot file for a given |url| and returns the 328 // metadata and platform path of the snapshot file via |callback|. 329 // In regular filesystem cases the implementation may simply return 330 // the metadata of the file itself (as well as GetMetadata does), 331 // while in non-regular filesystem case the backend may create a 332 // temporary snapshot file which holds the file data and return 333 // the metadata of the temporary file. 334 // 335 // In the callback, it returns: 336 // |file_info| is the metadata of the snapshot file created. 337 // |platform_path| is the full absolute platform path to the snapshot 338 // file created. If a file is not backed by a real local file in 339 // the implementor's FileSystem, the implementor must create a 340 // local snapshot file and return the path of the created file. 341 // 342 // If implementors creates a temporary file for snapshotting and wants 343 // FileAPI backend to take care of the lifetime of the file (so that 344 // it won't get deleted while JS layer has any references to the created 345 // File/Blob object), it should return non-empty |file_ref|. 346 // Via the |file_ref| implementors can schedule a file deletion 347 // or arbitrary callbacks when the last reference of File/Blob is dropped. 348 // 349 // FileSystemOperationImpl::CreateSnapshotFile calls this. 350 // 351 // This reports following error code via |callback|: 352 // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist. 353 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |url| exists but is a directory. 354 // 355 // The field values of |file_info| are undefined (implementation 356 // dependent) in error cases, and the caller should always 357 // check the return code. 358 virtual void CreateSnapshotFile( 359 scoped_ptr<FileSystemOperationContext> context, 360 const FileSystemURL& url, 361 const CreateSnapshotFileCallback& callback) = 0; 362 363 private: 364 DISALLOW_COPY_AND_ASSIGN(AsyncFileUtil); 365 }; 366 367 } // namespace fileapi 368 369 #endif // WEBKIT_BROWSER_FILEAPI_ASYNC_FILE_UTIL_H_ 370