Chromium Code Reviews| 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 "content/browser/download/download_manager.h" | 5 #include "content/browser/download/download_manager.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 } | 45 } |
| 46 | 46 |
| 47 } // namespace | 47 } // namespace |
| 48 | 48 |
| 49 DownloadManager::DownloadManager(DownloadManagerDelegate* delegate, | 49 DownloadManager::DownloadManager(DownloadManagerDelegate* delegate, |
| 50 DownloadStatusUpdater* status_updater) | 50 DownloadStatusUpdater* status_updater) |
| 51 : shutdown_needed_(false), | 51 : shutdown_needed_(false), |
| 52 browser_context_(NULL), | 52 browser_context_(NULL), |
| 53 file_manager_(NULL), | 53 file_manager_(NULL), |
| 54 status_updater_(status_updater->AsWeakPtr()), | 54 status_updater_(status_updater->AsWeakPtr()), |
| 55 delegate_(delegate) { | 55 delegate_(delegate), |
| 56 largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) { | |
| 56 if (status_updater_) | 57 if (status_updater_) |
| 57 status_updater_->AddDelegate(this); | 58 status_updater_->AddDelegate(this); |
| 58 } | 59 } |
| 59 | 60 |
| 60 DownloadManager::~DownloadManager() { | 61 DownloadManager::~DownloadManager() { |
| 61 DCHECK(!shutdown_needed_); | 62 DCHECK(!shutdown_needed_); |
| 62 if (status_updater_) | 63 if (status_updater_) |
| 63 status_updater_->RemoveDelegate(this); | 64 status_updater_->RemoveDelegate(this); |
| 64 } | 65 } |
| 65 | 66 |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 } | 282 } |
| 282 } | 283 } |
| 283 | 284 |
| 284 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { | 285 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { |
| 285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 286 | 287 |
| 287 DownloadItem* download = new DownloadItem(this, *info, | 288 DownloadItem* download = new DownloadItem(this, *info, |
| 288 browser_context_->IsOffTheRecord()); | 289 browser_context_->IsOffTheRecord()); |
| 289 int32 download_id = info->download_id; | 290 int32 download_id = info->download_id; |
| 290 DCHECK(!ContainsKey(in_progress_, download_id)); | 291 DCHECK(!ContainsKey(in_progress_, download_id)); |
| 292 | |
| 293 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. | |
| 291 CHECK(!ContainsKey(active_downloads_, download_id)); | 294 CHECK(!ContainsKey(active_downloads_, download_id)); |
| 292 downloads_.insert(download); | 295 downloads_.insert(download); |
| 293 active_downloads_[download_id] = download; | 296 active_downloads_[download_id] = download; |
| 294 } | 297 } |
| 295 | 298 |
| 296 void DownloadManager::ContinueDownloadWithPath(DownloadItem* download, | 299 void DownloadManager::ContinueDownloadWithPath(DownloadItem* download, |
| 297 const FilePath& chosen_file) { | 300 const FilePath& chosen_file) { |
| 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 301 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 299 DCHECK(download); | 302 DCHECK(download); |
| 300 | 303 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 NewRunnableMethod( | 502 NewRunnableMethod( |
| 500 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); | 503 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); |
| 501 | 504 |
| 502 if (uniquifier) | 505 if (uniquifier) |
| 503 item->set_path_uniquifier(uniquifier); | 506 item->set_path_uniquifier(uniquifier); |
| 504 | 507 |
| 505 item->OnDownloadRenamedToFinalName(full_path); | 508 item->OnDownloadRenamedToFinalName(full_path); |
| 506 delegate_->UpdatePathForItemInPersistentStore(item, full_path); | 509 delegate_->UpdatePathForItemInPersistentStore(item, full_path); |
| 507 } | 510 } |
| 508 | 511 |
| 509 void DownloadManager::DownloadCancelled(int32 download_id) { | 512 void DownloadManager::CancelDownload(int32 download_id) { |
| 510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 511 DownloadMap::iterator it = in_progress_.find(download_id); | 514 DownloadItem* download = GetDownloadItem(download_id); |
| 512 if (it == in_progress_.end()) | 515 if (!download) |
| 513 return; | 516 return; |
| 514 DownloadItem* download = it->second; | |
| 515 | 517 |
| 516 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 518 download->Cancel(true); |
| 519 } | |
| 520 | |
| 521 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { | |
| 522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 523 int download_id = download->id(); | |
| 524 | |
| 525 VLOG(20) << __FUNCTION__ << "()" | |
| 517 << " download = " << download->DebugString(true); | 526 << " download = " << download->DebugString(true); |
| 518 | 527 |
| 519 // Clean up will happen when the history system create callback runs if we | 528 // Clean up will happen when the history system create callback runs if we |
| 520 // don't have a valid db_handle yet. | 529 // don't have a valid db_handle yet. |
| 521 if (download->db_handle() != DownloadItem::kUninitializedHandle) { | 530 if (download->db_handle() != DownloadItem::kUninitializedHandle) { |
| 522 in_progress_.erase(it); | 531 in_progress_.erase(download_id); |
| 523 active_downloads_.erase(download_id); | 532 active_downloads_.erase(download_id); |
| 524 UpdateDownloadProgress(); // Reflect removal from in_progress_. | 533 UpdateDownloadProgress(); // Reflect removal from in_progress_. |
| 525 delegate_->UpdateItemInPersistentStore(download); | 534 delegate_->UpdateItemInPersistentStore(download); |
| 535 | |
| 536 // This function is called from the DownloadItem, so DI state | |
| 537 // should already have been updated. | |
| 526 AssertQueueStateConsistent(download); | 538 AssertQueueStateConsistent(download); |
| 527 } | 539 } |
| 528 | 540 |
| 529 DownloadCancelledInternal(download_id, download->request_handle()); | 541 download->OffThreadCancel(file_manager_); |
| 530 } | |
| 531 | |
| 532 void DownloadManager::DownloadCancelledInternal( | |
| 533 int download_id, const DownloadRequestHandle& request_handle) { | |
| 534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 535 request_handle.CancelRequest(); | |
| 536 | |
| 537 BrowserThread::PostTask( | |
| 538 BrowserThread::FILE, FROM_HERE, | |
| 539 NewRunnableMethod( | |
| 540 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | |
| 541 } | 542 } |
| 542 | 543 |
| 543 void DownloadManager::OnDownloadError(int32 download_id, | 544 void DownloadManager::OnDownloadError(int32 download_id, |
| 544 int64 size, | 545 int64 size, |
| 545 int os_error) { | 546 int os_error) { |
| 546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 547 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 547 DownloadMap::iterator it = active_downloads_.find(download_id); | 548 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 548 // A cancel at the right time could remove the download from the | 549 // A cancel at the right time could remove the download from the |
| 549 // |active_downloads_| map before we get here. | 550 // |active_downloads_| map before we get here. |
| 550 if (it == active_downloads_.end()) | 551 if (it == active_downloads_.end()) |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 int32 download_id = *id_ptr; | 756 int32 download_id = *id_ptr; |
| 756 delete id_ptr; | 757 delete id_ptr; |
| 757 | 758 |
| 758 DownloadItem* download = GetActiveDownloadItem(download_id); | 759 DownloadItem* download = GetActiveDownloadItem(download_id); |
| 759 if (!download) | 760 if (!download) |
| 760 return; | 761 return; |
| 761 | 762 |
| 762 VLOG(20) << __FUNCTION__ << "()" | 763 VLOG(20) << __FUNCTION__ << "()" |
| 763 << " download = " << download->DebugString(true); | 764 << " download = " << download->DebugString(true); |
| 764 | 765 |
| 765 DownloadCancelledInternal(download_id, download->request_handle()); | 766 download->OffThreadCancel(file_manager_); |
| 766 } | 767 } |
| 767 | 768 |
| 768 // Operations posted to us from the history service ---------------------------- | 769 // Operations posted to us from the history service ---------------------------- |
| 769 | 770 |
| 770 // The history service has retrieved all download entries. 'entries' contains | 771 // The history service has retrieved all download entries. 'entries' contains |
| 771 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 772 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
| 772 void DownloadManager::OnPersistentStoreQueryComplete( | 773 void DownloadManager::OnPersistentStoreQueryComplete( |
| 773 std::vector<DownloadPersistentStoreInfo>* entries) { | 774 std::vector<DownloadPersistentStoreInfo>* entries) { |
| 775 // TODO(rdsmith): Remove this and related logic when | |
| 776 // http://crbug.com/84508 is fixed. | |
| 777 int64 largest_handle = 0; | |
| 778 | |
| 774 for (size_t i = 0; i < entries->size(); ++i) { | 779 for (size_t i = 0; i < entries->size(); ++i) { |
| 775 DownloadItem* download = new DownloadItem(this, entries->at(i)); | 780 DownloadItem* download = new DownloadItem(this, entries->at(i)); |
| 781 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. | |
| 776 CHECK(!ContainsKey(history_downloads_, download->db_handle())); | 782 CHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 777 downloads_.insert(download); | 783 downloads_.insert(download); |
| 778 history_downloads_[download->db_handle()] = download; | 784 history_downloads_[download->db_handle()] = download; |
| 779 VLOG(20) << __FUNCTION__ << "()" << i << ">" | 785 VLOG(20) << __FUNCTION__ << "()" << i << ">" |
| 780 << " download = " << download->DebugString(true); | 786 << " download = " << download->DebugString(true); |
| 787 | |
| 788 if (download->db_handle() > largest_handle) | |
|
benjhayden
2011/08/25 20:41:40
Why not use largest_db_handle_in_history_ here and
Randy Smith (Not in Mondays)
2011/08/25 21:19:55
Because I'm being over-paranoid; I'll fix that. (
| |
| 789 largest_handle = download->db_handle(); | |
| 781 } | 790 } |
| 791 largest_db_handle_in_history_ = largest_handle; | |
| 782 NotifyModelChanged(); | 792 NotifyModelChanged(); |
| 783 CheckForHistoryFilesRemoval(); | 793 CheckForHistoryFilesRemoval(); |
| 784 } | 794 } |
| 785 | 795 |
| 786 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, | 796 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, |
| 787 int64 db_handle) { | 797 int64 db_handle) { |
| 788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 798 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 789 | 799 |
| 790 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 | 800 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 |
| 791 // is fixed. | 801 // is fixed. |
| 792 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle); | 802 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle); |
| 793 | 803 |
| 794 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle); | 804 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle); |
| 795 download->set_db_handle(db_handle); | 805 download->set_db_handle(db_handle); |
| 796 | 806 |
| 807 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 | |
| 808 // is fixed. | |
| 797 CHECK(!ContainsKey(history_downloads_, download->db_handle())); | 809 CHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 798 history_downloads_[download->db_handle()] = download; | 810 history_downloads_[download->db_handle()] = download; |
| 799 | 811 |
| 800 // Show in the appropriate browser UI. | 812 // Show in the appropriate browser UI. |
| 801 // This includes buttons to save or cancel, for a dangerous download. | 813 // This includes buttons to save or cancel, for a dangerous download. |
| 802 ShowDownloadInBrowser(download); | 814 ShowDownloadInBrowser(download); |
| 803 | 815 |
| 804 // Inform interested objects about the new download. | 816 // Inform interested objects about the new download. |
| 805 NotifyModelChanged(); | 817 NotifyModelChanged(); |
| 806 } | 818 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 823 int64 db_handle) { | 835 int64 db_handle) { |
| 824 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 836 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 825 DownloadItem* download = GetActiveDownloadItem(download_id); | 837 DownloadItem* download = GetActiveDownloadItem(download_id); |
| 826 if (!download) | 838 if (!download) |
| 827 return; | 839 return; |
| 828 | 840 |
| 829 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle | 841 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
| 830 << " download_id = " << download_id | 842 << " download_id = " << download_id |
| 831 << " download = " << download->DebugString(true); | 843 << " download = " << download->DebugString(true); |
| 832 | 844 |
| 845 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. | |
| 846 CHECK(!ContainsKey(history_downloads_, download->db_handle())); | |
| 847 int64 largest_handle = largest_db_handle_in_history_; | |
| 848 base::debug::Alias(&largest_handle); | |
| 849 | |
| 833 AddDownloadItemToHistory(download, db_handle); | 850 AddDownloadItemToHistory(download, db_handle); |
| 834 | 851 |
| 835 // If the download is still in progress, try to complete it. | 852 // If the download is still in progress, try to complete it. |
| 836 // | 853 // |
| 837 // Otherwise, download has been cancelled or interrupted before we've | 854 // Otherwise, download has been cancelled or interrupted before we've |
| 838 // received the DB handle. We post one final message to the history | 855 // received the DB handle. We post one final message to the history |
| 839 // service so that it can be properly in sync with the DownloadItem's | 856 // service so that it can be properly in sync with the DownloadItem's |
| 840 // completion status, and also inform any observers so that they get | 857 // completion status, and also inform any observers so that they get |
| 841 // more than just the start notification. | 858 // more than just the start notification. |
| 842 if (download->IsInProgress()) { | 859 if (download->IsInProgress()) { |
| 843 MaybeCompleteDownload(download); | 860 MaybeCompleteDownload(download); |
| 844 } else { | 861 } else { |
| 862 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 | |
| 863 // is fixed. | |
| 845 CHECK(download->IsCancelled()) | 864 CHECK(download->IsCancelled()) |
| 846 << " download = " << download->DebugString(true); | 865 << " download = " << download->DebugString(true); |
| 847 in_progress_.erase(download_id); | 866 in_progress_.erase(download_id); |
| 848 active_downloads_.erase(download_id); | 867 active_downloads_.erase(download_id); |
| 849 delegate_->UpdateItemInPersistentStore(download); | 868 delegate_->UpdateItemInPersistentStore(download); |
| 850 download->UpdateObservers(); | 869 download->UpdateObservers(); |
| 851 } | 870 } |
| 852 } | 871 } |
| 853 | 872 |
| 854 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { | 873 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 972 // have been cleared. | 991 // have been cleared. |
| 973 if (it == save_page_downloads_.end()) | 992 if (it == save_page_downloads_.end()) |
| 974 return; | 993 return; |
| 975 | 994 |
| 976 DownloadItem* download = it->second; | 995 DownloadItem* download = it->second; |
| 977 if (!download) { | 996 if (!download) { |
| 978 NOTREACHED(); | 997 NOTREACHED(); |
| 979 return; | 998 return; |
| 980 } | 999 } |
| 981 | 1000 |
| 1001 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. | |
| 1002 CHECK(!ContainsKey(history_downloads_, download->db_handle())); | |
| 1003 int64 largest_handle = largest_db_handle_in_history_; | |
| 1004 base::debug::Alias(&largest_handle); | |
| 1005 | |
| 982 AddDownloadItemToHistory(download, db_handle); | 1006 AddDownloadItemToHistory(download, db_handle); |
| 983 | 1007 |
| 984 // Finalize this download if it finished before the history callback. | 1008 // Finalize this download if it finished before the history callback. |
| 985 if (!download->IsInProgress()) | 1009 if (!download->IsInProgress()) |
| 986 SavePageDownloadFinished(download); | 1010 SavePageDownloadFinished(download); |
| 987 } | 1011 } |
| 988 | 1012 |
| 989 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { | 1013 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { |
| 990 if (download->db_handle() != DownloadItem::kUninitializedHandle) { | 1014 if (download->db_handle() != DownloadItem::kUninitializedHandle) { |
| 991 delegate_->UpdateItemInPersistentStore(download); | 1015 delegate_->UpdateItemInPersistentStore(download); |
| 992 DCHECK(ContainsKey(save_page_downloads_, download->id())); | 1016 DCHECK(ContainsKey(save_page_downloads_, download->id())); |
| 993 save_page_downloads_.erase(download->id()); | 1017 save_page_downloads_.erase(download->id()); |
| 994 | 1018 |
| 995 if (download->IsComplete()) | 1019 if (download->IsComplete()) |
| 996 NotificationService::current()->Notify( | 1020 NotificationService::current()->Notify( |
| 997 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | 1021 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
| 998 Source<DownloadManager>(this), | 1022 Source<DownloadManager>(this), |
| 999 Details<DownloadItem>(download)); | 1023 Details<DownloadItem>(download)); |
| 1000 } | 1024 } |
| 1001 } | 1025 } |
| OLD | NEW |