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