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 |