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 |