| 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 "chrome/browser/download/download_manager.h" | 5 #include "chrome/browser/download/download_manager.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 // The user hasn't accepted it, so we need to remove it | 98 // The user hasn't accepted it, so we need to remove it |
| 99 // from the disk. This may or may not result in it being | 99 // from the disk. This may or may not result in it being |
| 100 // removed from the DownloadManager queues and deleted | 100 // removed from the DownloadManager queues and deleted |
| 101 // (specifically, DownloadManager::RemoveDownload only | 101 // (specifically, DownloadManager::RemoveDownload only |
| 102 // removes and deletes it if it's known to the history service) | 102 // removes and deletes it if it's known to the history service) |
| 103 // so the only thing we know after calling this function is that | 103 // so the only thing we know after calling this function is that |
| 104 // the download was deleted if-and-only-if it was removed | 104 // the download was deleted if-and-only-if it was removed |
| 105 // from all queues. | 105 // from all queues. |
| 106 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); | 106 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); |
| 107 } else if (download->IsPartialDownload()) { | 107 } else if (download->IsPartialDownload()) { |
| 108 download->Cancel(false); | 108 download->Cancel(); |
| 109 download_history_->UpdateEntry(download); | |
| 110 } | 109 } |
| 111 } | 110 } |
| 112 | 111 |
| 113 // At this point, all dangerous downloads have had their files removed | 112 // At this point, all dangerous downloads have had their files removed |
| 114 // and all in progress downloads have been cancelled. We can now delete | 113 // and all in progress downloads have been cancelled. We can now delete |
| 115 // anything left. | 114 // anything left. |
| 116 | 115 |
| 117 // Copy downloads_ to separate container so as not to set off checks | 116 // Copy downloads_ to separate container so as not to set off checks |
| 118 // in DownloadItem destruction. | 117 // in DownloadItem destruction. |
| 119 DownloadSet downloads_to_delete; | 118 DownloadSet downloads_to_delete; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1, | 640 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1, |
| 642 // and Safari 5.0.4 - treat the download as complete in this case, so we | 641 // and Safari 5.0.4 - treat the download as complete in this case, so we |
| 643 // follow their lead. | 642 // follow their lead. |
| 644 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) { | 643 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) { |
| 645 OnAllDataSaved(download_id, size, hash); | 644 OnAllDataSaved(download_id, size, hash); |
| 646 } else { | 645 } else { |
| 647 OnDownloadError(download_id, size, os_error); | 646 OnDownloadError(download_id, size, os_error); |
| 648 } | 647 } |
| 649 } | 648 } |
| 650 | 649 |
| 650 void DownloadManager::CancelDownload(int32 download_id) { |
| 651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 652 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 653 if (it == active_downloads_.end()) |
| 654 return; |
| 655 |
| 656 it->second->Cancel(); |
| 657 } |
| 658 |
| 651 void DownloadManager::OnAllDataSaved(int32 download_id, | 659 void DownloadManager::OnAllDataSaved(int32 download_id, |
| 652 int64 size, | 660 int64 size, |
| 653 const std::string& hash) { | 661 const std::string& hash) { |
| 654 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 662 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
| 655 << " size = " << size; | 663 << " size = " << size; |
| 656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 657 | 665 |
| 658 // If it's not in active_downloads_, that means it was cancelled; just | 666 // If it's not in active_downloads_, that means it was cancelled; just |
| 659 // ignore the notification. | 667 // ignore the notification. |
| 660 if (active_downloads_.count(download_id) == 0) | 668 if (active_downloads_.count(download_id) == 0) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 // TODO(rdsmith): Somewhat painful; make sure to disable in | 729 // TODO(rdsmith): Somewhat painful; make sure to disable in |
| 722 // release builds after resolution of http://crbug.com/85408. | 730 // release builds after resolution of http://crbug.com/85408. |
| 723 for (DownloadMap::iterator it = history_downloads_.begin(); | 731 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 724 it != history_downloads_.end(); ++it) { | 732 it != history_downloads_.end(); ++it) { |
| 725 CHECK(it->second != download); | 733 CHECK(it->second != download); |
| 726 } | 734 } |
| 727 } | 735 } |
| 728 | 736 |
| 729 CHECK(ContainsKey(active_downloads_, download->id()) == | 737 CHECK(ContainsKey(active_downloads_, download->id()) == |
| 730 (download->state() == DownloadItem::IN_PROGRESS)); | 738 (download->state() == DownloadItem::IN_PROGRESS)); |
| 731 CHECK(ContainsKey(in_progress_, download->id()) == | 739 // Would check in_progress_, but removal from that queue happens |
| 732 (download->state() == DownloadItem::IN_PROGRESS)); | 740 // before transition from IN_PROGRESS for legacy reasons, so skipping. |
| 733 } | 741 } |
| 734 | 742 |
| 735 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { | 743 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { |
| 736 // If we don't have all the data, the download is not ready for | 744 // If we don't have all the data, the download is not ready for |
| 737 // completion. | 745 // completion. |
| 738 if (!download->all_data_saved()) | 746 if (!download->all_data_saved()) |
| 739 return false; | 747 return false; |
| 740 | 748 |
| 741 // If the download is dangerous, but not yet validated, it's not ready for | 749 // If the download is dangerous, but not yet validated, it's not ready for |
| 742 // completion. | 750 // completion. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 NewRunnableMethod( | 827 NewRunnableMethod( |
| 820 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); | 828 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); |
| 821 | 829 |
| 822 if (uniquifier) | 830 if (uniquifier) |
| 823 item->set_path_uniquifier(uniquifier); | 831 item->set_path_uniquifier(uniquifier); |
| 824 | 832 |
| 825 item->OnDownloadRenamedToFinalName(full_path); | 833 item->OnDownloadRenamedToFinalName(full_path); |
| 826 download_history_->UpdateDownloadPath(item, full_path); | 834 download_history_->UpdateDownloadPath(item, full_path); |
| 827 } | 835 } |
| 828 | 836 |
| 829 void DownloadManager::DownloadCancelled(int32 download_id) { | 837 void DownloadManager::DownloadStopped(int32 download_id) { |
| 830 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 831 DownloadMap::iterator it = in_progress_.find(download_id); | 839 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 832 if (it == in_progress_.end()) | 840 if (it == active_downloads_.end()) |
| 833 return; | 841 return; |
| 834 DownloadItem* download = it->second; | 842 DownloadItem* download = it->second; |
| 835 | 843 |
| 836 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 844 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
| 837 << " download = " << download->DebugString(true); | 845 << " download = " << download->DebugString(true); |
| 838 | 846 |
| 839 // Clean up will happen when the history system create callback runs if we | 847 in_progress_.erase(download_id); |
| 840 // don't have a valid db_handle yet. | 848 active_downloads_.erase(download_id); |
| 841 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | 849 UpdateAppIcon(); // Reflect removal from in_progress_. |
| 842 in_progress_.erase(it); | |
| 843 active_downloads_.erase(download_id); | |
| 844 UpdateAppIcon(); // Reflect removal from in_progress_. | |
| 845 download_history_->UpdateEntry(download); | |
| 846 } | |
| 847 | 850 |
| 848 DownloadCancelledInternal(download_id, download->request_handle()); | 851 // The history service should always outlive the DownloadManager. |
| 849 } | 852 download_history_->UpdateEntry(download); |
| 850 | 853 |
| 851 void DownloadManager::DownloadCancelledInternal( | 854 download->request_handle().CancelRequest(); |
| 852 int download_id, const DownloadRequestHandle& request_handle) { | |
| 853 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 854 request_handle.CancelRequest(); | |
| 855 | 855 |
| 856 BrowserThread::PostTask( | 856 BrowserThread::PostTask( |
| 857 BrowserThread::FILE, FROM_HERE, | 857 BrowserThread::FILE, FROM_HERE, |
| 858 NewRunnableMethod( | 858 NewRunnableMethod( |
| 859 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | 859 file_manager_, &DownloadFileManager::CancelDownload, download_id)); |
| 860 } | 860 } |
| 861 | 861 |
| 862 void DownloadManager::OnDownloadError(int32 download_id, | 862 void DownloadManager::OnDownloadError(int32 download_id, |
| 863 int64 size, | 863 int64 size, |
| 864 int os_error) { | 864 int os_error) { |
| 865 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 865 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 866 DownloadMap::iterator it = active_downloads_.find(download_id); | 866 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 867 // A cancel at the right time could remove the download from the | 867 // A cancel at the right time could remove the download from the |
| 868 // |active_downloads_| map before we get here. | 868 // |active_downloads_| map before we get here. |
| 869 if (it == active_downloads_.end()) | 869 if (it == active_downloads_.end()) |
| 870 return; | 870 return; |
| 871 | 871 |
| 872 DownloadItem* download = it->second; | 872 DownloadItem* download = it->second; |
| 873 | 873 |
| 874 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error | 874 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error |
| 875 << " at offset " << download->received_bytes() | 875 << " at offset " << download->received_bytes() |
| 876 << " for download = " << download->DebugString(true); | 876 << " for download = " << download->DebugString(true); |
| 877 | 877 |
| 878 download->Interrupted(size, os_error); | 878 download->Interrupt(size, os_error); |
| 879 | |
| 880 // TODO(ahendrickson) - Remove this when we add resuming of interrupted | |
| 881 // downloads, as we will keep the download item around in that case. | |
| 882 // | |
| 883 // Clean up will happen when the history system create callback runs if we | |
| 884 // don't have a valid db_handle yet. | |
| 885 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | |
| 886 in_progress_.erase(download_id); | |
| 887 active_downloads_.erase(download_id); | |
| 888 UpdateAppIcon(); // Reflect removal from in_progress_. | |
| 889 download_history_->UpdateEntry(download); | |
| 890 } | |
| 891 | |
| 892 BrowserThread::PostTask( | |
| 893 BrowserThread::FILE, FROM_HERE, | |
| 894 NewRunnableMethod( | |
| 895 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | |
| 896 } | 879 } |
| 897 | 880 |
| 898 void DownloadManager::UpdateAppIcon() { | 881 void DownloadManager::UpdateAppIcon() { |
| 899 if (status_updater_) | 882 if (status_updater_) |
| 900 status_updater_->Update(); | 883 status_updater_->Update(); |
| 901 } | 884 } |
| 902 | 885 |
| 903 void DownloadManager::RemoveDownload(int64 download_handle) { | 886 void DownloadManager::RemoveDownload(DownloadItem* download) { |
| 904 DownloadMap::iterator it = history_downloads_.find(download_handle); | 887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 905 if (it == history_downloads_.end()) | 888 // Silently ignores request if db handle indicates that the download |
| 906 return; | 889 // isn't in the history. |
| 907 | 890 download_history_->RemoveEntry(download->db_handle()); |
| 908 // Make history update. | |
| 909 DownloadItem* download = it->second; | |
| 910 download_history_->RemoveEntry(download); | |
| 911 | 891 |
| 912 // Remove from our tables and delete. | 892 // Remove from our tables and delete. |
| 913 history_downloads_.erase(it); | 893 if (download->db_handle() != DownloadHistory::kUninitializedHandle) |
| 894 history_downloads_.erase(download->db_handle()); |
| 914 int downloads_count = downloads_.erase(download); | 895 int downloads_count = downloads_.erase(download); |
| 915 DCHECK_EQ(1, downloads_count); | 896 DCHECK_EQ(1, downloads_count); |
| 916 | 897 |
| 917 // Tell observers to refresh their views. | 898 // Tell observers to refresh their views. |
| 918 NotifyModelChanged(); | 899 NotifyModelChanged(); |
| 919 | 900 |
| 920 delete download; | 901 delete download; |
| 921 } | 902 } |
| 922 | 903 |
| 923 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, | 904 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 return false; | 1035 return false; |
| 1055 } | 1036 } |
| 1056 | 1037 |
| 1057 return true; | 1038 return true; |
| 1058 } | 1039 } |
| 1059 | 1040 |
| 1060 int64 DownloadManager::GetInProgressDownloadCount() { | 1041 int64 DownloadManager::GetInProgressDownloadCount() { |
| 1061 return in_progress_.size(); | 1042 return in_progress_.size(); |
| 1062 } | 1043 } |
| 1063 | 1044 |
| 1045 void DownloadManager::SetSelectFileDialog( |
| 1046 scoped_refptr<SelectFileDialog> file_dialog) { |
| 1047 select_file_dialog_ = file_dialog; |
| 1048 } |
| 1049 |
| 1064 int64 DownloadManager::GetReceivedDownloadBytes() { | 1050 int64 DownloadManager::GetReceivedDownloadBytes() { |
| 1065 DCHECK(IsDownloadProgressKnown()); | 1051 DCHECK(IsDownloadProgressKnown()); |
| 1066 int64 received_bytes = 0; | 1052 int64 received_bytes = 0; |
| 1067 for (DownloadMap::iterator i = in_progress_.begin(); | 1053 for (DownloadMap::iterator i = in_progress_.begin(); |
| 1068 i != in_progress_.end(); ++i) { | 1054 i != in_progress_.end(); ++i) { |
| 1069 received_bytes += i->second->received_bytes(); | 1055 received_bytes += i->second->received_bytes(); |
| 1070 } | 1056 } |
| 1071 return received_bytes; | 1057 return received_bytes; |
| 1072 } | 1058 } |
| 1073 | 1059 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 int32 download_id = *id_ptr; | 1098 int32 download_id = *id_ptr; |
| 1113 delete id_ptr; | 1099 delete id_ptr; |
| 1114 | 1100 |
| 1115 DownloadItem* download = GetActiveDownloadItem(download_id); | 1101 DownloadItem* download = GetActiveDownloadItem(download_id); |
| 1116 if (!download) | 1102 if (!download) |
| 1117 return; | 1103 return; |
| 1118 | 1104 |
| 1119 VLOG(20) << __FUNCTION__ << "()" | 1105 VLOG(20) << __FUNCTION__ << "()" |
| 1120 << " download = " << download->DebugString(true); | 1106 << " download = " << download->DebugString(true); |
| 1121 | 1107 |
| 1122 DownloadCancelledInternal(download_id, download->request_handle()); | 1108 download->Cancel(); |
| 1123 } | 1109 } |
| 1124 | 1110 |
| 1125 // TODO(phajdan.jr): This is apparently not being exercised in tests. | 1111 // TODO(phajdan.jr): This is apparently not being exercised in tests. |
| 1126 bool DownloadManager::IsDangerous(const DownloadItem& download, | 1112 bool DownloadManager::IsDangerous(const DownloadItem& download, |
| 1127 const DownloadStateInfo& state, | 1113 const DownloadStateInfo& state, |
| 1128 bool visited_referrer_before) { | 1114 bool visited_referrer_before) { |
| 1129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1130 | 1116 |
| 1131 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path); | 1117 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path); |
| 1132 download_util::DownloadDangerLevel danger_level = | 1118 download_util::DownloadDangerLevel danger_level = |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 << " download = " << download->DebugString(true); | 1159 << " download = " << download->DebugString(true); |
| 1174 } | 1160 } |
| 1175 NotifyModelChanged(); | 1161 NotifyModelChanged(); |
| 1176 CheckForHistoryFilesRemoval(); | 1162 CheckForHistoryFilesRemoval(); |
| 1177 } | 1163 } |
| 1178 | 1164 |
| 1179 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, | 1165 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, |
| 1180 int64 db_handle) { | 1166 int64 db_handle) { |
| 1181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1182 | 1168 |
| 1169 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
| 1170 << " download = " << download->DebugString(false); |
| 1171 |
| 1183 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 1172 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
| 1184 // call this function with an invalid |db_handle|. For instance, this can | 1173 // call this function with an invalid |db_handle|. For instance, this can |
| 1185 // happen when the history database is offline. We cannot have multiple | 1174 // happen when the history database is offline. We cannot have multiple |
| 1186 // DownloadItems with the same invalid db_handle, so we need to assign a | 1175 // DownloadItems with the same invalid db_handle, so we need to assign a |
| 1187 // unique |db_handle| here. | 1176 // unique |db_handle| here. |
| 1188 if (db_handle == DownloadHistory::kUninitializedHandle) | 1177 if (db_handle == DownloadHistory::kUninitializedHandle) |
| 1189 db_handle = download_history_->GetNextFakeDbHandle(); | 1178 db_handle = download_history_->GetNextFakeDbHandle(); |
| 1190 | 1179 |
| 1180 // We shouldn't be here if the download is no longer in progress. |
| 1191 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 | 1181 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 |
| 1192 // is fixed. | 1182 // is fixed. |
| 1193 CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle); | 1183 CHECK(download->IsInProgress()); |
| 1194 | 1184 |
| 1195 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); | 1185 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); |
| 1196 download->set_db_handle(db_handle); | 1186 download->set_db_handle(db_handle); |
| 1197 | 1187 |
| 1198 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); | 1188 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 1199 history_downloads_[download->db_handle()] = download; | 1189 history_downloads_[download->db_handle()] = download; |
| 1200 } | 1190 } |
| 1201 | 1191 |
| 1202 // Once the new DownloadItem's creation info has been committed to the history | 1192 // Once the new DownloadItem's creation info has been committed to the history |
| 1203 // service, we associate the DownloadItem with the db handle, update our | 1193 // service, we associate the DownloadItem with the db handle, update our |
| 1204 // 'history_downloads_' map and inform observers. | 1194 // 'history_downloads_' map and inform observers. |
| 1205 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, | 1195 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, |
| 1206 int64 db_handle) { | 1196 int64 db_handle) { |
| 1207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1198 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
| 1199 << " download_id = " << download_id; |
| 1208 DownloadItem* download = GetActiveDownloadItem(download_id); | 1200 DownloadItem* download = GetActiveDownloadItem(download_id); |
| 1209 if (!download) | 1201 if (!download) { |
| 1202 // The download was cancelled while the history system was entering it. |
| 1203 // We resolve this race by turning around and deleting it in the |
| 1204 // history system (implicitly treating it as a failure in download |
| 1205 // initiation, which is appropriate as the only places the cancel could |
| 1206 // have come from were in resolving issues (like the file name) which |
| 1207 // we need to have resolved for history system insertion). |
| 1208 |
| 1209 // Make sure we haven't already been shutdown (the callback raced |
| 1210 // with shutdown), as that would mean that the history service has |
| 1211 // also been shutdown. In that case, the history will be cleaned up |
| 1212 // on next browser start. |
| 1213 if (download_history_.get()) |
| 1214 download_history_->RemoveEntry(db_handle); |
| 1210 return; | 1215 return; |
| 1211 | 1216 } |
| 1212 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle | |
| 1213 << " download_id = " << download_id | |
| 1214 << " download = " << download->DebugString(true); | |
| 1215 | 1217 |
| 1216 AddDownloadItemToHistory(download, db_handle); | 1218 AddDownloadItemToHistory(download, db_handle); |
| 1217 | 1219 |
| 1218 // Show in the appropriate browser UI. | 1220 // Show in the appropriate browser UI. |
| 1219 // This includes buttons to save or cancel, for a dangerous download. | 1221 // This includes buttons to save or cancel, for a dangerous download. |
| 1220 ShowDownloadInBrowser(download); | 1222 ShowDownloadInBrowser(download); |
| 1221 | 1223 |
| 1222 // Inform interested objects about the new download. | 1224 // Inform interested objects about the new download. |
| 1223 NotifyModelChanged(); | 1225 NotifyModelChanged(); |
| 1224 | 1226 |
| 1225 // If the download is still in progress, try to complete it. | 1227 MaybeCompleteDownload(download); |
| 1226 // | |
| 1227 // Otherwise, download has been cancelled or interrupted before we've | |
| 1228 // received the DB handle. We post one final message to the history | |
| 1229 // service so that it can be properly in sync with the DownloadItem's | |
| 1230 // completion status, and also inform any observers so that they get | |
| 1231 // more than just the start notification. | |
| 1232 if (download->IsInProgress()) { | |
| 1233 MaybeCompleteDownload(download); | |
| 1234 } else { | |
| 1235 DCHECK(download->IsCancelled()) | |
| 1236 << " download = " << download->DebugString(true); | |
| 1237 in_progress_.erase(download_id); | |
| 1238 active_downloads_.erase(download_id); | |
| 1239 download_history_->UpdateEntry(download); | |
| 1240 download->UpdateObservers(); | |
| 1241 } | |
| 1242 } | 1228 } |
| 1243 | 1229 |
| 1244 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { | 1230 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { |
| 1245 // The 'contents' may no longer exist if the user closed the tab before we | 1231 // The 'contents' may no longer exist if the user closed the tab before we |
| 1246 // get this start completion event. If it does, tell the origin TabContents | 1232 // get this start completion event. If it does, tell the origin TabContents |
| 1247 // to display its download shelf. | 1233 // to display its download shelf. |
| 1248 DownloadRequestHandle request_handle = download->request_handle(); | 1234 DownloadRequestHandle request_handle = download->request_handle(); |
| 1249 TabContents* content = request_handle.GetTabContents(); | 1235 TabContents* content = request_handle.GetTabContents(); |
| 1250 // If the contents no longer exists, we start the download in the last active | 1236 // If the contents no longer exists, we start the download in the last active |
| 1251 // browser. This is not ideal but better than fully hiding the download from | 1237 // browser. This is not ideal but better than fully hiding the download from |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1276 // not its id, so we have to iterate. | 1262 // not its id, so we have to iterate. |
| 1277 for (DownloadMap::iterator it = history_downloads_.begin(); | 1263 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 1278 it != history_downloads_.end(); ++it) { | 1264 it != history_downloads_.end(); ++it) { |
| 1279 DownloadItem* item = it->second; | 1265 DownloadItem* item = it->second; |
| 1280 if (item->id() == download_id) | 1266 if (item->id() == download_id) |
| 1281 return item; | 1267 return item; |
| 1282 } | 1268 } |
| 1283 return NULL; | 1269 return NULL; |
| 1284 } | 1270 } |
| 1285 | 1271 |
| 1272 void DownloadManager::GetInProgressDownloads( |
| 1273 std::vector<DownloadItem*>* result) { |
| 1274 DCHECK(result); |
| 1275 |
| 1276 for (DownloadMap::iterator it = active_downloads_.begin(); |
| 1277 it != active_downloads_.end(); ++it) { |
| 1278 result->push_back(it->second); |
| 1279 } |
| 1280 } |
| 1281 |
| 1286 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { | 1282 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { |
| 1287 DCHECK(ContainsKey(active_downloads_, download_id)); | 1283 DCHECK(ContainsKey(active_downloads_, download_id)); |
| 1288 DownloadItem* download = active_downloads_[download_id]; | 1284 DownloadItem* download = active_downloads_[download_id]; |
| 1289 DCHECK(download != NULL); | 1285 DCHECK(download != NULL); |
| 1290 return download; | 1286 return download; |
| 1291 } | 1287 } |
| 1292 | 1288 |
| 1293 // Confirm that everything in all maps is also in |downloads_|, and that | 1289 // Confirm that everything in all maps is also in |downloads_|, and that |
| 1294 // everything in |downloads_| is also in some other map. | 1290 // everything in |downloads_| is also in some other map. |
| 1295 void DownloadManager::AssertContainersConsistent() const { | 1291 void DownloadManager::AssertContainersConsistent() const { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 observed_download_manager_->RemoveObserver(this); | 1352 observed_download_manager_->RemoveObserver(this); |
| 1357 } | 1353 } |
| 1358 | 1354 |
| 1359 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { | 1355 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { |
| 1360 observing_download_manager_->NotifyModelChanged(); | 1356 observing_download_manager_->NotifyModelChanged(); |
| 1361 } | 1357 } |
| 1362 | 1358 |
| 1363 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { | 1359 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { |
| 1364 observed_download_manager_ = NULL; | 1360 observed_download_manager_ = NULL; |
| 1365 } | 1361 } |
| OLD | NEW |