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