| Index: chrome/browser/download/download_manager.cc
|
| diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
|
| index 10ac74e7b06aeef486bf84de64defb6bde68d892..a6857c2c91115bc14a5e3b14b8e7c484428ed46c 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 handle indicates that the download
|
| + // 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,9 +1163,33 @@ 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 it as a failure in download
|
| + // 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.
|
| +
|
| + // 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
|
| + // on next browser startup.
|
| + 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.
|
| // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508
|
| // is fixed.
|
| - CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle);
|
| + CHECK(download->IsInProgress());
|
|
|
| DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
|
| download->set_db_handle(db_handle);
|
| @@ -1202,23 +1204,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) {
|
| @@ -1268,6 +1254,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];
|
|
|