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_.swap(cancel_dispatcher); |
tzik
2012/01/10 08:31:13
can be cancel_dispatcher_ = cancel_dispatcher.Pass
kinuko
2012/01/10 09:48:53
Done.
| |
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 } | |
609 dispatcher_->DidOpenFileSystem(name, result); | |
610 } | |
611 | |
612 void FileSystemOperation::DidEnsureFileExistsExclusive( | 563 void FileSystemOperation::DidEnsureFileExistsExclusive( |
613 base::PlatformFileError rv, bool created) { | 564 base::PlatformFileError rv, bool created) { |
614 if (rv == base::PLATFORM_FILE_OK && !created) { | 565 if (rv == base::PLATFORM_FILE_OK && !created) { |
615 if (dispatcher_.get()) | 566 if (dispatcher_.get()) |
616 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); | 567 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); |
617 } else { | 568 } else { |
618 DidFinishFileOperation(rv); | 569 DidFinishFileOperation(rv); |
619 } | 570 } |
620 } | 571 } |
621 | 572 |
622 void FileSystemOperation::DidEnsureFileExistsNonExclusive( | 573 void FileSystemOperation::DidEnsureFileExistsNonExclusive( |
623 base::PlatformFileError rv, bool /* created */) { | 574 base::PlatformFileError rv, bool /* created */) { |
624 DidFinishFileOperation(rv); | 575 DidFinishFileOperation(rv); |
625 } | 576 } |
626 | 577 |
627 void FileSystemOperation::DidFinishFileOperation( | 578 void FileSystemOperation::DidFinishFileOperation( |
628 base::PlatformFileError rv) { | 579 base::PlatformFileError rv) { |
629 if (cancel_operation_.get()) { | 580 if (cancel_dispatcher_.get()) { |
630 #ifndef NDEBUG | 581 #ifndef NDEBUG |
631 DCHECK(kOperationTruncate == pending_operation_); | 582 DCHECK(kOperationTruncate == pending_operation_); |
632 #endif | 583 #endif |
633 | 584 |
634 if (dispatcher_.get()) | 585 if (dispatcher_.get()) |
635 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); | 586 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); |
636 cancel_operation_->dispatcher_->DidSucceed(); | 587 cancel_dispatcher_->DidSucceed(); |
637 } else if (dispatcher_.get()) { | 588 } else if (dispatcher_.get()) { |
638 if (rv == base::PLATFORM_FILE_OK) | 589 if (rv == base::PLATFORM_FILE_OK) |
639 dispatcher_->DidSucceed(); | 590 dispatcher_->DidSucceed(); |
640 else | 591 else |
641 dispatcher_->DidFail(rv); | 592 dispatcher_->DidFail(rv); |
642 } | 593 } |
643 } | 594 } |
644 | 595 |
645 void FileSystemOperation::DidDirectoryExists( | 596 void FileSystemOperation::DidDirectoryExists( |
646 base::PlatformFileError rv, | 597 base::PlatformFileError rv, |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
849 bool result = VerifyFileSystemPathForWrite( | 800 bool result = VerifyFileSystemPathForWrite( |
850 path, create, &origin_url, &type, &dest_virtual_path_, &file_util); | 801 path, create, &origin_url, &type, &dest_virtual_path_, &file_util); |
851 operation_context_.set_dest_origin_url(origin_url); | 802 operation_context_.set_dest_origin_url(origin_url); |
852 operation_context_.set_dest_type(type); | 803 operation_context_.set_dest_type(type); |
853 if (!operation_context_.dest_file_util()) | 804 if (!operation_context_.dest_file_util()) |
854 operation_context_.set_dest_file_util(file_util); | 805 operation_context_.set_dest_file_util(file_util); |
855 return result; | 806 return result; |
856 } | 807 } |
857 | 808 |
858 } // namespace fileapi | 809 } // namespace fileapi |
OLD | NEW |