Index: chrome/browser/download/download_manager.cc |
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc |
index 26a58bede0001edf11ab5441d78ef1998ead02e4..3b03e4524901960091663439599d3991d0cc862c 100644 |
--- a/chrome/browser/download/download_manager.cc |
+++ b/chrome/browser/download/download_manager.cc |
@@ -106,8 +106,7 @@ void DownloadManager::Shutdown() { |
// from all queues. |
download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN); |
} else if (download->IsPartialDownload()) { |
- download->Cancel(false); |
- download_history_->UpdateEntry(download); |
+ download->Cancel(); |
} |
} |
@@ -644,6 +643,15 @@ void DownloadManager::OnResponseCompleted(int32 download_id, |
} |
} |
+void DownloadManager::CancelDownload(int32 download_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DownloadMap::iterator it = active_downloads_.find(download_id); |
+ if (it == active_downloads_.end()) |
+ return; |
+ |
+ it->second->Cancel(); |
+} |
+ |
void DownloadManager::OnAllDataSaved(int32 download_id, |
int64 size, |
const std::string& hash) { |
@@ -718,8 +726,8 @@ void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) { |
CHECK(ContainsKey(active_downloads_, download->id()) == |
(download->state() == DownloadItem::IN_PROGRESS)); |
- CHECK(ContainsKey(in_progress_, download->id()) == |
- (download->state() == DownloadItem::IN_PROGRESS)); |
+ // Would check in_progress_, but removal from that queue happens |
+ // before transition from IN_PROGRESS for legacy reasons, so skipping. |
} |
bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { |
@@ -816,33 +824,27 @@ void DownloadManager::OnDownloadRenamedToFinalName(int download_id, |
download_history_->UpdateDownloadPath(item, full_path); |
} |
-void DownloadManager::DownloadCancelled(int32 download_id) { |
+void DownloadManager::DownloadStopped(int32 download_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DownloadMap::iterator it = in_progress_.find(download_id); |
- if (it == in_progress_.end()) |
+ DownloadMap::iterator it = active_downloads_.find(download_id); |
+ if (it == active_downloads_.end()) |
return; |
DownloadItem* download = it->second; |
VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
<< " download = " << download->DebugString(true); |
- // Clean up will happen when the history system create callback runs if we |
- // don't have a valid db_handle yet. |
- if (download->db_handle() != DownloadHistory::kUninitializedHandle) { |
- in_progress_.erase(it); |
- active_downloads_.erase(download_id); |
- UpdateAppIcon(); // Reflect removal from in_progress_. |
- download_history_->UpdateEntry(download); |
- } |
+ in_progress_.erase(download_id); |
+ active_downloads_.erase(download_id); |
+ UpdateAppIcon(); // Reflect removal from in_progress_. |
- DownloadCancelledInternal(download_id, download->request_handle()); |
-} |
+ // The history service should always outlive the DownloadManager. |
+ download_history_->UpdateEntry(download); |
-void DownloadManager::DownloadCancelledInternal( |
- int download_id, DownloadRequestHandle request_handle) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- request_handle.CancelRequest(); |
+ download->request_handle().CancelRequest(); |
+ // TODO(ahendrickson) - Remove this when we add resuming of interrupted |
+ // downloads, as we will keep the download item around in that case. |
BrowserThread::PostTask( |
BrowserThread::FILE, FROM_HERE, |
NewRunnableMethod( |
@@ -865,24 +867,7 @@ void DownloadManager::OnDownloadError(int32 download_id, |
<< " at offset " << download->received_bytes() |
<< " for download = " << download->DebugString(true); |
- download->Interrupted(size, os_error); |
- |
- // TODO(ahendrickson) - Remove this when we add resuming of interrupted |
- // downloads, as we will keep the download item around in that case. |
- // |
- // Clean up will happen when the history system create callback runs if we |
- // don't have a valid db_handle yet. |
- if (download->db_handle() != DownloadHistory::kUninitializedHandle) { |
- in_progress_.erase(download_id); |
- active_downloads_.erase(download_id); |
- UpdateAppIcon(); // Reflect removal from in_progress_. |
- download_history_->UpdateEntry(download); |
- } |
- |
- BrowserThread::PostTask( |
- BrowserThread::FILE, FROM_HERE, |
- NewRunnableMethod( |
- file_manager_, &DownloadFileManager::CancelDownload, download_id)); |
+ download->Interrupt(size, os_error); |
} |
void DownloadManager::UpdateAppIcon() { |
@@ -890,17 +875,14 @@ void DownloadManager::UpdateAppIcon() { |
status_updater_->Update(); |
} |
-void DownloadManager::RemoveDownload(int64 download_handle) { |
- DownloadMap::iterator it = history_downloads_.find(download_handle); |
- if (it == history_downloads_.end()) |
- return; |
- |
- // Make history update. |
- DownloadItem* download = it->second; |
- download_history_->RemoveEntry(download); |
+void DownloadManager::RemoveDownload(DownloadItem* download) { |
+ // Silently ignores request if db handled indicates that the download |
Randy Smith (Not in Mondays)
2011/06/30 23:05:13
"handled" -> "handle"
Randy Smith (Not in Mondays)
2011/07/05 20:28:44
Done.
|
+ // isn't in the history. |
+ download_history_->RemoveEntry(download->db_handle()); |
// Remove from our tables and delete. |
- history_downloads_.erase(it); |
+ if (download->db_handle() != DownloadHistory::kUninitializedHandle) |
+ history_downloads_.erase(download->db_handle()); |
int downloads_count = downloads_.erase(download); |
DCHECK_EQ(1, downloads_count); |
@@ -1106,7 +1088,7 @@ void DownloadManager::FileSelectionCanceled(void* params) { |
VLOG(20) << __FUNCTION__ << "()" |
<< " download = " << download->DebugString(true); |
- DownloadCancelledInternal(download_id, download->request_handle()); |
+ download->Cancel(); |
} |
// TODO(phajdan.jr): This is apparently not being exercised in tests. |
@@ -1169,13 +1151,9 @@ void DownloadManager::OnQueryDownloadEntriesComplete( |
void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, |
int64 db_handle) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DownloadItem* download = GetActiveDownloadItem(download_id); |
- if (!download) |
- return; |
VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
- << " download_id = " << download_id |
- << " download = " << download->DebugString(true); |
+ << " download_id = " << download_id; |
// It's not immediately obvious, but HistoryBackend::CreateDownload() can |
// call this function with an invalid |db_handle|. For instance, this can |
@@ -1185,6 +1163,32 @@ void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, |
if (db_handle == DownloadHistory::kUninitializedHandle) |
db_handle = download_history_->GetNextFakeDbHandle(); |
+ DownloadItem* download = GetActiveDownloadItem(download_id); |
+ if (!download) { |
+ // The download was cancelled while the history system was entering it. |
+ // We resolve this race by turning around and deleting it in the |
+ // history system (implicitly treating is as a failure in download |
Randy Smith (Not in Mondays)
2011/06/30 23:05:13
"is" -> "it"
Randy Smith (Not in Mondays)
2011/07/05 20:28:44
Done.
|
+ // initiation, which is appropriate as the only places the cancel could |
+ // have come from were in resolving issues (like the file name) which |
+ // we need to have resolved for history system insertion. |
Randy Smith (Not in Mondays)
2011/06/30 23:05:13
Not quite true--could have come from FileSelection
Randy Smith (Not in Mondays)
2011/07/05 20:28:44
FileSelectionCancelled is part of resolving the fi
|
+ |
+ // Make sure we haven't already been shutdown (the callback raced |
+ // with shutdown), as that would mean that the history service has |
+ // also been shutdown. In that case, the history will be fixed up |
+ // when it's next read in. |
Randy Smith (Not in Mondays)
2011/06/30 23:05:13
"on next browser startup".
Randy Smith (Not in Mondays)
2011/07/05 20:28:44
Done.
|
+ if (download_history_.get()) |
+ download_history_->RemoveEntry(db_handle); |
+ return; |
+ } |
+ |
+ VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
+ << " download_id = " << download_id |
+ << " download = " << download->DebugString(true); |
+ |
+ // The download shouldn't have been returned from GetActiveDownloadItem() |
+ // if it's not in progress. |
+ DCHECK(download->IsInProgress()); |
+ |
DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); |
download->set_db_handle(db_handle); |
@@ -1198,23 +1202,7 @@ void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, |
// Inform interested objects about the new download. |
NotifyModelChanged(); |
- // If the download is still in progress, try to complete it. |
- // |
- // Otherwise, download has been cancelled or interrupted before we've |
- // received the DB handle. We post one final message to the history |
- // service so that it can be properly in sync with the DownloadItem's |
- // completion status, and also inform any observers so that they get |
- // more than just the start notification. |
- if (download->IsInProgress()) { |
- MaybeCompleteDownload(download); |
- } else { |
- DCHECK(download->IsCancelled()) |
- << " download = " << download->DebugString(true); |
- in_progress_.erase(download_id); |
- active_downloads_.erase(download_id); |
- download_history_->UpdateEntry(download); |
- download->UpdateObservers(); |
- } |
+ MaybeCompleteDownload(download); |
} |
void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { |
@@ -1264,6 +1252,16 @@ DownloadItem* DownloadManager::GetDownloadItem(int download_id) { |
return NULL; |
} |
+void DownloadManager::GetInProgressDownloads( |
+ std::vector<DownloadItem*>* result) { |
+ DCHECK(result); |
+ |
+ for (DownloadMap::iterator it = active_downloads_.begin(); |
+ it != active_downloads_.end(); ++it) { |
+ result->push_back(it->second); |
+ } |
+} |
+ |
DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { |
DCHECK(ContainsKey(active_downloads_, download_id)); |
DownloadItem* download = active_downloads_[download_id]; |