1 // Copyright 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_FILE_SYSTEM_OPERATION_IMPL_H_ 6 #define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_IMPL_H_ 7 8 #include <vector> 9 10 #include "base/memory/ref_counted.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/weak_ptr.h" 13 #include "webkit/browser/fileapi/file_system_operation.h" 14 #include "webkit/browser/fileapi/file_system_operation_context.h" 15 #include "webkit/browser/fileapi/file_system_url.h" 16 #include "webkit/browser/fileapi/file_writer_delegate.h" 17 #include "webkit/browser/webkit_storage_browser_export.h" 18 #include "webkit/common/blob/scoped_file.h" 19 #include "webkit/common/quota/quota_types.h" 20 21 namespace fileapi { 22 23 class AsyncFileUtil; 24 class FileSystemContext; 25 class RecursiveOperationDelegate; 26 27 // The default implementation of FileSystemOperation for file systems. 28 class WEBKIT_STORAGE_BROWSER_EXPORT FileSystemOperationImpl 29 : public NON_EXPORTED_BASE(FileSystemOperation), 30 public base::SupportsWeakPtr<FileSystemOperationImpl> { 31 public: 32 // NOTE: This constructor should not be called outside FileSystemBackends; 33 // instead please consider using 34 // file_system_context->CreateFileSystemOperation() to instantiate 35 // an appropriate FileSystemOperation. 36 FileSystemOperationImpl( 37 const FileSystemURL& url, 38 FileSystemContext* file_system_context, 39 scoped_ptr<FileSystemOperationContext> operation_context); 40 41 virtual ~FileSystemOperationImpl(); 42 43 // FileSystemOperation overrides. 44 virtual void CreateFile(const FileSystemURL& url, 45 bool exclusive, 46 const StatusCallback& callback) OVERRIDE; 47 virtual void CreateDirectory(const FileSystemURL& url, 48 bool exclusive, 49 bool recursive, 50 const StatusCallback& callback) OVERRIDE; 51 virtual void Copy(const FileSystemURL& src_url, 52 const FileSystemURL& dest_url, 53 const StatusCallback& callback) OVERRIDE; 54 virtual void Move(const FileSystemURL& src_url, 55 const FileSystemURL& dest_url, 56 const StatusCallback& callback) OVERRIDE; 57 virtual void DirectoryExists(const FileSystemURL& url, 58 const StatusCallback& callback) OVERRIDE; 59 virtual void FileExists(const FileSystemURL& url, 60 const StatusCallback& callback) OVERRIDE; 61 virtual void GetMetadata(const FileSystemURL& url, 62 const GetMetadataCallback& callback) OVERRIDE; 63 virtual void ReadDirectory(const FileSystemURL& url, 64 const ReadDirectoryCallback& callback) OVERRIDE; 65 virtual void Remove(const FileSystemURL& url, bool recursive, 66 const StatusCallback& callback) OVERRIDE; 67 virtual void Write(const FileSystemURL& url, 68 scoped_ptr<FileWriterDelegate> writer_delegate, 69 scoped_ptr<net::URLRequest> blob_request, 70 const WriteCallback& callback) OVERRIDE; 71 virtual void Truncate(const FileSystemURL& url, int64 length, 72 const StatusCallback& callback) OVERRIDE; 73 virtual void TouchFile(const FileSystemURL& url, 74 const base::Time& last_access_time, 75 const base::Time& last_modified_time, 76 const StatusCallback& callback) OVERRIDE; 77 virtual void OpenFile(const FileSystemURL& url, 78 int file_flags, 79 base::ProcessHandle peer_handle, 80 const OpenFileCallback& callback) OVERRIDE; 81 virtual void Cancel(const StatusCallback& cancel_callback) OVERRIDE; 82 virtual FileSystemOperationImpl* AsFileSystemOperationImpl() OVERRIDE; 83 virtual void CreateSnapshotFile( 84 const FileSystemURL& path, 85 const SnapshotFileCallback& callback) OVERRIDE; 86 87 // Copies in a single file from a different filesystem. 88 // 89 // This returns: 90 // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_file_path| 91 // or the parent directory of |dest_url| does not exist. 92 // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and 93 // is not a file. 94 // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and 95 // its parent path is a file. 96 // 97 virtual void CopyInForeignFile(const base::FilePath& src_local_disk_path, 98 const FileSystemURL& dest_url, 99 const StatusCallback& callback); 100 101 // Removes a single file. 102 // 103 // This returns: 104 // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist. 105 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |url| is not a file. 106 // 107 void RemoveFile(const FileSystemURL& url, 108 const StatusCallback& callback); 109 110 // Removes a single empty directory. 111 // 112 // This returns: 113 // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist. 114 // - PLATFORM_FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory. 115 // - PLATFORM_FILE_ERROR_NOT_EMPTY if |url| is not empty. 116 // 117 void RemoveDirectory(const FileSystemURL& url, 118 const StatusCallback& callback); 119 120 // Copies a file from |src_url| to |dest_url|. 121 // This must be called for files that belong to the same filesystem 122 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). 123 // 124 // This returns: 125 // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_url| 126 // or the parent directory of |dest_url| does not exist. 127 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. 128 // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and 129 // is not a file. 130 // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and 131 // its parent path is a file. 132 // 133 void CopyFileLocal(const FileSystemURL& src_url, 134 const FileSystemURL& dest_url, 135 const StatusCallback& callback); 136 137 // Moves a local file from |src_url| to |dest_url|. 138 // This must be called for files that belong to the same filesystem 139 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). 140 // 141 // This returns: 142 // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_url| 143 // or the parent directory of |dest_url| does not exist. 144 // - PLATFORM_FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. 145 // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and 146 // is not a file. 147 // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and 148 // its parent path is a file. 149 // 150 void MoveFileLocal(const FileSystemURL& src_url, 151 const FileSystemURL& dest_url, 152 const StatusCallback& callback); 153 154 // Synchronously gets the platform path for the given |url|. 155 // This may fail if |file_system_context| returns NULL on GetFileUtil(). 156 // In such a case, base::PLATFORM_FILE_ERROR_INVALID_OPERATION will be 157 // returned. 158 base::PlatformFileError SyncGetPlatformPath(const FileSystemURL& url, 159 base::FilePath* platform_path); 160 161 FileSystemContext* file_system_context() const { 162 return file_system_context_.get(); 163 } 164 165 protected: 166 // Queries the quota and usage and then runs the given |task|. 167 // If an error occurs during the quota query it runs |error_callback| instead. 168 void GetUsageAndQuotaThenRunTask( 169 const FileSystemURL& url, 170 const base::Closure& task, 171 const base::Closure& error_callback); 172 173 // Called after the quota info is obtained from the quota manager 174 // (which is triggered by GetUsageAndQuotaThenRunTask). 175 // Sets the quota info in the operation_context_ and then runs the given 176 // |task| if the returned quota status is successful, otherwise runs 177 // |error_callback|. 178 void DidGetUsageAndQuotaAndRunTask( 179 const base::Closure& task, 180 const base::Closure& error_callback, 181 quota::QuotaStatusCode status, 182 int64 usage, int64 quota); 183 184 // The 'body' methods that perform the actual work (i.e. posting the 185 // file task on proxy_) after the quota check. 186 void DoCreateFile(const FileSystemURL& url, 187 const StatusCallback& callback, bool exclusive); 188 void DoCreateDirectory(const FileSystemURL& url, 189 const StatusCallback& callback, 190 bool exclusive, 191 bool recursive); 192 void DoCopyFileLocal(const FileSystemURL& src, 193 const FileSystemURL& dest, 194 const StatusCallback& callback); 195 void DoMoveFileLocal(const FileSystemURL& src, 196 const FileSystemURL& dest, 197 const StatusCallback& callback); 198 void DoCopyInForeignFile(const base::FilePath& src_local_disk_file_path, 199 const FileSystemURL& dest, 200 const StatusCallback& callback); 201 void DoTruncate(const FileSystemURL& url, 202 const StatusCallback& callback, int64 length); 203 void DoOpenFile(const FileSystemURL& url, 204 const OpenFileCallback& callback, int file_flags); 205 206 // Callback for CreateFile for |exclusive|=true cases. 207 void DidEnsureFileExistsExclusive(const StatusCallback& callback, 208 base::PlatformFileError rv, 209 bool created); 210 211 // Callback for CreateFile for |exclusive|=false cases. 212 void DidEnsureFileExistsNonExclusive(const StatusCallback& callback, 213 base::PlatformFileError rv, 214 bool created); 215 216 void DidFinishOperation(const StatusCallback& callback, 217 base::PlatformFileError rv); 218 void DidDirectoryExists(const StatusCallback& callback, 219 base::PlatformFileError rv, 220 const base::PlatformFileInfo& file_info); 221 void DidFileExists(const StatusCallback& callback, 222 base::PlatformFileError rv, 223 const base::PlatformFileInfo& file_info); 224 void DidDeleteRecursively(const FileSystemURL& url, 225 const StatusCallback& callback, 226 base::PlatformFileError rv); 227 void DidWrite(const FileSystemURL& url, 228 const WriteCallback& callback, 229 base::PlatformFileError rv, 230 int64 bytes, 231 FileWriterDelegate::WriteProgressStatus write_status); 232 void DidOpenFile(const OpenFileCallback& callback, 233 base::PlatformFileError rv, 234 base::PassPlatformFile file, 235 const base::Closure& on_close_callback); 236 237 // Used only for internal assertions. 238 // Returns false if there's another inflight pending operation. 239 bool SetPendingOperationType(OperationType type); 240 241 scoped_refptr<FileSystemContext> file_system_context_; 242 243 scoped_ptr<FileSystemOperationContext> operation_context_; 244 AsyncFileUtil* async_file_util_; // Not owned. 245 246 scoped_ptr<FileWriterDelegate> file_writer_delegate_; 247 scoped_ptr<RecursiveOperationDelegate> recursive_operation_delegate_; 248 249 StatusCallback cancel_callback_; 250 251 // Used only by OpenFile, in order to clone the file handle back to the 252 // requesting process. 253 base::ProcessHandle peer_handle_; 254 255 // A flag to make sure we call operation only once per instance. 256 OperationType pending_operation_; 257 258 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImpl); 259 }; 260 261 } // namespace fileapi 262 263 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_IMPL_H_ 264