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