| 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 largest_db_handle_in_history_ = 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_db_handle_in_history_) |
| 789 largest_db_handle_in_history_ = download->db_handle(); |
| 781 } | 790 } |
| 782 NotifyModelChanged(); | 791 NotifyModelChanged(); |
| 783 CheckForHistoryFilesRemoval(); | 792 CheckForHistoryFilesRemoval(); |
| 784 } | 793 } |
| 785 | 794 |
| 786 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, | 795 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, |
| 787 int64 db_handle) { | 796 int64 db_handle) { |
| 788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 797 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 789 | 798 |
| 790 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 | 799 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 |
| 791 // is fixed. | 800 // is fixed. |
| 792 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle); | 801 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle); |
| 793 | 802 |
| 794 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle); | 803 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle); |
| 795 download->set_db_handle(db_handle); | 804 download->set_db_handle(db_handle); |
| 796 | 805 |
| 806 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 |
| 807 // is fixed. |
| 797 CHECK(!ContainsKey(history_downloads_, download->db_handle())); | 808 CHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 798 history_downloads_[download->db_handle()] = download; | 809 history_downloads_[download->db_handle()] = download; |
| 799 | 810 |
| 800 // Show in the appropriate browser UI. | 811 // Show in the appropriate browser UI. |
| 801 // This includes buttons to save or cancel, for a dangerous download. | 812 // This includes buttons to save or cancel, for a dangerous download. |
| 802 ShowDownloadInBrowser(download); | 813 ShowDownloadInBrowser(download); |
| 803 | 814 |
| 804 // Inform interested objects about the new download. | 815 // Inform interested objects about the new download. |
| 805 NotifyModelChanged(); | 816 NotifyModelChanged(); |
| 806 } | 817 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 823 int64 db_handle) { | 834 int64 db_handle) { |
| 824 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 835 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 825 DownloadItem* download = GetActiveDownloadItem(download_id); | 836 DownloadItem* download = GetActiveDownloadItem(download_id); |
| 826 if (!download) | 837 if (!download) |
| 827 return; | 838 return; |
| 828 | 839 |
| 829 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle | 840 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
| 830 << " download_id = " << download_id | 841 << " download_id = " << download_id |
| 831 << " download = " << download->DebugString(true); | 842 << " download = " << download->DebugString(true); |
| 832 | 843 |
| 844 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. |
| 845 CHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 846 int64 largest_handle = largest_db_handle_in_history_; |
| 847 base::debug::Alias(&largest_handle); |
| 848 |
| 833 AddDownloadItemToHistory(download, db_handle); | 849 AddDownloadItemToHistory(download, db_handle); |
| 834 | 850 |
| 835 // If the download is still in progress, try to complete it. | 851 // If the download is still in progress, try to complete it. |
| 836 // | 852 // |
| 837 // Otherwise, download has been cancelled or interrupted before we've | 853 // Otherwise, download has been cancelled or interrupted before we've |
| 838 // received the DB handle. We post one final message to the history | 854 // 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 | 855 // 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 | 856 // completion status, and also inform any observers so that they get |
| 841 // more than just the start notification. | 857 // more than just the start notification. |
| 842 if (download->IsInProgress()) { | 858 if (download->IsInProgress()) { |
| 843 MaybeCompleteDownload(download); | 859 MaybeCompleteDownload(download); |
| 844 } else { | 860 } else { |
| 861 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 |
| 862 // is fixed. |
| 845 CHECK(download->IsCancelled()) | 863 CHECK(download->IsCancelled()) |
| 846 << " download = " << download->DebugString(true); | 864 << " download = " << download->DebugString(true); |
| 847 in_progress_.erase(download_id); | 865 in_progress_.erase(download_id); |
| 848 active_downloads_.erase(download_id); | 866 active_downloads_.erase(download_id); |
| 849 delegate_->UpdateItemInPersistentStore(download); | 867 delegate_->UpdateItemInPersistentStore(download); |
| 850 download->UpdateObservers(); | 868 download->UpdateObservers(); |
| 851 } | 869 } |
| 852 } | 870 } |
| 853 | 871 |
| 854 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { | 872 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 // have been cleared. | 990 // have been cleared. |
| 973 if (it == save_page_downloads_.end()) | 991 if (it == save_page_downloads_.end()) |
| 974 return; | 992 return; |
| 975 | 993 |
| 976 DownloadItem* download = it->second; | 994 DownloadItem* download = it->second; |
| 977 if (!download) { | 995 if (!download) { |
| 978 NOTREACHED(); | 996 NOTREACHED(); |
| 979 return; | 997 return; |
| 980 } | 998 } |
| 981 | 999 |
| 1000 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. |
| 1001 CHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 1002 int64 largest_handle = largest_db_handle_in_history_; |
| 1003 base::debug::Alias(&largest_handle); |
| 1004 |
| 982 AddDownloadItemToHistory(download, db_handle); | 1005 AddDownloadItemToHistory(download, db_handle); |
| 983 | 1006 |
| 984 // Finalize this download if it finished before the history callback. | 1007 // Finalize this download if it finished before the history callback. |
| 985 if (!download->IsInProgress()) | 1008 if (!download->IsInProgress()) |
| 986 SavePageDownloadFinished(download); | 1009 SavePageDownloadFinished(download); |
| 987 } | 1010 } |
| 988 | 1011 |
| 989 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { | 1012 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { |
| 990 if (download->db_handle() != DownloadItem::kUninitializedHandle) { | 1013 if (download->db_handle() != DownloadItem::kUninitializedHandle) { |
| 991 delegate_->UpdateItemInPersistentStore(download); | 1014 delegate_->UpdateItemInPersistentStore(download); |
| 992 DCHECK(ContainsKey(save_page_downloads_, download->id())); | 1015 DCHECK(ContainsKey(save_page_downloads_, download->id())); |
| 993 save_page_downloads_.erase(download->id()); | 1016 save_page_downloads_.erase(download->id()); |
| 994 | 1017 |
| 995 if (download->IsComplete()) | 1018 if (download->IsComplete()) |
| 996 NotificationService::current()->Notify( | 1019 NotificationService::current()->Notify( |
| 997 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | 1020 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
| 998 Source<DownloadManager>(this), | 1021 Source<DownloadManager>(this), |
| 999 Details<DownloadItem>(download)); | 1022 Details<DownloadItem>(download)); |
| 1000 } | 1023 } |
| 1001 } | 1024 } |
| OLD | NEW |