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 "content/browser/download/download_item_impl.h" | 5 #include "content/browser/download/download_item_impl.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 | 482 |
483 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); | 483 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); |
484 | 484 |
485 TransitionTo(CANCELLED); | 485 TransitionTo(CANCELLED); |
486 if (user_cancel) | 486 if (user_cancel) |
487 delegate_->DownloadStopped(this); | 487 delegate_->DownloadStopped(this); |
488 } | 488 } |
489 | 489 |
490 // An error occurred somewhere. | 490 // An error occurred somewhere. |
491 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { | 491 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { |
492 // Somewhat counter-intuitively, it is possible for us to receive an | 492 // It should not be possible both to have an error and complete. |
493 // interrupt after we've already been interrupted. The generation of | 493 DCHECK(IsInProgress()); |
494 // interrupts from the file thread Renames and the generation of | |
495 // interrupts from disk writes go through two different mechanisms (driven | |
496 // by rename requests from UI thread and by write requests from IO thread, | |
497 // respectively), and since we choose not to keep state on the File thread, | |
498 // this is the place where the races collide. It's also possible for | |
499 // interrupts to race with cancels. | |
500 | |
501 // Whatever happens, the first one to hit the UI thread wins. | |
502 if (!IsInProgress()) | |
503 return; | |
504 | |
505 last_reason_ = reason; | 494 last_reason_ = reason; |
506 TransitionTo(INTERRUPTED); | 495 TransitionTo(INTERRUPTED); |
507 download_stats::RecordDownloadInterrupted( | 496 download_stats::RecordDownloadInterrupted( |
508 reason, received_bytes_, total_bytes_); | 497 reason, received_bytes_, total_bytes_); |
509 delegate_->DownloadStopped(this); | 498 delegate_->DownloadStopped(this); |
510 } | 499 } |
511 | 500 |
512 void DownloadItemImpl::MarkAsComplete() { | 501 void DownloadItemImpl::MarkAsComplete() { |
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
514 | 503 |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 BrowserThread::FILE, FROM_HERE, | 732 BrowserThread::FILE, FROM_HERE, |
744 base::Bind(&DownloadFileManager::CompleteDownload, | 733 base::Bind(&DownloadFileManager::CompleteDownload, |
745 file_manager, GetGlobalId(), | 734 file_manager, GetGlobalId(), |
746 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, | 735 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, |
747 weak_ptr_factory_.GetWeakPtr()))); | 736 weak_ptr_factory_.GetWeakPtr()))); |
748 } | 737 } |
749 } | 738 } |
750 | 739 |
751 void DownloadItemImpl::OnDownloadRenamedToFinalName( | 740 void DownloadItemImpl::OnDownloadRenamedToFinalName( |
752 DownloadFileManager* file_manager, | 741 DownloadFileManager* file_manager, |
753 content::DownloadInterruptReason reason, | |
754 const FilePath& full_path) { | 742 const FilePath& full_path) { |
755 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 743 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
756 | 744 |
757 VLOG(20) << __FUNCTION__ << "()" | 745 VLOG(20) << __FUNCTION__ << "()" |
758 << " full_path = \"" << full_path.value() << "\"" | 746 << " full_path = \"" << full_path.value() << "\"" |
759 << " needed rename = " << NeedsRename() | 747 << " needed rename = " << NeedsRename() |
760 << " " << DebugString(false); | 748 << " " << DebugString(false); |
761 DCHECK(NeedsRename()); | 749 DCHECK(NeedsRename()); |
762 | 750 |
763 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 751 if (full_path.empty()) |
764 Interrupt(reason); | 752 // Indicates error; also reported |
| 753 // by DownloadManagerImpl::OnDownloadInterrupted. |
765 return; | 754 return; |
766 } | |
767 | 755 |
768 // full_path is now the current and target file path. | 756 // full_path is now the current and target file path. |
769 DCHECK(!full_path.empty()); | |
770 target_path_ = full_path; | 757 target_path_ = full_path; |
771 SetFullPath(full_path); | 758 SetFullPath(full_path); |
772 delegate_->DownloadRenamedToFinalName(this); | 759 delegate_->DownloadRenamedToFinalName(this); |
773 | 760 |
774 // Complete the download and release the DownloadFile. | 761 // Complete the download and release the DownloadFile. |
775 BrowserThread::PostTask( | 762 BrowserThread::PostTask( |
776 BrowserThread::FILE, FROM_HERE, | 763 BrowserThread::FILE, FROM_HERE, |
777 base::Bind(&DownloadFileManager::CompleteDownload, | 764 base::Bind(&DownloadFileManager::CompleteDownload, |
778 file_manager, GetGlobalId(), | 765 file_manager, GetGlobalId(), |
779 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, | 766 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, |
780 weak_ptr_factory_.GetWeakPtr()))); | 767 weak_ptr_factory_.GetWeakPtr()))); |
781 } | 768 } |
782 | 769 |
783 void DownloadItemImpl::OnDownloadFileReleased() { | 770 void DownloadItemImpl::OnDownloadFileReleased() { |
784 if (delegate_->ShouldOpenDownload(this)) | 771 if (delegate_->ShouldOpenDownload(this)) |
785 Completed(); | 772 Completed(); |
786 else | 773 else |
787 delegate_delayed_complete_ = true; | 774 delegate_delayed_complete_ = true; |
788 } | 775 } |
789 | 776 |
790 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( | 777 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( |
791 content::DownloadInterruptReason reason, | |
792 const FilePath& full_path) { | 778 const FilePath& full_path) { |
793 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 779 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
794 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 780 if (!full_path.empty()) { |
795 Interrupt(reason); | |
796 } else { | |
797 SetFullPath(full_path); | 781 SetFullPath(full_path); |
798 UpdateObservers(); | 782 UpdateObservers(); |
799 } | 783 } |
800 | |
801 delegate_->DownloadRenamedToIntermediateName(this); | 784 delegate_->DownloadRenamedToIntermediateName(this); |
802 } | 785 } |
803 | 786 |
804 bool DownloadItemImpl::MatchesQuery(const string16& query) const { | 787 bool DownloadItemImpl::MatchesQuery(const string16& query) const { |
805 if (query.empty()) | 788 if (query.empty()) |
806 return true; | 789 return true; |
807 | 790 |
808 DCHECK_EQ(query, base::i18n::ToLower(query)); | 791 DCHECK_EQ(query, base::i18n::ToLower(query)); |
809 | 792 |
810 string16 url_raw(UTF8ToUTF16(GetURL().spec())); | 793 string16 url_raw(UTF8ToUTF16(GetURL().spec())); |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 std::map<const void*, ExternalData*>::iterator it = | 1186 std::map<const void*, ExternalData*>::iterator it = |
1204 external_data_map_.find(key); | 1187 external_data_map_.find(key); |
1205 | 1188 |
1206 if (it == external_data_map_.end()) { | 1189 if (it == external_data_map_.end()) { |
1207 external_data_map_[key] = data; | 1190 external_data_map_[key] = data; |
1208 } else if (it->second != data) { | 1191 } else if (it->second != data) { |
1209 delete it->second; | 1192 delete it->second; |
1210 it->second = data; | 1193 it->second = data; |
1211 } | 1194 } |
1212 } | 1195 } |
OLD | NEW |