Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: chrome/browser/download/download_manager.cc

Issue 7294013: Modified cancel and interrupt processing to avoid race with history. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporated comments, fixed some stuff from try jobs. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 // The user hasn't accepted it, so we need to remove it 99 // The user hasn't accepted it, so we need to remove it
100 // from the disk. This may or may not result in it being 100 // from the disk. This may or may not result in it being
101 // removed from the DownloadManager queues and deleted 101 // removed from the DownloadManager queues and deleted
102 // (specifically, DownloadManager::RemoveDownload only 102 // (specifically, DownloadManager::RemoveDownload only
103 // removes and deletes it if it's known to the history service) 103 // removes and deletes it if it's known to the history service)
104 // so the only thing we know after calling this function is that 104 // so the only thing we know after calling this function is that
105 // the download was deleted if-and-only-if it was removed 105 // the download was deleted if-and-only-if it was removed
106 // from all queues. 106 // from all queues.
107 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); 107 download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN);
108 } else if (download->IsPartialDownload()) { 108 } else if (download->IsPartialDownload()) {
109 download->Cancel(false); 109 download->Cancel();
110 download_history_->UpdateEntry(download);
111 } 110 }
112 } 111 }
113 112
114 // At this point, all dangerous downloads have had their files removed 113 // At this point, all dangerous downloads have had their files removed
115 // and all in progress downloads have been cancelled. We can now delete 114 // and all in progress downloads have been cancelled. We can now delete
116 // anything left. 115 // anything left.
117 116
118 // Copy downloads_ to separate container so as not to set off checks 117 // Copy downloads_ to separate container so as not to set off checks
119 // in DownloadItem destruction. 118 // in DownloadItem destruction.
120 DownloadSet downloads_to_delete; 119 DownloadSet downloads_to_delete;
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1, 636 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
638 // and Safari 5.0.4 - treat the download as complete in this case, so we 637 // and Safari 5.0.4 - treat the download as complete in this case, so we
639 // follow their lead. 638 // follow their lead.
640 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) { 639 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) {
641 OnAllDataSaved(download_id, size, hash); 640 OnAllDataSaved(download_id, size, hash);
642 } else { 641 } else {
643 OnDownloadError(download_id, size, os_error); 642 OnDownloadError(download_id, size, os_error);
644 } 643 }
645 } 644 }
646 645
646 void DownloadManager::CancelDownload(int32 download_id) {
647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
648 DownloadMap::iterator it = active_downloads_.find(download_id);
649 if (it == active_downloads_.end())
650 return;
651
652 it->second->Cancel();
653 }
654
647 void DownloadManager::OnAllDataSaved(int32 download_id, 655 void DownloadManager::OnAllDataSaved(int32 download_id,
648 int64 size, 656 int64 size,
649 const std::string& hash) { 657 const std::string& hash) {
650 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 658 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
651 << " size = " << size; 659 << " size = " << size;
652 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
653 661
654 // If it's not in active_downloads_, that means it was cancelled; just 662 // If it's not in active_downloads_, that means it was cancelled; just
655 // ignore the notification. 663 // ignore the notification.
656 if (active_downloads_.count(download_id) == 0) 664 if (active_downloads_.count(download_id) == 0)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 // TODO(rdsmith): Somewhat painful; make sure to disable in 719 // TODO(rdsmith): Somewhat painful; make sure to disable in
712 // release builds after resolution of http://crbug.com/85408. 720 // release builds after resolution of http://crbug.com/85408.
713 for (DownloadMap::iterator it = history_downloads_.begin(); 721 for (DownloadMap::iterator it = history_downloads_.begin();
714 it != history_downloads_.end(); ++it) { 722 it != history_downloads_.end(); ++it) {
715 CHECK(it->second != download); 723 CHECK(it->second != download);
716 } 724 }
717 } 725 }
718 726
719 CHECK(ContainsKey(active_downloads_, download->id()) == 727 CHECK(ContainsKey(active_downloads_, download->id()) ==
720 (download->state() == DownloadItem::IN_PROGRESS)); 728 (download->state() == DownloadItem::IN_PROGRESS));
721 CHECK(ContainsKey(in_progress_, download->id()) == 729 // Would check in_progress_, but removal from that queue happens
722 (download->state() == DownloadItem::IN_PROGRESS)); 730 // before transition from IN_PROGRESS for legacy reasons, so skipping.
723 } 731 }
724 732
725 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { 733 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) {
726 // If we don't have all the data, the download is not ready for 734 // If we don't have all the data, the download is not ready for
727 // completion. 735 // completion.
728 if (!download->all_data_saved()) 736 if (!download->all_data_saved())
729 return false; 737 return false;
730 738
731 // If the download is dangerous, but not yet validated, it's not ready for 739 // If the download is dangerous, but not yet validated, it's not ready for
732 // completion. 740 // completion.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 NewRunnableMethod( 817 NewRunnableMethod(
810 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); 818 file_manager_, &DownloadFileManager::CompleteDownload, download_id));
811 819
812 if (uniquifier) 820 if (uniquifier)
813 item->set_path_uniquifier(uniquifier); 821 item->set_path_uniquifier(uniquifier);
814 822
815 item->OnDownloadRenamedToFinalName(full_path); 823 item->OnDownloadRenamedToFinalName(full_path);
816 download_history_->UpdateDownloadPath(item, full_path); 824 download_history_->UpdateDownloadPath(item, full_path);
817 } 825 }
818 826
819 void DownloadManager::DownloadCancelled(int32 download_id) { 827 void DownloadManager::DownloadStopped(int32 download_id) {
820 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
821 DownloadMap::iterator it = in_progress_.find(download_id); 829 DownloadMap::iterator it = active_downloads_.find(download_id);
822 if (it == in_progress_.end()) 830 if (it == active_downloads_.end())
823 return; 831 return;
824 DownloadItem* download = it->second; 832 DownloadItem* download = it->second;
825 833
826 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 834 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
827 << " download = " << download->DebugString(true); 835 << " download = " << download->DebugString(true);
828 836
829 // Clean up will happen when the history system create callback runs if we 837 in_progress_.erase(download_id);
830 // don't have a valid db_handle yet. 838 active_downloads_.erase(download_id);
831 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { 839 UpdateAppIcon(); // Reflect removal from in_progress_.
832 in_progress_.erase(it);
833 active_downloads_.erase(download_id);
834 UpdateAppIcon(); // Reflect removal from in_progress_.
835 download_history_->UpdateEntry(download);
836 }
837 840
838 DownloadCancelledInternal(download_id, download->request_handle()); 841 // The history service should always outlive the DownloadManager.
839 } 842 download_history_->UpdateEntry(download);
840 843
841 void DownloadManager::DownloadCancelledInternal( 844 download->request_handle().CancelRequest();
842 int download_id, DownloadRequestHandle request_handle) {
843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
844 request_handle.CancelRequest();
845 845
846 // TODO(ahendrickson) - Remove this when we add resuming of interrupted
847 // downloads, as we will keep the download item around in that case.
846 BrowserThread::PostTask( 848 BrowserThread::PostTask(
847 BrowserThread::FILE, FROM_HERE, 849 BrowserThread::FILE, FROM_HERE,
848 NewRunnableMethod( 850 NewRunnableMethod(
849 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 851 file_manager_, &DownloadFileManager::CancelDownload, download_id));
850 } 852 }
851 853
852 void DownloadManager::OnDownloadError(int32 download_id, 854 void DownloadManager::OnDownloadError(int32 download_id,
853 int64 size, 855 int64 size,
854 int os_error) { 856 int os_error) {
855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 857 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
856 DownloadMap::iterator it = active_downloads_.find(download_id); 858 DownloadMap::iterator it = active_downloads_.find(download_id);
857 // A cancel at the right time could remove the download from the 859 // A cancel at the right time could remove the download from the
858 // |active_downloads_| map before we get here. 860 // |active_downloads_| map before we get here.
859 if (it == active_downloads_.end()) 861 if (it == active_downloads_.end())
860 return; 862 return;
861 863
862 DownloadItem* download = it->second; 864 DownloadItem* download = it->second;
863 865
864 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 866 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error
865 << " at offset " << download->received_bytes() 867 << " at offset " << download->received_bytes()
866 << " for download = " << download->DebugString(true); 868 << " for download = " << download->DebugString(true);
867 869
868 download->Interrupted(size, os_error); 870 download->Interrupt(size, os_error);
869
870 // TODO(ahendrickson) - Remove this when we add resuming of interrupted
871 // downloads, as we will keep the download item around in that case.
872 //
873 // Clean up will happen when the history system create callback runs if we
874 // don't have a valid db_handle yet.
875 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
876 in_progress_.erase(download_id);
877 active_downloads_.erase(download_id);
878 UpdateAppIcon(); // Reflect removal from in_progress_.
879 download_history_->UpdateEntry(download);
880 }
881
882 BrowserThread::PostTask(
883 BrowserThread::FILE, FROM_HERE,
884 NewRunnableMethod(
885 file_manager_, &DownloadFileManager::CancelDownload, download_id));
886 } 871 }
887 872
888 void DownloadManager::UpdateAppIcon() { 873 void DownloadManager::UpdateAppIcon() {
889 if (status_updater_) 874 if (status_updater_)
890 status_updater_->Update(); 875 status_updater_->Update();
891 } 876 }
892 877
893 void DownloadManager::RemoveDownload(int64 download_handle) { 878 void DownloadManager::RemoveDownload(DownloadItem* download) {
894 DownloadMap::iterator it = history_downloads_.find(download_handle); 879 // Silently ignores request if db handle indicates that the download
ahendrickson 2011/07/11 20:05:48 Add DCHECK(BrowserThread::CurrentlyOn(BrowserThre
Randy Smith (Not in Mondays) 2011/07/13 21:11:38 Done.
895 if (it == history_downloads_.end()) 880 // isn't in the history.
896 return; 881 download_history_->RemoveEntry(download->db_handle());
897
898 // Make history update.
899 DownloadItem* download = it->second;
900 download_history_->RemoveEntry(download);
901 882
902 // Remove from our tables and delete. 883 // Remove from our tables and delete.
903 history_downloads_.erase(it); 884 if (download->db_handle() != DownloadHistory::kUninitializedHandle)
885 history_downloads_.erase(download->db_handle());
904 int downloads_count = downloads_.erase(download); 886 int downloads_count = downloads_.erase(download);
905 DCHECK_EQ(1, downloads_count); 887 DCHECK_EQ(1, downloads_count);
906 888
907 // Tell observers to refresh their views. 889 // Tell observers to refresh their views.
908 NotifyModelChanged(); 890 NotifyModelChanged();
909 891
910 delete download; 892 delete download;
911 } 893 }
912 894
913 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, 895 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin,
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 int32 download_id = *id_ptr; 1084 int32 download_id = *id_ptr;
1103 delete id_ptr; 1085 delete id_ptr;
1104 1086
1105 DownloadItem* download = GetActiveDownloadItem(download_id); 1087 DownloadItem* download = GetActiveDownloadItem(download_id);
1106 if (!download) 1088 if (!download)
1107 return; 1089 return;
1108 1090
1109 VLOG(20) << __FUNCTION__ << "()" 1091 VLOG(20) << __FUNCTION__ << "()"
1110 << " download = " << download->DebugString(true); 1092 << " download = " << download->DebugString(true);
1111 1093
1112 DownloadCancelledInternal(download_id, download->request_handle()); 1094 download->Cancel();
1113 } 1095 }
1114 1096
1115 // TODO(phajdan.jr): This is apparently not being exercised in tests. 1097 // TODO(phajdan.jr): This is apparently not being exercised in tests.
1116 bool DownloadManager::IsDangerous(const DownloadItem& download, 1098 bool DownloadManager::IsDangerous(const DownloadItem& download,
1117 const DownloadStateInfo& state, 1099 const DownloadStateInfo& state,
1118 bool visited_referrer_before) { 1100 bool visited_referrer_before) {
1119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1120 1102
1121 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path); 1103 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path);
1122 download_util::DownloadDangerLevel danger_level = 1104 download_util::DownloadDangerLevel danger_level =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 VLOG(20) << __FUNCTION__ << "()" << i << ">" 1144 VLOG(20) << __FUNCTION__ << "()" << i << ">"
1163 << " download = " << download->DebugString(true); 1145 << " download = " << download->DebugString(true);
1164 } 1146 }
1165 NotifyModelChanged(); 1147 NotifyModelChanged();
1166 CheckForHistoryFilesRemoval(); 1148 CheckForHistoryFilesRemoval();
1167 } 1149 }
1168 1150
1169 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, 1151 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download,
1170 int64 db_handle) { 1152 int64 db_handle) {
1171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1154 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
1155 << " download = " << download->DebugString(false);
1172 1156
1173 // It's not immediately obvious, but HistoryBackend::CreateDownload() can 1157 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
1174 // call this function with an invalid |db_handle|. For instance, this can 1158 // call this function with an invalid |db_handle|. For instance, this can
1175 // happen when the history database is offline. We cannot have multiple 1159 // happen when the history database is offline. We cannot have multiple
1176 // DownloadItems with the same invalid db_handle, so we need to assign a 1160 // DownloadItems with the same invalid db_handle, so we need to assign a
1177 // unique |db_handle| here. 1161 // unique |db_handle| here.
1178 if (db_handle == DownloadHistory::kUninitializedHandle) 1162 if (db_handle == DownloadHistory::kUninitializedHandle)
1179 db_handle = download_history_->GetNextFakeDbHandle(); 1163 db_handle = download_history_->GetNextFakeDbHandle();
1180 1164
1165 // The download shouldn't have been returned from GetActiveDownloadItem()
1166 // if it's not in progress.
1181 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 1167 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508
1182 // is fixed. 1168 // is fixed.
1183 CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle); 1169 CHECK(download->IsInProgress());
1184 1170
1185 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); 1171 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
1186 download->set_db_handle(db_handle); 1172 download->set_db_handle(db_handle);
1187 1173
1188 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); 1174 DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
1189 history_downloads_[download->db_handle()] = download; 1175 history_downloads_[download->db_handle()] = download;
1190 } 1176 }
1191 1177
1192 // Once the new DownloadItem's creation info has been committed to the history 1178 // Once the new DownloadItem's creation info has been committed to the history
1193 // service, we associate the DownloadItem with the db handle, update our 1179 // service, we associate the DownloadItem with the db handle, update our
1194 // 'history_downloads_' map and inform observers. 1180 // 'history_downloads_' map and inform observers.
1195 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, 1181 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
1196 int64 db_handle) { 1182 int64 db_handle) {
1197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1184 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
1185 << " download_id = " << download_id;
1198 DownloadItem* download = GetActiveDownloadItem(download_id); 1186 DownloadItem* download = GetActiveDownloadItem(download_id);
1199 if (!download) 1187 if (!download) {
1188 // The download was cancelled while the history system was entering it.
1189 // We resolve this race by turning around and deleting it in the
1190 // history system (implicitly treating it as a failure in download
1191 // initiation, which is appropriate as the only places the cancel could
1192 // have come from were in resolving issues (like the file name) which
1193 // we need to have resolved for history system insertion).
1194
1195 // Make sure we haven't already been shutdown (the callback raced
1196 // with shutdown), as that would mean that the history service has
1197 // also been shutdown. In that case, the history will be cleaned up
1198 // on next browser start.
1199 if (download_history_.get())
1200 download_history_->RemoveEntry(db_handle);
1200 return; 1201 return;
1201 1202 }
1202 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
1203 << " download_id = " << download_id
1204 << " download = " << download->DebugString(true);
1205 1203
1206 AddDownloadItemToHistory(download, db_handle); 1204 AddDownloadItemToHistory(download, db_handle);
1207 1205
1208 // Show in the appropriate browser UI. 1206 // Show in the appropriate browser UI.
1209 // This includes buttons to save or cancel, for a dangerous download. 1207 // This includes buttons to save or cancel, for a dangerous download.
1210 ShowDownloadInBrowser(download); 1208 ShowDownloadInBrowser(download);
1211 1209
1212 // Inform interested objects about the new download. 1210 // Inform interested objects about the new download.
1213 NotifyModelChanged(); 1211 NotifyModelChanged();
1214 1212
1215 // If the download is still in progress, try to complete it. 1213 MaybeCompleteDownload(download);
1216 //
1217 // Otherwise, download has been cancelled or interrupted before we've
1218 // received the DB handle. We post one final message to the history
1219 // service so that it can be properly in sync with the DownloadItem's
1220 // completion status, and also inform any observers so that they get
1221 // more than just the start notification.
1222 if (download->IsInProgress()) {
1223 MaybeCompleteDownload(download);
1224 } else {
1225 DCHECK(download->IsCancelled())
1226 << " download = " << download->DebugString(true);
1227 in_progress_.erase(download_id);
1228 active_downloads_.erase(download_id);
1229 download_history_->UpdateEntry(download);
1230 download->UpdateObservers();
1231 }
1232 } 1214 }
1233 1215
1234 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { 1216 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) {
1235 // The 'contents' may no longer exist if the user closed the tab before we 1217 // The 'contents' may no longer exist if the user closed the tab before we
1236 // get this start completion event. If it does, tell the origin TabContents 1218 // get this start completion event. If it does, tell the origin TabContents
1237 // to display its download shelf. 1219 // to display its download shelf.
1238 DownloadRequestHandle request_handle = download->request_handle(); 1220 DownloadRequestHandle request_handle = download->request_handle();
1239 TabContents* contents = request_handle.GetTabContents(); 1221 TabContents* contents = request_handle.GetTabContents();
1240 TabContentsWrapper* wrapper = NULL; 1222 TabContentsWrapper* wrapper = NULL;
1241 if (contents) 1223 if (contents)
(...skipping 28 matching lines...) Expand all
1270 // not its id, so we have to iterate. 1252 // not its id, so we have to iterate.
1271 for (DownloadMap::iterator it = history_downloads_.begin(); 1253 for (DownloadMap::iterator it = history_downloads_.begin();
1272 it != history_downloads_.end(); ++it) { 1254 it != history_downloads_.end(); ++it) {
1273 DownloadItem* item = it->second; 1255 DownloadItem* item = it->second;
1274 if (item->id() == download_id) 1256 if (item->id() == download_id)
1275 return item; 1257 return item;
1276 } 1258 }
1277 return NULL; 1259 return NULL;
1278 } 1260 }
1279 1261
1262 void DownloadManager::GetInProgressDownloads(
1263 std::vector<DownloadItem*>* result) {
1264 DCHECK(result);
1265
1266 for (DownloadMap::iterator it = active_downloads_.begin();
1267 it != active_downloads_.end(); ++it) {
1268 result->push_back(it->second);
1269 }
1270 }
1271
1280 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { 1272 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) {
1281 DCHECK(ContainsKey(active_downloads_, download_id)); 1273 DCHECK(ContainsKey(active_downloads_, download_id));
1282 DownloadItem* download = active_downloads_[download_id]; 1274 DownloadItem* download = active_downloads_[download_id];
1283 DCHECK(download != NULL); 1275 DCHECK(download != NULL);
1284 return download; 1276 return download;
1285 } 1277 }
1286 1278
1287 // Confirm that everything in all maps is also in |downloads_|, and that 1279 // Confirm that everything in all maps is also in |downloads_|, and that
1288 // everything in |downloads_| is also in some other map. 1280 // everything in |downloads_| is also in some other map.
1289 void DownloadManager::AssertContainersConsistent() const { 1281 void DownloadManager::AssertContainersConsistent() const {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 observed_download_manager_->RemoveObserver(this); 1342 observed_download_manager_->RemoveObserver(this);
1351 } 1343 }
1352 1344
1353 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { 1345 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() {
1354 observing_download_manager_->NotifyModelChanged(); 1346 observing_download_manager_->NotifyModelChanged();
1355 } 1347 }
1356 1348
1357 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1349 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1358 observed_download_manager_ = NULL; 1350 observed_download_manager_ = NULL;
1359 } 1351 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698