| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_ | 5 #include "storage/browser/fileapi/file_system_operation_runner.h" |
| 6 #define WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <set> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/id_map.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/memory/weak_ptr.h" | |
| 16 #include "webkit/browser/blob/blob_data_handle.h" | |
| 17 #include "webkit/browser/fileapi/file_system_operation.h" | |
| 18 #include "webkit/browser/fileapi/file_system_url.h" | |
| 19 #include "webkit/browser/storage_browser_export.h" | |
| 20 | |
| 21 namespace net { | |
| 22 class URLRequestContext; | |
| 23 } | |
| 24 | |
| 25 namespace storage { | |
| 26 | |
| 27 class FileSystemURL; | |
| 28 class FileSystemContext; | |
| 29 | |
| 30 // A central interface for running FileSystem API operations. | |
| 31 // All operation methods take callback and returns OperationID, which is | |
| 32 // an integer value which can be used for cancelling an operation. | |
| 33 // All operation methods return kErrorOperationID if running (posting) an | |
| 34 // operation fails, in addition to dispatching the callback with an error | |
| 35 // code (therefore in most cases the caller does not need to check the | |
| 36 // returned operation ID). | |
| 37 class STORAGE_EXPORT FileSystemOperationRunner | |
| 38 : public base::SupportsWeakPtr<FileSystemOperationRunner> { | |
| 39 public: | |
| 40 typedef FileSystemOperation::GetMetadataCallback GetMetadataCallback; | |
| 41 typedef FileSystemOperation::ReadDirectoryCallback ReadDirectoryCallback; | |
| 42 typedef FileSystemOperation::SnapshotFileCallback SnapshotFileCallback; | |
| 43 typedef FileSystemOperation::StatusCallback StatusCallback; | |
| 44 typedef FileSystemOperation::WriteCallback WriteCallback; | |
| 45 typedef FileSystemOperation::OpenFileCallback OpenFileCallback; | |
| 46 typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback; | |
| 47 typedef FileSystemOperation::CopyFileProgressCallback | |
| 48 CopyFileProgressCallback; | |
| 49 typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption; | |
| 50 | |
| 51 typedef int OperationID; | |
| 52 | |
| 53 virtual ~FileSystemOperationRunner(); | |
| 54 | |
| 55 // Cancels all inflight operations. | |
| 56 void Shutdown(); | |
| 57 | |
| 58 // Creates a file at |url|. If |exclusive| is true, an error is raised | |
| 59 // in case a file is already present at the URL. | |
| 60 OperationID CreateFile(const FileSystemURL& url, | |
| 61 bool exclusive, | |
| 62 const StatusCallback& callback); | |
| 63 | |
| 64 OperationID CreateDirectory(const FileSystemURL& url, | |
| 65 bool exclusive, | |
| 66 bool recursive, | |
| 67 const StatusCallback& callback); | |
| 68 | |
| 69 // Copies a file or directory from |src_url| to |dest_url|. If | |
| 70 // |src_url| is a directory, the contents of |src_url| are copied to | |
| 71 // |dest_url| recursively. A new file or directory is created at | |
| 72 // |dest_url| as needed. | |
| 73 // For |option| and |progress_callback|, see file_system_operation.h for | |
| 74 // details. | |
| 75 OperationID Copy(const FileSystemURL& src_url, | |
| 76 const FileSystemURL& dest_url, | |
| 77 CopyOrMoveOption option, | |
| 78 const CopyProgressCallback& progress_callback, | |
| 79 const StatusCallback& callback); | |
| 80 | |
| 81 // Moves a file or directory from |src_url| to |dest_url|. A new file | |
| 82 // or directory is created at |dest_url| as needed. | |
| 83 // For |option|, see file_system_operation.h for details. | |
| 84 OperationID Move(const FileSystemURL& src_url, | |
| 85 const FileSystemURL& dest_url, | |
| 86 CopyOrMoveOption option, | |
| 87 const StatusCallback& callback); | |
| 88 | |
| 89 // Checks if a directory is present at |url|. | |
| 90 OperationID DirectoryExists(const FileSystemURL& url, | |
| 91 const StatusCallback& callback); | |
| 92 | |
| 93 // Checks if a file is present at |url|. | |
| 94 OperationID FileExists(const FileSystemURL& url, | |
| 95 const StatusCallback& callback); | |
| 96 | |
| 97 // Gets the metadata of a file or directory at |url|. | |
| 98 OperationID GetMetadata(const FileSystemURL& url, | |
| 99 const GetMetadataCallback& callback); | |
| 100 | |
| 101 // Reads contents of a directory at |url|. | |
| 102 OperationID ReadDirectory(const FileSystemURL& url, | |
| 103 const ReadDirectoryCallback& callback); | |
| 104 | |
| 105 // Removes a file or directory at |url|. If |recursive| is true, remove | |
| 106 // all files and directories under the directory at |url| recursively. | |
| 107 OperationID Remove(const FileSystemURL& url, bool recursive, | |
| 108 const StatusCallback& callback); | |
| 109 | |
| 110 // Writes contents of |blob_url| to |url| at |offset|. | |
| 111 // |url_request_context| is used to read contents in |blob|. | |
| 112 OperationID Write(const net::URLRequestContext* url_request_context, | |
| 113 const FileSystemURL& url, | |
| 114 scoped_ptr<storage::BlobDataHandle> blob, | |
| 115 int64 offset, | |
| 116 const WriteCallback& callback); | |
| 117 | |
| 118 // Truncates a file at |url| to |length|. If |length| is larger than | |
| 119 // the original file size, the file will be extended, and the extended | |
| 120 // part is filled with null bytes. | |
| 121 OperationID Truncate(const FileSystemURL& url, int64 length, | |
| 122 const StatusCallback& callback); | |
| 123 | |
| 124 // Tries to cancel the operation |id| [we support cancelling write or | |
| 125 // truncate only]. Reports failure for the current operation, then reports | |
| 126 // success for the cancel operation itself via the |callback|. | |
| 127 void Cancel(OperationID id, const StatusCallback& callback); | |
| 128 | |
| 129 // Modifies timestamps of a file or directory at |url| with | |
| 130 // |last_access_time| and |last_modified_time|. The function DOES NOT | |
| 131 // create a file unlike 'touch' command on Linux. | |
| 132 // | |
| 133 // This function is used only by Pepper as of writing. | |
| 134 OperationID TouchFile(const FileSystemURL& url, | |
| 135 const base::Time& last_access_time, | |
| 136 const base::Time& last_modified_time, | |
| 137 const StatusCallback& callback); | |
| 138 | |
| 139 // Opens a file at |url| with |file_flags|, where flags are OR'ed | |
| 140 // values of base::PlatformFileFlags. | |
| 141 // | |
| 142 // |peer_handle| is the process handle of a pepper plugin process, which | |
| 143 // is necessary for underlying IPC calls with Pepper plugins. | |
| 144 // | |
| 145 // This function is used only by Pepper as of writing. | |
| 146 OperationID OpenFile(const FileSystemURL& url, | |
| 147 int file_flags, | |
| 148 const OpenFileCallback& callback); | |
| 149 | |
| 150 // Creates a local snapshot file for a given |url| and returns the | |
| 151 // metadata and platform url of the snapshot file via |callback|. | |
| 152 // In local filesystem cases the implementation may simply return | |
| 153 // the metadata of the file itself (as well as GetMetadata does), | |
| 154 // while in remote filesystem case the backend may want to download the file | |
| 155 // into a temporary snapshot file and return the metadata of the | |
| 156 // temporary file. Or if the implementaiton already has the local cache | |
| 157 // data for |url| it can simply return the url to the cache. | |
| 158 OperationID CreateSnapshotFile(const FileSystemURL& url, | |
| 159 const SnapshotFileCallback& callback); | |
| 160 | |
| 161 // Copies in a single file from a different filesystem. | |
| 162 // | |
| 163 // This returns: | |
| 164 // - File::FILE_ERROR_NOT_FOUND if |src_file_path| | |
| 165 // or the parent directory of |dest_url| does not exist. | |
| 166 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and | |
| 167 // is not a file. | |
| 168 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and | |
| 169 // its parent path is a file. | |
| 170 // | |
| 171 OperationID CopyInForeignFile(const base::FilePath& src_local_disk_path, | |
| 172 const FileSystemURL& dest_url, | |
| 173 const StatusCallback& callback); | |
| 174 | |
| 175 // Removes a single file. | |
| 176 // | |
| 177 // This returns: | |
| 178 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist. | |
| 179 // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file. | |
| 180 // | |
| 181 OperationID RemoveFile(const FileSystemURL& url, | |
| 182 const StatusCallback& callback); | |
| 183 | |
| 184 // Removes a single empty directory. | |
| 185 // | |
| 186 // This returns: | |
| 187 // - File::FILE_ERROR_NOT_FOUND if |url| does not exist. | |
| 188 // - File::FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory. | |
| 189 // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty. | |
| 190 // | |
| 191 OperationID RemoveDirectory(const FileSystemURL& url, | |
| 192 const StatusCallback& callback); | |
| 193 | |
| 194 // Copies a file from |src_url| to |dest_url|. | |
| 195 // This must be called for files that belong to the same filesystem | |
| 196 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). | |
| 197 // For |option| and |progress_callback|, see file_system_operation.h for | |
| 198 // details. | |
| 199 // | |
| 200 // This returns: | |
| 201 // - File::FILE_ERROR_NOT_FOUND if |src_url| | |
| 202 // or the parent directory of |dest_url| does not exist. | |
| 203 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. | |
| 204 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and | |
| 205 // is not a file. | |
| 206 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and | |
| 207 // its parent path is a file. | |
| 208 // | |
| 209 OperationID CopyFileLocal(const FileSystemURL& src_url, | |
| 210 const FileSystemURL& dest_url, | |
| 211 CopyOrMoveOption option, | |
| 212 const CopyFileProgressCallback& progress_callback, | |
| 213 const StatusCallback& callback); | |
| 214 | |
| 215 // Moves a local file from |src_url| to |dest_url|. | |
| 216 // This must be called for files that belong to the same filesystem | |
| 217 // (i.e. type() and origin() of the |src_url| and |dest_url| must match). | |
| 218 // For |option|, see file_system_operation.h for details. | |
| 219 // | |
| 220 // This returns: | |
| 221 // - File::FILE_ERROR_NOT_FOUND if |src_url| | |
| 222 // or the parent directory of |dest_url| does not exist. | |
| 223 // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file. | |
| 224 // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and | |
| 225 // is not a file. | |
| 226 // - File::FILE_ERROR_FAILED if |dest_url| does not exist and | |
| 227 // its parent path is a file. | |
| 228 // | |
| 229 OperationID MoveFileLocal(const FileSystemURL& src_url, | |
| 230 const FileSystemURL& dest_url, | |
| 231 CopyOrMoveOption option, | |
| 232 const StatusCallback& callback); | |
| 233 | |
| 234 // This is called only by pepper plugin as of writing to synchronously get | |
| 235 // the underlying platform path to upload a file in the sandboxed filesystem | |
| 236 // (e.g. TEMPORARY or PERSISTENT). | |
| 237 base::File::Error SyncGetPlatformPath(const FileSystemURL& url, | |
| 238 base::FilePath* platform_path); | |
| 239 | |
| 240 private: | |
| 241 class BeginOperationScoper; | |
| 242 | |
| 243 struct OperationHandle { | |
| 244 OperationID id; | |
| 245 base::WeakPtr<BeginOperationScoper> scope; | |
| 246 | |
| 247 OperationHandle(); | |
| 248 ~OperationHandle(); | |
| 249 }; | |
| 250 | |
| 251 friend class FileSystemContext; | |
| 252 explicit FileSystemOperationRunner(FileSystemContext* file_system_context); | |
| 253 | |
| 254 void DidFinish(const OperationHandle& handle, | |
| 255 const StatusCallback& callback, | |
| 256 base::File::Error rv); | |
| 257 void DidGetMetadata(const OperationHandle& handle, | |
| 258 const GetMetadataCallback& callback, | |
| 259 base::File::Error rv, | |
| 260 const base::File::Info& file_info); | |
| 261 void DidReadDirectory(const OperationHandle& handle, | |
| 262 const ReadDirectoryCallback& callback, | |
| 263 base::File::Error rv, | |
| 264 const std::vector<DirectoryEntry>& entries, | |
| 265 bool has_more); | |
| 266 void DidWrite(const OperationHandle& handle, | |
| 267 const WriteCallback& callback, | |
| 268 base::File::Error rv, | |
| 269 int64 bytes, | |
| 270 bool complete); | |
| 271 void DidOpenFile( | |
| 272 const OperationHandle& handle, | |
| 273 const OpenFileCallback& callback, | |
| 274 base::File file, | |
| 275 const base::Closure& on_close_callback); | |
| 276 void DidCreateSnapshot( | |
| 277 const OperationHandle& handle, | |
| 278 const SnapshotFileCallback& callback, | |
| 279 base::File::Error rv, | |
| 280 const base::File::Info& file_info, | |
| 281 const base::FilePath& platform_path, | |
| 282 const scoped_refptr<storage::ShareableFileReference>& file_ref); | |
| 283 | |
| 284 void OnCopyProgress( | |
| 285 const OperationHandle& handle, | |
| 286 const CopyProgressCallback& callback, | |
| 287 FileSystemOperation::CopyProgressType type, | |
| 288 const FileSystemURL& source_url, | |
| 289 const FileSystemURL& dest_url, | |
| 290 int64 size); | |
| 291 | |
| 292 void PrepareForWrite(OperationID id, const FileSystemURL& url); | |
| 293 void PrepareForRead(OperationID id, const FileSystemURL& url); | |
| 294 | |
| 295 // These must be called at the beginning and end of any async operations. | |
| 296 OperationHandle BeginOperation(FileSystemOperation* operation, | |
| 297 base::WeakPtr<BeginOperationScoper> scope); | |
| 298 void FinishOperation(OperationID id); | |
| 299 | |
| 300 // Not owned; file_system_context owns this. | |
| 301 FileSystemContext* file_system_context_; | |
| 302 | |
| 303 // IDMap<FileSystemOperation, IDMapOwnPointer> operations_; | |
| 304 IDMap<FileSystemOperation, IDMapOwnPointer> operations_; | |
| 305 | |
| 306 // We keep track of the file to be modified by each operation so that | |
| 307 // we can notify observers when we're done. | |
| 308 typedef std::map<OperationID, FileSystemURLSet> OperationToURLSet; | |
| 309 OperationToURLSet write_target_urls_; | |
| 310 | |
| 311 // Operations that are finished but not yet fire their callbacks. | |
| 312 std::set<OperationID> finished_operations_; | |
| 313 | |
| 314 // Callbacks for stray cancels whose target operation is already finished. | |
| 315 std::map<OperationID, StatusCallback> stray_cancel_callbacks_; | |
| 316 | |
| 317 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner); | |
| 318 }; | |
| 319 | |
| 320 } // namespace storage | |
| 321 | |
| 322 #endif // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_ | |
| OLD | NEW |