| OLD | NEW |
| (Empty) |
| 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 #include "webkit/browser/fileapi/file_system_operation_runner.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/message_loop/message_loop_proxy.h" | |
| 9 #include "base/stl_util.h" | |
| 10 #include "net/url_request/url_request_context.h" | |
| 11 #include "webkit/browser/blob/blob_url_request_job_factory.h" | |
| 12 #include "webkit/browser/fileapi/file_observers.h" | |
| 13 #include "webkit/browser/fileapi/file_stream_writer.h" | |
| 14 #include "webkit/browser/fileapi/file_system_context.h" | |
| 15 #include "webkit/browser/fileapi/file_system_operation.h" | |
| 16 #include "webkit/browser/fileapi/file_writer_delegate.h" | |
| 17 #include "webkit/common/blob/shareable_file_reference.h" | |
| 18 | |
| 19 namespace storage { | |
| 20 | |
| 21 typedef FileSystemOperationRunner::OperationID OperationID; | |
| 22 | |
| 23 class FileSystemOperationRunner::BeginOperationScoper | |
| 24 : public base::SupportsWeakPtr< | |
| 25 FileSystemOperationRunner::BeginOperationScoper> { | |
| 26 public: | |
| 27 BeginOperationScoper() {} | |
| 28 private: | |
| 29 DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper); | |
| 30 }; | |
| 31 | |
| 32 FileSystemOperationRunner::OperationHandle::OperationHandle() {} | |
| 33 FileSystemOperationRunner::OperationHandle::~OperationHandle() {} | |
| 34 | |
| 35 FileSystemOperationRunner::~FileSystemOperationRunner() { | |
| 36 } | |
| 37 | |
| 38 void FileSystemOperationRunner::Shutdown() { | |
| 39 operations_.Clear(); | |
| 40 } | |
| 41 | |
| 42 OperationID FileSystemOperationRunner::CreateFile( | |
| 43 const FileSystemURL& url, | |
| 44 bool exclusive, | |
| 45 const StatusCallback& callback) { | |
| 46 base::File::Error error = base::File::FILE_OK; | |
| 47 FileSystemOperation* operation = | |
| 48 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 49 | |
| 50 BeginOperationScoper scope; | |
| 51 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 52 if (!operation) { | |
| 53 DidFinish(handle, callback, error); | |
| 54 return handle.id; | |
| 55 } | |
| 56 PrepareForWrite(handle.id, url); | |
| 57 operation->CreateFile( | |
| 58 url, exclusive, | |
| 59 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 60 handle, callback)); | |
| 61 return handle.id; | |
| 62 } | |
| 63 | |
| 64 OperationID FileSystemOperationRunner::CreateDirectory( | |
| 65 const FileSystemURL& url, | |
| 66 bool exclusive, | |
| 67 bool recursive, | |
| 68 const StatusCallback& callback) { | |
| 69 base::File::Error error = base::File::FILE_OK; | |
| 70 FileSystemOperation* operation = | |
| 71 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 72 BeginOperationScoper scope; | |
| 73 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 74 if (!operation) { | |
| 75 DidFinish(handle, callback, error); | |
| 76 return handle.id; | |
| 77 } | |
| 78 PrepareForWrite(handle.id, url); | |
| 79 operation->CreateDirectory( | |
| 80 url, exclusive, recursive, | |
| 81 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 82 handle, callback)); | |
| 83 return handle.id; | |
| 84 } | |
| 85 | |
| 86 OperationID FileSystemOperationRunner::Copy( | |
| 87 const FileSystemURL& src_url, | |
| 88 const FileSystemURL& dest_url, | |
| 89 CopyOrMoveOption option, | |
| 90 const CopyProgressCallback& progress_callback, | |
| 91 const StatusCallback& callback) { | |
| 92 base::File::Error error = base::File::FILE_OK; | |
| 93 FileSystemOperation* operation = | |
| 94 file_system_context_->CreateFileSystemOperation(dest_url, &error); | |
| 95 BeginOperationScoper scope; | |
| 96 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 97 if (!operation) { | |
| 98 DidFinish(handle, callback, error); | |
| 99 return handle.id; | |
| 100 } | |
| 101 PrepareForWrite(handle.id, dest_url); | |
| 102 PrepareForRead(handle.id, src_url); | |
| 103 operation->Copy( | |
| 104 src_url, dest_url, option, | |
| 105 progress_callback.is_null() ? | |
| 106 CopyProgressCallback() : | |
| 107 base::Bind(&FileSystemOperationRunner::OnCopyProgress, AsWeakPtr(), | |
| 108 handle, progress_callback), | |
| 109 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 110 handle, callback)); | |
| 111 return handle.id; | |
| 112 } | |
| 113 | |
| 114 OperationID FileSystemOperationRunner::Move( | |
| 115 const FileSystemURL& src_url, | |
| 116 const FileSystemURL& dest_url, | |
| 117 CopyOrMoveOption option, | |
| 118 const StatusCallback& callback) { | |
| 119 base::File::Error error = base::File::FILE_OK; | |
| 120 FileSystemOperation* operation = | |
| 121 file_system_context_->CreateFileSystemOperation(dest_url, &error); | |
| 122 BeginOperationScoper scope; | |
| 123 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 124 if (!operation) { | |
| 125 DidFinish(handle, callback, error); | |
| 126 return handle.id; | |
| 127 } | |
| 128 PrepareForWrite(handle.id, dest_url); | |
| 129 PrepareForWrite(handle.id, src_url); | |
| 130 operation->Move( | |
| 131 src_url, dest_url, option, | |
| 132 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 133 handle, callback)); | |
| 134 return handle.id; | |
| 135 } | |
| 136 | |
| 137 OperationID FileSystemOperationRunner::DirectoryExists( | |
| 138 const FileSystemURL& url, | |
| 139 const StatusCallback& callback) { | |
| 140 base::File::Error error = base::File::FILE_OK; | |
| 141 FileSystemOperation* operation = | |
| 142 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 143 BeginOperationScoper scope; | |
| 144 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 145 if (!operation) { | |
| 146 DidFinish(handle, callback, error); | |
| 147 return handle.id; | |
| 148 } | |
| 149 PrepareForRead(handle.id, url); | |
| 150 operation->DirectoryExists( | |
| 151 url, | |
| 152 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 153 handle, callback)); | |
| 154 return handle.id; | |
| 155 } | |
| 156 | |
| 157 OperationID FileSystemOperationRunner::FileExists( | |
| 158 const FileSystemURL& url, | |
| 159 const StatusCallback& callback) { | |
| 160 base::File::Error error = base::File::FILE_OK; | |
| 161 FileSystemOperation* operation = | |
| 162 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 163 BeginOperationScoper scope; | |
| 164 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 165 if (!operation) { | |
| 166 DidFinish(handle, callback, error); | |
| 167 return handle.id; | |
| 168 } | |
| 169 PrepareForRead(handle.id, url); | |
| 170 operation->FileExists( | |
| 171 url, | |
| 172 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 173 handle, callback)); | |
| 174 return handle.id; | |
| 175 } | |
| 176 | |
| 177 OperationID FileSystemOperationRunner::GetMetadata( | |
| 178 const FileSystemURL& url, | |
| 179 const GetMetadataCallback& callback) { | |
| 180 base::File::Error error = base::File::FILE_OK; | |
| 181 FileSystemOperation* operation = | |
| 182 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 183 BeginOperationScoper scope; | |
| 184 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 185 if (!operation) { | |
| 186 DidGetMetadata(handle, callback, error, base::File::Info()); | |
| 187 return handle.id; | |
| 188 } | |
| 189 PrepareForRead(handle.id, url); | |
| 190 operation->GetMetadata( | |
| 191 url, | |
| 192 base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(), | |
| 193 handle, callback)); | |
| 194 return handle.id; | |
| 195 } | |
| 196 | |
| 197 OperationID FileSystemOperationRunner::ReadDirectory( | |
| 198 const FileSystemURL& url, | |
| 199 const ReadDirectoryCallback& callback) { | |
| 200 base::File::Error error = base::File::FILE_OK; | |
| 201 FileSystemOperation* operation = | |
| 202 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 203 BeginOperationScoper scope; | |
| 204 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 205 if (!operation) { | |
| 206 DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(), | |
| 207 false); | |
| 208 return handle.id; | |
| 209 } | |
| 210 PrepareForRead(handle.id, url); | |
| 211 operation->ReadDirectory( | |
| 212 url, | |
| 213 base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(), | |
| 214 handle, callback)); | |
| 215 return handle.id; | |
| 216 } | |
| 217 | |
| 218 OperationID FileSystemOperationRunner::Remove( | |
| 219 const FileSystemURL& url, bool recursive, | |
| 220 const StatusCallback& callback) { | |
| 221 base::File::Error error = base::File::FILE_OK; | |
| 222 FileSystemOperation* operation = | |
| 223 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 224 BeginOperationScoper scope; | |
| 225 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 226 if (!operation) { | |
| 227 DidFinish(handle, callback, error); | |
| 228 return handle.id; | |
| 229 } | |
| 230 PrepareForWrite(handle.id, url); | |
| 231 operation->Remove( | |
| 232 url, recursive, | |
| 233 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 234 handle, callback)); | |
| 235 return handle.id; | |
| 236 } | |
| 237 | |
| 238 OperationID FileSystemOperationRunner::Write( | |
| 239 const net::URLRequestContext* url_request_context, | |
| 240 const FileSystemURL& url, | |
| 241 scoped_ptr<storage::BlobDataHandle> blob, | |
| 242 int64 offset, | |
| 243 const WriteCallback& callback) { | |
| 244 base::File::Error error = base::File::FILE_OK; | |
| 245 FileSystemOperation* operation = | |
| 246 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 247 | |
| 248 BeginOperationScoper scope; | |
| 249 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 250 if (!operation) { | |
| 251 DidWrite(handle, callback, error, 0, true); | |
| 252 return handle.id; | |
| 253 } | |
| 254 | |
| 255 scoped_ptr<FileStreamWriter> writer( | |
| 256 file_system_context_->CreateFileStreamWriter(url, offset)); | |
| 257 if (!writer) { | |
| 258 // Write is not supported. | |
| 259 DidWrite(handle, callback, base::File::FILE_ERROR_SECURITY, 0, true); | |
| 260 return handle.id; | |
| 261 } | |
| 262 | |
| 263 FileWriterDelegate::FlushPolicy flush_policy = | |
| 264 file_system_context_->ShouldFlushOnWriteCompletion(url.type()) | |
| 265 ? FileWriterDelegate::FLUSH_ON_COMPLETION | |
| 266 : FileWriterDelegate::NO_FLUSH_ON_COMPLETION; | |
| 267 scoped_ptr<FileWriterDelegate> writer_delegate( | |
| 268 new FileWriterDelegate(writer.Pass(), flush_policy)); | |
| 269 | |
| 270 scoped_ptr<net::URLRequest> blob_request( | |
| 271 storage::BlobProtocolHandler::CreateBlobRequest( | |
| 272 blob.Pass(), url_request_context, writer_delegate.get())); | |
| 273 | |
| 274 PrepareForWrite(handle.id, url); | |
| 275 operation->Write( | |
| 276 url, writer_delegate.Pass(), blob_request.Pass(), | |
| 277 base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), | |
| 278 handle, callback)); | |
| 279 return handle.id; | |
| 280 } | |
| 281 | |
| 282 OperationID FileSystemOperationRunner::Truncate( | |
| 283 const FileSystemURL& url, int64 length, | |
| 284 const StatusCallback& callback) { | |
| 285 base::File::Error error = base::File::FILE_OK; | |
| 286 FileSystemOperation* operation = | |
| 287 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 288 BeginOperationScoper scope; | |
| 289 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 290 if (!operation) { | |
| 291 DidFinish(handle, callback, error); | |
| 292 return handle.id; | |
| 293 } | |
| 294 PrepareForWrite(handle.id, url); | |
| 295 operation->Truncate( | |
| 296 url, length, | |
| 297 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 298 handle, callback)); | |
| 299 return handle.id; | |
| 300 } | |
| 301 | |
| 302 void FileSystemOperationRunner::Cancel( | |
| 303 OperationID id, | |
| 304 const StatusCallback& callback) { | |
| 305 if (ContainsKey(finished_operations_, id)) { | |
| 306 DCHECK(!ContainsKey(stray_cancel_callbacks_, id)); | |
| 307 stray_cancel_callbacks_[id] = callback; | |
| 308 return; | |
| 309 } | |
| 310 FileSystemOperation* operation = operations_.Lookup(id); | |
| 311 if (!operation) { | |
| 312 // There is no operation with |id|. | |
| 313 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION); | |
| 314 return; | |
| 315 } | |
| 316 operation->Cancel(callback); | |
| 317 } | |
| 318 | |
| 319 OperationID FileSystemOperationRunner::TouchFile( | |
| 320 const FileSystemURL& url, | |
| 321 const base::Time& last_access_time, | |
| 322 const base::Time& last_modified_time, | |
| 323 const StatusCallback& callback) { | |
| 324 base::File::Error error = base::File::FILE_OK; | |
| 325 FileSystemOperation* operation = | |
| 326 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 327 BeginOperationScoper scope; | |
| 328 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 329 if (!operation) { | |
| 330 DidFinish(handle, callback, error); | |
| 331 return handle.id; | |
| 332 } | |
| 333 PrepareForWrite(handle.id, url); | |
| 334 operation->TouchFile( | |
| 335 url, last_access_time, last_modified_time, | |
| 336 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 337 handle, callback)); | |
| 338 return handle.id; | |
| 339 } | |
| 340 | |
| 341 OperationID FileSystemOperationRunner::OpenFile( | |
| 342 const FileSystemURL& url, | |
| 343 int file_flags, | |
| 344 const OpenFileCallback& callback) { | |
| 345 base::File::Error error = base::File::FILE_OK; | |
| 346 FileSystemOperation* operation = | |
| 347 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 348 BeginOperationScoper scope; | |
| 349 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 350 if (!operation) { | |
| 351 DidOpenFile(handle, callback, base::File(error), base::Closure()); | |
| 352 return handle.id; | |
| 353 } | |
| 354 if (file_flags & | |
| 355 (base::File::FLAG_CREATE | base::File::FLAG_OPEN_ALWAYS | | |
| 356 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_TRUNCATED | | |
| 357 base::File::FLAG_WRITE | base::File::FLAG_EXCLUSIVE_WRITE | | |
| 358 base::File::FLAG_DELETE_ON_CLOSE | | |
| 359 base::File::FLAG_WRITE_ATTRIBUTES)) { | |
| 360 PrepareForWrite(handle.id, url); | |
| 361 } else { | |
| 362 PrepareForRead(handle.id, url); | |
| 363 } | |
| 364 operation->OpenFile( | |
| 365 url, file_flags, | |
| 366 base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(), | |
| 367 handle, callback)); | |
| 368 return handle.id; | |
| 369 } | |
| 370 | |
| 371 OperationID FileSystemOperationRunner::CreateSnapshotFile( | |
| 372 const FileSystemURL& url, | |
| 373 const SnapshotFileCallback& callback) { | |
| 374 base::File::Error error = base::File::FILE_OK; | |
| 375 FileSystemOperation* operation = | |
| 376 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 377 BeginOperationScoper scope; | |
| 378 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 379 if (!operation) { | |
| 380 DidCreateSnapshot(handle, callback, error, base::File::Info(), | |
| 381 base::FilePath(), NULL); | |
| 382 return handle.id; | |
| 383 } | |
| 384 PrepareForRead(handle.id, url); | |
| 385 operation->CreateSnapshotFile( | |
| 386 url, | |
| 387 base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(), | |
| 388 handle, callback)); | |
| 389 return handle.id; | |
| 390 } | |
| 391 | |
| 392 OperationID FileSystemOperationRunner::CopyInForeignFile( | |
| 393 const base::FilePath& src_local_disk_path, | |
| 394 const FileSystemURL& dest_url, | |
| 395 const StatusCallback& callback) { | |
| 396 base::File::Error error = base::File::FILE_OK; | |
| 397 FileSystemOperation* operation = | |
| 398 file_system_context_->CreateFileSystemOperation(dest_url, &error); | |
| 399 BeginOperationScoper scope; | |
| 400 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 401 if (!operation) { | |
| 402 DidFinish(handle, callback, error); | |
| 403 return handle.id; | |
| 404 } | |
| 405 operation->CopyInForeignFile( | |
| 406 src_local_disk_path, dest_url, | |
| 407 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 408 handle, callback)); | |
| 409 return handle.id; | |
| 410 } | |
| 411 | |
| 412 OperationID FileSystemOperationRunner::RemoveFile( | |
| 413 const FileSystemURL& url, | |
| 414 const StatusCallback& callback) { | |
| 415 base::File::Error error = base::File::FILE_OK; | |
| 416 FileSystemOperation* operation = | |
| 417 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 418 BeginOperationScoper scope; | |
| 419 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 420 if (!operation) { | |
| 421 DidFinish(handle, callback, error); | |
| 422 return handle.id; | |
| 423 } | |
| 424 operation->RemoveFile( | |
| 425 url, | |
| 426 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 427 handle, callback)); | |
| 428 return handle.id; | |
| 429 } | |
| 430 | |
| 431 OperationID FileSystemOperationRunner::RemoveDirectory( | |
| 432 const FileSystemURL& url, | |
| 433 const StatusCallback& callback) { | |
| 434 base::File::Error error = base::File::FILE_OK; | |
| 435 FileSystemOperation* operation = | |
| 436 file_system_context_->CreateFileSystemOperation(url, &error); | |
| 437 BeginOperationScoper scope; | |
| 438 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 439 if (!operation) { | |
| 440 DidFinish(handle, callback, error); | |
| 441 return handle.id; | |
| 442 } | |
| 443 operation->RemoveDirectory( | |
| 444 url, | |
| 445 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 446 handle, callback)); | |
| 447 return handle.id; | |
| 448 } | |
| 449 | |
| 450 OperationID FileSystemOperationRunner::CopyFileLocal( | |
| 451 const FileSystemURL& src_url, | |
| 452 const FileSystemURL& dest_url, | |
| 453 CopyOrMoveOption option, | |
| 454 const CopyFileProgressCallback& progress_callback, | |
| 455 const StatusCallback& callback) { | |
| 456 base::File::Error error = base::File::FILE_OK; | |
| 457 FileSystemOperation* operation = | |
| 458 file_system_context_->CreateFileSystemOperation(src_url, &error); | |
| 459 BeginOperationScoper scope; | |
| 460 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 461 if (!operation) { | |
| 462 DidFinish(handle, callback, error); | |
| 463 return handle.id; | |
| 464 } | |
| 465 operation->CopyFileLocal( | |
| 466 src_url, dest_url, option, progress_callback, | |
| 467 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 468 handle, callback)); | |
| 469 return handle.id; | |
| 470 } | |
| 471 | |
| 472 OperationID FileSystemOperationRunner::MoveFileLocal( | |
| 473 const FileSystemURL& src_url, | |
| 474 const FileSystemURL& dest_url, | |
| 475 CopyOrMoveOption option, | |
| 476 const StatusCallback& callback) { | |
| 477 base::File::Error error = base::File::FILE_OK; | |
| 478 FileSystemOperation* operation = | |
| 479 file_system_context_->CreateFileSystemOperation(src_url, &error); | |
| 480 BeginOperationScoper scope; | |
| 481 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
| 482 if (!operation) { | |
| 483 DidFinish(handle, callback, error); | |
| 484 return handle.id; | |
| 485 } | |
| 486 operation->MoveFileLocal( | |
| 487 src_url, dest_url, option, | |
| 488 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
| 489 handle, callback)); | |
| 490 return handle.id; | |
| 491 } | |
| 492 | |
| 493 base::File::Error FileSystemOperationRunner::SyncGetPlatformPath( | |
| 494 const FileSystemURL& url, | |
| 495 base::FilePath* platform_path) { | |
| 496 base::File::Error error = base::File::FILE_OK; | |
| 497 scoped_ptr<FileSystemOperation> operation( | |
| 498 file_system_context_->CreateFileSystemOperation(url, &error)); | |
| 499 if (!operation.get()) | |
| 500 return error; | |
| 501 return operation->SyncGetPlatformPath(url, platform_path); | |
| 502 } | |
| 503 | |
| 504 FileSystemOperationRunner::FileSystemOperationRunner( | |
| 505 FileSystemContext* file_system_context) | |
| 506 : file_system_context_(file_system_context) {} | |
| 507 | |
| 508 void FileSystemOperationRunner::DidFinish( | |
| 509 const OperationHandle& handle, | |
| 510 const StatusCallback& callback, | |
| 511 base::File::Error rv) { | |
| 512 if (handle.scope) { | |
| 513 finished_operations_.insert(handle.id); | |
| 514 base::MessageLoopProxy::current()->PostTask( | |
| 515 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish, | |
| 516 AsWeakPtr(), handle, callback, rv)); | |
| 517 return; | |
| 518 } | |
| 519 callback.Run(rv); | |
| 520 FinishOperation(handle.id); | |
| 521 } | |
| 522 | |
| 523 void FileSystemOperationRunner::DidGetMetadata( | |
| 524 const OperationHandle& handle, | |
| 525 const GetMetadataCallback& callback, | |
| 526 base::File::Error rv, | |
| 527 const base::File::Info& file_info) { | |
| 528 if (handle.scope) { | |
| 529 finished_operations_.insert(handle.id); | |
| 530 base::MessageLoopProxy::current()->PostTask( | |
| 531 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata, | |
| 532 AsWeakPtr(), handle, callback, rv, file_info)); | |
| 533 return; | |
| 534 } | |
| 535 callback.Run(rv, file_info); | |
| 536 FinishOperation(handle.id); | |
| 537 } | |
| 538 | |
| 539 void FileSystemOperationRunner::DidReadDirectory( | |
| 540 const OperationHandle& handle, | |
| 541 const ReadDirectoryCallback& callback, | |
| 542 base::File::Error rv, | |
| 543 const std::vector<DirectoryEntry>& entries, | |
| 544 bool has_more) { | |
| 545 if (handle.scope) { | |
| 546 finished_operations_.insert(handle.id); | |
| 547 base::MessageLoopProxy::current()->PostTask( | |
| 548 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory, | |
| 549 AsWeakPtr(), handle, callback, rv, | |
| 550 entries, has_more)); | |
| 551 return; | |
| 552 } | |
| 553 callback.Run(rv, entries, has_more); | |
| 554 if (rv != base::File::FILE_OK || !has_more) | |
| 555 FinishOperation(handle.id); | |
| 556 } | |
| 557 | |
| 558 void FileSystemOperationRunner::DidWrite( | |
| 559 const OperationHandle& handle, | |
| 560 const WriteCallback& callback, | |
| 561 base::File::Error rv, | |
| 562 int64 bytes, | |
| 563 bool complete) { | |
| 564 if (handle.scope) { | |
| 565 finished_operations_.insert(handle.id); | |
| 566 base::MessageLoopProxy::current()->PostTask( | |
| 567 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), | |
| 568 handle, callback, rv, bytes, complete)); | |
| 569 return; | |
| 570 } | |
| 571 callback.Run(rv, bytes, complete); | |
| 572 if (rv != base::File::FILE_OK || complete) | |
| 573 FinishOperation(handle.id); | |
| 574 } | |
| 575 | |
| 576 void FileSystemOperationRunner::DidOpenFile( | |
| 577 const OperationHandle& handle, | |
| 578 const OpenFileCallback& callback, | |
| 579 base::File file, | |
| 580 const base::Closure& on_close_callback) { | |
| 581 if (handle.scope) { | |
| 582 finished_operations_.insert(handle.id); | |
| 583 base::MessageLoopProxy::current()->PostTask( | |
| 584 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile, | |
| 585 AsWeakPtr(), handle, callback, Passed(&file), | |
| 586 on_close_callback)); | |
| 587 return; | |
| 588 } | |
| 589 callback.Run(file.Pass(), on_close_callback); | |
| 590 FinishOperation(handle.id); | |
| 591 } | |
| 592 | |
| 593 void FileSystemOperationRunner::DidCreateSnapshot( | |
| 594 const OperationHandle& handle, | |
| 595 const SnapshotFileCallback& callback, | |
| 596 base::File::Error rv, | |
| 597 const base::File::Info& file_info, | |
| 598 const base::FilePath& platform_path, | |
| 599 const scoped_refptr<storage::ShareableFileReference>& file_ref) { | |
| 600 if (handle.scope) { | |
| 601 finished_operations_.insert(handle.id); | |
| 602 base::MessageLoopProxy::current()->PostTask( | |
| 603 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, | |
| 604 AsWeakPtr(), handle, callback, rv, file_info, | |
| 605 platform_path, file_ref)); | |
| 606 return; | |
| 607 } | |
| 608 callback.Run(rv, file_info, platform_path, file_ref); | |
| 609 FinishOperation(handle.id); | |
| 610 } | |
| 611 | |
| 612 void FileSystemOperationRunner::OnCopyProgress( | |
| 613 const OperationHandle& handle, | |
| 614 const CopyProgressCallback& callback, | |
| 615 FileSystemOperation::CopyProgressType type, | |
| 616 const FileSystemURL& source_url, | |
| 617 const FileSystemURL& dest_url, | |
| 618 int64 size) { | |
| 619 if (handle.scope) { | |
| 620 base::MessageLoopProxy::current()->PostTask( | |
| 621 FROM_HERE, base::Bind( | |
| 622 &FileSystemOperationRunner::OnCopyProgress, | |
| 623 AsWeakPtr(), handle, callback, type, source_url, dest_url, size)); | |
| 624 return; | |
| 625 } | |
| 626 callback.Run(type, source_url, dest_url, size); | |
| 627 } | |
| 628 | |
| 629 void FileSystemOperationRunner::PrepareForWrite(OperationID id, | |
| 630 const FileSystemURL& url) { | |
| 631 if (file_system_context_->GetUpdateObservers(url.type())) { | |
| 632 file_system_context_->GetUpdateObservers(url.type())->Notify( | |
| 633 &FileUpdateObserver::OnStartUpdate, MakeTuple(url)); | |
| 634 } | |
| 635 write_target_urls_[id].insert(url); | |
| 636 } | |
| 637 | |
| 638 void FileSystemOperationRunner::PrepareForRead(OperationID id, | |
| 639 const FileSystemURL& url) { | |
| 640 if (file_system_context_->GetAccessObservers(url.type())) { | |
| 641 file_system_context_->GetAccessObservers(url.type())->Notify( | |
| 642 &FileAccessObserver::OnAccess, MakeTuple(url)); | |
| 643 } | |
| 644 } | |
| 645 | |
| 646 FileSystemOperationRunner::OperationHandle | |
| 647 FileSystemOperationRunner::BeginOperation( | |
| 648 FileSystemOperation* operation, | |
| 649 base::WeakPtr<BeginOperationScoper> scope) { | |
| 650 OperationHandle handle; | |
| 651 handle.id = operations_.Add(operation); | |
| 652 handle.scope = scope; | |
| 653 return handle; | |
| 654 } | |
| 655 | |
| 656 void FileSystemOperationRunner::FinishOperation(OperationID id) { | |
| 657 OperationToURLSet::iterator found = write_target_urls_.find(id); | |
| 658 if (found != write_target_urls_.end()) { | |
| 659 const FileSystemURLSet& urls = found->second; | |
| 660 for (FileSystemURLSet::const_iterator iter = urls.begin(); | |
| 661 iter != urls.end(); ++iter) { | |
| 662 if (file_system_context_->GetUpdateObservers(iter->type())) { | |
| 663 file_system_context_->GetUpdateObservers(iter->type())->Notify( | |
| 664 &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter)); | |
| 665 } | |
| 666 } | |
| 667 write_target_urls_.erase(found); | |
| 668 } | |
| 669 | |
| 670 // IDMap::Lookup fails if the operation is NULL, so we don't check | |
| 671 // operations_.Lookup(id) here. | |
| 672 | |
| 673 operations_.Remove(id); | |
| 674 finished_operations_.erase(id); | |
| 675 | |
| 676 // Dispatch stray cancel callback if exists. | |
| 677 std::map<OperationID, StatusCallback>::iterator found_cancel = | |
| 678 stray_cancel_callbacks_.find(id); | |
| 679 if (found_cancel != stray_cancel_callbacks_.end()) { | |
| 680 // This cancel has been requested after the operation has finished, | |
| 681 // so report that we failed to stop it. | |
| 682 found_cancel->second.Run(base::File::FILE_ERROR_INVALID_OPERATION); | |
| 683 stray_cancel_callbacks_.erase(found_cancel); | |
| 684 } | |
| 685 } | |
| 686 | |
| 687 } // namespace storage | |
| OLD | NEW |