| 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/time.h" | 8 #include "base/time.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "net/base/escape.h" | 10 #include "net/base/escape.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 } | 51 } |
| 52 | 52 |
| 53 FileSystemOperation::ScopedQuotaUtilHelper::~ScopedQuotaUtilHelper() { | 53 FileSystemOperation::ScopedQuotaUtilHelper::~ScopedQuotaUtilHelper() { |
| 54 if (quota_util_) { | 54 if (quota_util_) { |
| 55 DCHECK(quota_util_->proxy()); | 55 DCHECK(quota_util_->proxy()); |
| 56 quota_util_->proxy()->EndUpdateOrigin(origin_url_, type_); | 56 quota_util_->proxy()->EndUpdateOrigin(origin_url_, type_); |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 | 59 |
| 60 FileSystemOperation::FileSystemOperation( | 60 FileSystemOperation::FileSystemOperation( |
| 61 FileSystemCallbackDispatcher* dispatcher, | 61 scoped_ptr<FileSystemCallbackDispatcher> dispatcher, |
| 62 scoped_refptr<base::MessageLoopProxy> proxy, | 62 scoped_refptr<base::MessageLoopProxy> proxy, |
| 63 FileSystemContext* file_system_context) | 63 FileSystemContext* file_system_context) |
| 64 : proxy_(proxy), | 64 : proxy_(proxy), |
| 65 dispatcher_(dispatcher), | 65 dispatcher_(dispatcher.Pass()), |
| 66 operation_context_(file_system_context, NULL), | 66 operation_context_(file_system_context, NULL), |
| 67 peer_handle_(base::kNullProcessHandle) { | 67 peer_handle_(base::kNullProcessHandle) { |
| 68 #ifndef NDEBUG | 68 #ifndef NDEBUG |
| 69 pending_operation_ = kOperationNone; | 69 pending_operation_ = kOperationNone; |
| 70 #endif | 70 #endif |
| 71 } | 71 } |
| 72 | 72 |
| 73 FileSystemOperation::~FileSystemOperation() { | 73 FileSystemOperation::~FileSystemOperation() { |
| 74 if (file_writer_delegate_.get()) { | 74 if (file_writer_delegate_.get()) { |
| 75 FileSystemOperationContext* c = | 75 FileSystemOperationContext* c = |
| 76 new FileSystemOperationContext(operation_context_); | 76 new FileSystemOperationContext(operation_context_); |
| 77 base::FileUtilProxy::RelayClose( | 77 base::FileUtilProxy::RelayClose( |
| 78 proxy_, | 78 proxy_, |
| 79 base::Bind(&FileSystemFileUtil::Close, | 79 base::Bind(&FileSystemFileUtil::Close, |
| 80 base::Unretained(c->src_file_util()), | 80 base::Unretained(c->src_file_util()), |
| 81 base::Owned(c)), | 81 base::Owned(c)), |
| 82 file_writer_delegate_->file(), | 82 file_writer_delegate_->file(), |
| 83 base::FileUtilProxy::StatusCallback()); | 83 base::FileUtilProxy::StatusCallback()); |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 | 86 |
| 87 void FileSystemOperation::OpenFileSystem( | |
| 88 const GURL& origin_url, fileapi::FileSystemType type, bool create) { | |
| 89 #ifndef NDEBUG | |
| 90 DCHECK(kOperationNone == pending_operation_); | |
| 91 pending_operation_ = static_cast<FileSystemOperation::OperationType>( | |
| 92 kOperationOpenFileSystem); | |
| 93 #endif | |
| 94 | |
| 95 DCHECK(file_system_context()); | |
| 96 operation_context_.set_src_origin_url(origin_url); | |
| 97 operation_context_.set_src_type(type); | |
| 98 // TODO(ericu): We don't really need to make this call if !create. | |
| 99 // Also, in the future we won't need it either way, as long as we do all | |
| 100 // permission+quota checks beforehand. We only need it now because we have to | |
| 101 // create an unpredictable directory name. Without that, we could lazily | |
| 102 // create the root later on the first filesystem write operation, and just | |
| 103 // return GetFileSystemRootURI() here. | |
| 104 FileSystemMountPointProvider* mount_point_provider = | |
| 105 file_system_context()->GetMountPointProvider(type); | |
| 106 if (!mount_point_provider) { | |
| 107 DidGetRootPath(false, FilePath(), std::string()); | |
| 108 delete this; | |
| 109 return; | |
| 110 } | |
| 111 mount_point_provider->ValidateFileSystemRootAndGetURL( | |
| 112 origin_url, type, create, | |
| 113 base::Bind(&FileSystemOperation::DidGetRootPath, | |
| 114 base::Owned(this))); | |
| 115 } | |
| 116 | |
| 117 void FileSystemOperation::CreateFile(const GURL& path, | 87 void FileSystemOperation::CreateFile(const GURL& path, |
| 118 bool exclusive) { | 88 bool exclusive) { |
| 119 #ifndef NDEBUG | 89 #ifndef NDEBUG |
| 120 DCHECK(kOperationNone == pending_operation_); | 90 DCHECK(kOperationNone == pending_operation_); |
| 121 pending_operation_ = kOperationCreateFile; | 91 pending_operation_ = kOperationCreateFile; |
| 122 #endif | 92 #endif |
| 123 if (!SetupSrcContextForWrite(path, true)) { | 93 if (!SetupSrcContextForWrite(path, true)) { |
| 124 delete this; | 94 delete this; |
| 125 return; | 95 return; |
| 126 } | 96 } |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 base::Bind(&FileSystemFileUtil::CreateOrOpen, | 480 base::Bind(&FileSystemFileUtil::CreateOrOpen, |
| 511 base::Unretained(operation_context_.src_file_util()), | 481 base::Unretained(operation_context_.src_file_util()), |
| 512 &operation_context_, | 482 &operation_context_, |
| 513 src_virtual_path_, file_flags), | 483 src_virtual_path_, file_flags), |
| 514 base::Bind(&FileSystemFileUtil::Close, | 484 base::Bind(&FileSystemFileUtil::Close, |
| 515 base::Unretained(operation_context_.src_file_util()), | 485 base::Unretained(operation_context_.src_file_util()), |
| 516 &operation_context_), | 486 &operation_context_), |
| 517 base::Bind(&FileSystemOperation::DidOpenFile, base::Owned(this))); | 487 base::Bind(&FileSystemOperation::DidOpenFile, base::Owned(this))); |
| 518 } | 488 } |
| 519 | 489 |
| 520 void FileSystemOperation::SyncGetPlatformPath(const GURL& path, | |
| 521 FilePath* platform_path) { | |
| 522 #ifndef NDEBUG | |
| 523 DCHECK(kOperationNone == pending_operation_); | |
| 524 pending_operation_ = kOperationGetLocalPath; | |
| 525 #endif | |
| 526 if (!SetupSrcContextForRead(path)) { | |
| 527 delete this; | |
| 528 return; | |
| 529 } | |
| 530 | |
| 531 operation_context_.src_file_util()->GetLocalFilePath( | |
| 532 &operation_context_, src_virtual_path_, platform_path); | |
| 533 | |
| 534 delete this; | |
| 535 } | |
| 536 | |
| 537 // We can only get here on a write or truncate that's not yet completed. | 490 // We can only get here on a write or truncate that's not yet completed. |
| 538 // We don't support cancelling any other operation at this time. | 491 // We don't support cancelling any other operation at this time. |
| 539 void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation_ptr) { | 492 void FileSystemOperation::Cancel( |
| 540 scoped_ptr<FileSystemOperation> cancel_operation(cancel_operation_ptr); | 493 scoped_ptr<FileSystemCallbackDispatcher> cancel_dispatcher) { |
| 541 if (file_writer_delegate_.get()) { | 494 if (file_writer_delegate_.get()) { |
| 542 #ifndef NDEBUG | 495 #ifndef NDEBUG |
| 543 DCHECK(kOperationWrite == pending_operation_); | 496 DCHECK(kOperationWrite == pending_operation_); |
| 544 #endif | 497 #endif |
| 545 // Writes are done without proxying through FileUtilProxy after the initial | 498 // Writes are done without proxying through FileUtilProxy after the initial |
| 546 // opening of the PlatformFile. All state changes are done on this thread, | 499 // opening of the PlatformFile. All state changes are done on this thread, |
| 547 // so we're guaranteed to be able to shut down atomically. We do need to | 500 // so we're guaranteed to be able to shut down atomically. We do need to |
| 548 // check that the file has been opened [which means the blob_request_ has | 501 // check that the file has been opened [which means the blob_request_ has |
| 549 // been created], so we know how much we need to do. | 502 // been created], so we know how much we need to do. |
| 550 if (blob_request_.get()) | 503 if (blob_request_.get()) |
| 551 // This halts any calls to file_writer_delegate_ from blob_request_. | 504 // This halts any calls to file_writer_delegate_ from blob_request_. |
| 552 blob_request_->Cancel(); | 505 blob_request_->Cancel(); |
| 553 | 506 |
| 554 if (dispatcher_.get()) | 507 if (dispatcher_.get()) |
| 555 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); | 508 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); |
| 556 cancel_operation->dispatcher_->DidSucceed(); | 509 cancel_dispatcher->DidSucceed(); |
| 557 dispatcher_.reset(); | 510 dispatcher_.reset(); |
| 558 } else { | 511 } else { |
| 559 #ifndef NDEBUG | 512 #ifndef NDEBUG |
| 560 DCHECK(kOperationTruncate == pending_operation_); | 513 DCHECK(kOperationTruncate == pending_operation_); |
| 561 #endif | 514 #endif |
| 562 // We're cancelling a truncate operation, but we can't actually stop it | 515 // We're cancelling a truncate operation, but we can't actually stop it |
| 563 // since it's been proxied to another thread. We need to save the | 516 // since it's been proxied to another thread. We need to save the |
| 564 // cancel_operation so that when the truncate returns, it can see that it's | 517 // cancel_dispatcher so that when the truncate returns, it can see that it's |
| 565 // been cancelled, report it, and report that the cancel has succeeded. | 518 // been cancelled, report it, and report that the cancel has succeeded. |
| 566 DCHECK(!cancel_operation_.get()); | 519 DCHECK(!cancel_dispatcher_.get()); |
| 567 cancel_operation_.swap(cancel_operation); | 520 cancel_dispatcher_ = cancel_dispatcher.Pass(); |
| 568 } | 521 } |
| 569 } | 522 } |
| 570 | 523 |
| 524 void FileSystemOperation::SyncGetPlatformPath(const GURL& path, |
| 525 FilePath* platform_path) { |
| 526 #ifndef NDEBUG |
| 527 DCHECK(kOperationNone == pending_operation_); |
| 528 pending_operation_ = kOperationGetLocalPath; |
| 529 #endif |
| 530 if (!SetupSrcContextForRead(path)) { |
| 531 delete this; |
| 532 return; |
| 533 } |
| 534 |
| 535 operation_context_.src_file_util()->GetLocalFilePath( |
| 536 &operation_context_, src_virtual_path_, platform_path); |
| 537 |
| 538 delete this; |
| 539 } |
| 540 |
| 571 void FileSystemOperation::GetUsageAndQuotaThenCallback( | 541 void FileSystemOperation::GetUsageAndQuotaThenCallback( |
| 572 const GURL& origin_url, | 542 const GURL& origin_url, |
| 573 const quota::QuotaManager::GetUsageAndQuotaCallback& callback) { | 543 const quota::QuotaManager::GetUsageAndQuotaCallback& callback) { |
| 574 quota::QuotaManagerProxy* quota_manager_proxy = | 544 quota::QuotaManagerProxy* quota_manager_proxy = |
| 575 file_system_context()->quota_manager_proxy(); | 545 file_system_context()->quota_manager_proxy(); |
| 576 if (!quota_manager_proxy || | 546 if (!quota_manager_proxy || |
| 577 !file_system_context()->GetQuotaUtil( | 547 !file_system_context()->GetQuotaUtil( |
| 578 operation_context_.src_type())) { | 548 operation_context_.src_type())) { |
| 579 // If we don't have the quota manager or the requested filesystem type | 549 // If we don't have the quota manager or the requested filesystem type |
| 580 // does not support quota, we should be able to let it go. | 550 // does not support quota, we should be able to let it go. |
| 581 callback.Run(quota::kQuotaStatusOk, 0, kint64max); | 551 callback.Run(quota::kQuotaStatusOk, 0, kint64max); |
| 582 return; | 552 return; |
| 583 } | 553 } |
| 584 DCHECK(quota_manager_proxy); | 554 DCHECK(quota_manager_proxy); |
| 585 DCHECK(quota_manager_proxy->quota_manager()); | 555 DCHECK(quota_manager_proxy->quota_manager()); |
| 586 quota_manager_proxy->quota_manager()->GetUsageAndQuota( | 556 quota_manager_proxy->quota_manager()->GetUsageAndQuota( |
| 587 operation_context_.src_origin_url(), | 557 operation_context_.src_origin_url(), |
| 588 FileSystemTypeToQuotaStorageType( | 558 FileSystemTypeToQuotaStorageType( |
| 589 operation_context_.src_type()), | 559 operation_context_.src_type()), |
| 590 callback); | 560 callback); |
| 591 } | 561 } |
| 592 | 562 |
| 593 void FileSystemOperation::DidGetRootPath( | |
| 594 bool success, | |
| 595 const FilePath& path, const std::string& name) { | |
| 596 if (!dispatcher_.get()) | |
| 597 return; | |
| 598 DCHECK(success || path.empty()); | |
| 599 GURL result; | |
| 600 if (!dispatcher_.get()) | |
| 601 return; | |
| 602 // We ignore the path, and return a URL instead. The point was just to verify | |
| 603 // that we could create/find the path. | |
| 604 if (success) { | |
| 605 result = GetFileSystemRootURI( | |
| 606 operation_context_.src_origin_url(), | |
| 607 operation_context_.src_type()); | |
| 608 DCHECK(result.is_valid()); | |
| 609 dispatcher_->DidOpenFileSystem(name, result); | |
| 610 } else { | |
| 611 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 612 } | |
| 613 } | |
| 614 | |
| 615 void FileSystemOperation::DidEnsureFileExistsExclusive( | 563 void FileSystemOperation::DidEnsureFileExistsExclusive( |
| 616 base::PlatformFileError rv, bool created) { | 564 base::PlatformFileError rv, bool created) { |
| 617 if (rv == base::PLATFORM_FILE_OK && !created) { | 565 if (rv == base::PLATFORM_FILE_OK && !created) { |
| 618 if (dispatcher_.get()) | 566 if (dispatcher_.get()) |
| 619 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); | 567 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); |
| 620 } else { | 568 } else { |
| 621 DidFinishFileOperation(rv); | 569 DidFinishFileOperation(rv); |
| 622 } | 570 } |
| 623 } | 571 } |
| 624 | 572 |
| 625 void FileSystemOperation::DidEnsureFileExistsNonExclusive( | 573 void FileSystemOperation::DidEnsureFileExistsNonExclusive( |
| 626 base::PlatformFileError rv, bool /* created */) { | 574 base::PlatformFileError rv, bool /* created */) { |
| 627 DidFinishFileOperation(rv); | 575 DidFinishFileOperation(rv); |
| 628 } | 576 } |
| 629 | 577 |
| 630 void FileSystemOperation::DidFinishFileOperation( | 578 void FileSystemOperation::DidFinishFileOperation( |
| 631 base::PlatformFileError rv) { | 579 base::PlatformFileError rv) { |
| 632 if (cancel_operation_.get()) { | 580 if (cancel_dispatcher_.get()) { |
| 633 #ifndef NDEBUG | 581 #ifndef NDEBUG |
| 634 DCHECK(kOperationTruncate == pending_operation_); | 582 DCHECK(kOperationTruncate == pending_operation_); |
| 635 #endif | 583 #endif |
| 636 | 584 |
| 637 if (dispatcher_.get()) | 585 if (dispatcher_.get()) |
| 638 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); | 586 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); |
| 639 cancel_operation_->dispatcher_->DidSucceed(); | 587 cancel_dispatcher_->DidSucceed(); |
| 640 } else if (dispatcher_.get()) { | 588 } else if (dispatcher_.get()) { |
| 641 if (rv == base::PLATFORM_FILE_OK) | 589 if (rv == base::PLATFORM_FILE_OK) |
| 642 dispatcher_->DidSucceed(); | 590 dispatcher_->DidSucceed(); |
| 643 else | 591 else |
| 644 dispatcher_->DidFail(rv); | 592 dispatcher_->DidFail(rv); |
| 645 } | 593 } |
| 646 } | 594 } |
| 647 | 595 |
| 648 void FileSystemOperation::DidDirectoryExists( | 596 void FileSystemOperation::DidDirectoryExists( |
| 649 base::PlatformFileError rv, | 597 base::PlatformFileError rv, |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 bool result = VerifyFileSystemPathForWrite( | 800 bool result = VerifyFileSystemPathForWrite( |
| 853 path, create, &origin_url, &type, &dest_virtual_path_, &file_util); | 801 path, create, &origin_url, &type, &dest_virtual_path_, &file_util); |
| 854 operation_context_.set_dest_origin_url(origin_url); | 802 operation_context_.set_dest_origin_url(origin_url); |
| 855 operation_context_.set_dest_type(type); | 803 operation_context_.set_dest_type(type); |
| 856 if (!operation_context_.dest_file_util()) | 804 if (!operation_context_.dest_file_util()) |
| 857 operation_context_.set_dest_file_util(file_util); | 805 operation_context_.set_dest_file_util(file_util); |
| 858 return result; | 806 return result; |
| 859 } | 807 } |
| 860 | 808 |
| 861 } // namespace fileapi | 809 } // namespace fileapi |
| OLD | NEW |