| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "webkit/fileapi/file_system_operation.h" | 5 #include "webkit/fileapi/file_system_operation.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/sequenced_task_runner.h" | 8 #include "base/sequenced_task_runner.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); | 283 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); |
| 284 if (result != base::PLATFORM_FILE_OK) { | 284 if (result != base::PLATFORM_FILE_OK) { |
| 285 callback.Run(result, 0, false); | 285 callback.Run(result, 0, false); |
| 286 delete this; | 286 delete this; |
| 287 return; | 287 return; |
| 288 } | 288 } |
| 289 DCHECK(blob_url.is_valid()); | 289 DCHECK(blob_url.is_valid()); |
| 290 file_writer_delegate_.reset(new FileWriterDelegate( | 290 file_writer_delegate_.reset(new FileWriterDelegate( |
| 291 this, src_path_, offset)); | 291 this, src_path_, offset)); |
| 292 set_write_callback(callback); | 292 set_write_callback(callback); |
| 293 blob_request_.reset( | 293 scoped_ptr<net::URLRequest> blob_request( |
| 294 new net::URLRequest(blob_url, file_writer_delegate_.get())); | 294 new net::URLRequest(blob_url, file_writer_delegate_.get())); |
| 295 blob_request_->set_context(url_request_context); | 295 blob_request->set_context(url_request_context); |
| 296 | 296 |
| 297 GetUsageAndQuotaThenRunTask( | 297 GetUsageAndQuotaThenRunTask( |
| 298 src_path_.origin(), src_path_.type(), | 298 src_path_.origin(), src_path_.type(), |
| 299 base::Bind(&FileSystemOperation::DoWrite, base::Unretained(this)), | 299 base::Bind(&FileSystemOperation::DoWrite, weak_factory_.GetWeakPtr(), |
| 300 base::Passed(&blob_request)), |
| 300 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true)); | 301 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, 0, true)); |
| 301 } | 302 } |
| 302 | 303 |
| 303 void FileSystemOperation::Truncate(const GURL& path_url, int64 length, | 304 void FileSystemOperation::Truncate(const GURL& path_url, int64 length, |
| 304 const StatusCallback& callback) { | 305 const StatusCallback& callback) { |
| 305 DCHECK(SetPendingOperationType(kOperationTruncate)); | 306 DCHECK(SetPendingOperationType(kOperationTruncate)); |
| 306 | 307 |
| 307 base::PlatformFileError result = SetUpFileSystemPath( | 308 base::PlatformFileError result = SetUpFileSystemPath( |
| 308 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); | 309 path_url, &src_path_, &src_util_, PATH_FOR_WRITE); |
| 309 if (result != base::PLATFORM_FILE_OK) { | 310 if (result != base::PLATFORM_FILE_OK) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, | 383 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, |
| 383 base::kInvalidPlatformFileValue, | 384 base::kInvalidPlatformFileValue, |
| 384 base::kNullProcessHandle)); | 385 base::kNullProcessHandle)); |
| 385 } | 386 } |
| 386 | 387 |
| 387 // We can only get here on a write or truncate that's not yet completed. | 388 // We can only get here on a write or truncate that's not yet completed. |
| 388 // We don't support cancelling any other operation at this time. | 389 // We don't support cancelling any other operation at this time. |
| 389 void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) { | 390 void FileSystemOperation::Cancel(const StatusCallback& cancel_callback) { |
| 390 if (file_writer_delegate_.get()) { | 391 if (file_writer_delegate_.get()) { |
| 391 DCHECK_EQ(kOperationWrite, pending_operation_); | 392 DCHECK_EQ(kOperationWrite, pending_operation_); |
| 393 |
| 392 // Writes are done without proxying through FileUtilProxy after the initial | 394 // Writes are done without proxying through FileUtilProxy after the initial |
| 393 // opening of the PlatformFile. All state changes are done on this thread, | 395 // opening of the PlatformFile. All state changes are done on this thread, |
| 394 // so we're guaranteed to be able to shut down atomically. We do need to | 396 // so we're guaranteed to be able to shut down atomically. |
| 395 // check that the file has been opened [which means the blob_request_ has | 397 const bool delete_now = file_writer_delegate_->Cancel(); |
| 396 // been created], so we know how much we need to do. | |
| 397 if (blob_request_.get()) | |
| 398 // This halts any calls to file_writer_delegate_ from blob_request_. | |
| 399 blob_request_->Cancel(); | |
| 400 | 398 |
| 401 if (!write_callback_.is_null()) { | 399 if (!write_callback_.is_null()) { |
| 402 // Notify the failure status to the ongoing operation's callback. | 400 // Notify the failure status to the ongoing operation's callback. |
| 403 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false); | 401 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false); |
| 404 // Do not delete this FileSystemOperation object yet. As a result of | |
| 405 // abort, this->DidWrite is called later and there we delete this object. | |
| 406 } | 402 } |
| 407 cancel_callback.Run(base::PLATFORM_FILE_OK); | 403 cancel_callback.Run(base::PLATFORM_FILE_OK); |
| 408 write_callback_.Reset(); | 404 write_callback_.Reset(); |
| 405 |
| 406 if (delete_now) { |
| 407 delete this; |
| 408 return; |
| 409 } |
| 409 } else { | 410 } else { |
| 410 DCHECK_EQ(kOperationTruncate, pending_operation_); | 411 DCHECK_EQ(kOperationTruncate, pending_operation_); |
| 411 // We're cancelling a truncate operation, but we can't actually stop it | 412 // We're cancelling a truncate operation, but we can't actually stop it |
| 412 // since it's been proxied to another thread. We need to save the | 413 // since it's been proxied to another thread. We need to save the |
| 413 // cancel_callback so that when the truncate returns, it can see that it's | 414 // cancel_callback so that when the truncate returns, it can see that it's |
| 414 // been cancelled, report it, and report that the cancel has succeeded. | 415 // been cancelled, report it, and report that the cancel has succeeded. |
| 415 DCHECK(cancel_callback_.is_null()); | 416 DCHECK(cancel_callback_.is_null()); |
| 416 cancel_callback_ = cancel_callback; | 417 cancel_callback_ = cancel_callback; |
| 417 } | 418 } |
| 418 } | 419 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 443 const SnapshotFileCallback& callback) { | 444 const SnapshotFileCallback& callback) { |
| 444 GetMetadata(path_url, base::Bind(&GetMetadataForSnapshot, callback)); | 445 GetMetadata(path_url, base::Bind(&GetMetadataForSnapshot, callback)); |
| 445 } | 446 } |
| 446 | 447 |
| 447 FileSystemOperation::FileSystemOperation( | 448 FileSystemOperation::FileSystemOperation( |
| 448 FileSystemContext* file_system_context) | 449 FileSystemContext* file_system_context) |
| 449 : operation_context_(file_system_context), | 450 : operation_context_(file_system_context), |
| 450 src_util_(NULL), | 451 src_util_(NULL), |
| 451 dest_util_(NULL), | 452 dest_util_(NULL), |
| 452 peer_handle_(base::kNullProcessHandle), | 453 peer_handle_(base::kNullProcessHandle), |
| 453 pending_operation_(kOperationNone) { | 454 pending_operation_(kOperationNone), |
| 455 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 454 } | 456 } |
| 455 | 457 |
| 456 void FileSystemOperation::GetUsageAndQuotaThenRunTask( | 458 void FileSystemOperation::GetUsageAndQuotaThenRunTask( |
| 457 const GURL& origin, FileSystemType type, | 459 const GURL& origin, FileSystemType type, |
| 458 const base::Closure& task, | 460 const base::Closure& task, |
| 459 const base::Closure& error_callback) { | 461 const base::Closure& error_callback) { |
| 460 quota::QuotaManagerProxy* quota_manager_proxy = | 462 quota::QuotaManagerProxy* quota_manager_proxy = |
| 461 file_system_context()->quota_manager_proxy(); | 463 file_system_context()->quota_manager_proxy(); |
| 462 if (!quota_manager_proxy || | 464 if (!quota_manager_proxy || |
| 463 !file_system_context()->GetQuotaUtil(type)) { | 465 !file_system_context()->GetQuotaUtil(type)) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 | 535 |
| 534 void FileSystemOperation::DoMove(const StatusCallback& callback) { | 536 void FileSystemOperation::DoMove(const StatusCallback& callback) { |
| 535 FileSystemFileUtilProxy::Move( | 537 FileSystemFileUtilProxy::Move( |
| 536 &operation_context_, | 538 &operation_context_, |
| 537 src_util_, dest_util_, | 539 src_util_, dest_util_, |
| 538 src_path_, dest_path_, | 540 src_path_, dest_path_, |
| 539 base::Bind(&FileSystemOperation::DidFinishFileOperation, | 541 base::Bind(&FileSystemOperation::DidFinishFileOperation, |
| 540 base::Owned(this), callback)); | 542 base::Owned(this), callback)); |
| 541 } | 543 } |
| 542 | 544 |
| 543 void FileSystemOperation::DoWrite() { | 545 void FileSystemOperation::DoWrite(scoped_ptr<net::URLRequest> blob_request) { |
| 544 int file_flags = base::PLATFORM_FILE_OPEN | | 546 int file_flags = base::PLATFORM_FILE_OPEN | |
| 545 base::PLATFORM_FILE_WRITE | | 547 base::PLATFORM_FILE_WRITE | |
| 546 base::PLATFORM_FILE_ASYNC; | 548 base::PLATFORM_FILE_ASYNC; |
| 547 | 549 |
| 550 // We may get deleted on the way so allocate a new operation context |
| 551 // to keep it alive. |
| 552 FileSystemOperationContext* write_context = new FileSystemOperationContext( |
| 553 operation_context_); |
| 548 FileSystemFileUtilProxy::CreateOrOpen( | 554 FileSystemFileUtilProxy::CreateOrOpen( |
| 549 &operation_context_, src_util_, src_path_, file_flags, | 555 write_context, src_util_, src_path_, file_flags, |
| 550 base::Bind(&FileSystemOperation::OnFileOpenedForWrite, | 556 base::Bind(&FileSystemOperation::OnFileOpenedForWrite, |
| 551 base::Unretained(this))); | 557 weak_factory_.GetWeakPtr(), |
| 558 base::Passed(&blob_request), |
| 559 base::Owned(write_context))); |
| 552 } | 560 } |
| 553 | 561 |
| 554 void FileSystemOperation::DoTruncate(const StatusCallback& callback, | 562 void FileSystemOperation::DoTruncate(const StatusCallback& callback, |
| 555 int64 length) { | 563 int64 length) { |
| 556 FileSystemFileUtilProxy::Truncate( | 564 FileSystemFileUtilProxy::Truncate( |
| 557 &operation_context_, src_util_, src_path_, length, | 565 &operation_context_, src_util_, src_path_, length, |
| 558 base::Bind(&FileSystemOperation::DidFinishFileOperation, | 566 base::Bind(&FileSystemOperation::DidFinishFileOperation, |
| 559 base::Owned(this), callback)); | 567 base::Owned(this), callback)); |
| 560 } | 568 } |
| 561 | 569 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 const OpenFileCallback& callback, | 665 const OpenFileCallback& callback, |
| 658 base::PlatformFileError rv, | 666 base::PlatformFileError rv, |
| 659 base::PassPlatformFile file, | 667 base::PassPlatformFile file, |
| 660 bool unused) { | 668 bool unused) { |
| 661 if (rv == base::PLATFORM_FILE_OK) | 669 if (rv == base::PLATFORM_FILE_OK) |
| 662 CHECK_NE(base::kNullProcessHandle, peer_handle_); | 670 CHECK_NE(base::kNullProcessHandle, peer_handle_); |
| 663 callback.Run(rv, file.ReleaseValue(), peer_handle_); | 671 callback.Run(rv, file.ReleaseValue(), peer_handle_); |
| 664 } | 672 } |
| 665 | 673 |
| 666 void FileSystemOperation::OnFileOpenedForWrite( | 674 void FileSystemOperation::OnFileOpenedForWrite( |
| 675 scoped_ptr<net::URLRequest> blob_request, |
| 676 FileSystemOperationContext* unused, |
| 667 base::PlatformFileError rv, | 677 base::PlatformFileError rv, |
| 668 base::PassPlatformFile file, | 678 base::PassPlatformFile file, |
| 669 bool created) { | 679 bool created) { |
| 670 if (rv != base::PLATFORM_FILE_OK) { | 680 if (rv != base::PLATFORM_FILE_OK) { |
| 671 if (!write_callback_.is_null()) | 681 if (!write_callback_.is_null()) |
| 672 write_callback_.Run(rv, 0, false); | 682 write_callback_.Run(rv, 0, false); |
| 673 delete this; | 683 delete this; |
| 674 return; | 684 return; |
| 675 } | 685 } |
| 676 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); | 686 file_writer_delegate_->Start(file.ReleaseValue(), blob_request.Pass()); |
| 677 } | 687 } |
| 678 | 688 |
| 679 base::PlatformFileError FileSystemOperation::SetUpFileSystemPath( | 689 base::PlatformFileError FileSystemOperation::SetUpFileSystemPath( |
| 680 const GURL& path_url, | 690 const GURL& path_url, |
| 681 FileSystemPath* file_system_path, | 691 FileSystemPath* file_system_path, |
| 682 FileSystemFileUtil** file_util, | 692 FileSystemFileUtil** file_util, |
| 683 SetUpPathMode mode) { | 693 SetUpPathMode mode) { |
| 684 DCHECK(file_system_path); | 694 DCHECK(file_system_path); |
| 685 GURL origin_url; | 695 GURL origin_url; |
| 686 FileSystemType type; | 696 FileSystemType type; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 } | 746 } |
| 737 | 747 |
| 738 bool FileSystemOperation::SetPendingOperationType(OperationType type) { | 748 bool FileSystemOperation::SetPendingOperationType(OperationType type) { |
| 739 if (pending_operation_ != kOperationNone) | 749 if (pending_operation_ != kOperationNone) |
| 740 return false; | 750 return false; |
| 741 pending_operation_ = type; | 751 pending_operation_ = type; |
| 742 return true; | 752 return true; |
| 743 } | 753 } |
| 744 | 754 |
| 745 } // namespace fileapi | 755 } // namespace fileapi |
| OLD | NEW |