| Index: content/browser/download/download_manager_impl.cc
|
| diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
|
| index e0f441b949876d3d7db5aa3a5d29779ef988bc24..f742c7c0cd238f0a431b8c6b5de7909c3e9fe7e4 100644
|
| --- a/content/browser/download/download_manager_impl.cc
|
| +++ b/content/browser/download/download_manager_impl.cc
|
| @@ -51,6 +51,28 @@ using content::WebContents;
|
|
|
| namespace {
|
|
|
| +// This is just used to remember which DownloadItems come from SavePage.
|
| +class SavePageExternalData : public DownloadItem::ExternalData {
|
| + public:
|
| + // A spoonful of syntactic sugar.
|
| + static bool Get(DownloadItem* item) {
|
| + return item->GetExternalData(kKey) != NULL;
|
| + }
|
| +
|
| + explicit SavePageExternalData(DownloadItem* item) {
|
| + item->SetExternalData(kKey, this);
|
| + }
|
| +
|
| + virtual ~SavePageExternalData() {}
|
| +
|
| + private:
|
| + static const char kKey[];
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SavePageExternalData);
|
| +};
|
| +
|
| +const char SavePageExternalData::kKey[] = "DownloadItem SavePageExternalData";
|
| +
|
| void BeginDownload(content::DownloadUrlParameters* params) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and
|
| @@ -306,8 +328,6 @@ void DownloadManagerImpl::Shutdown() {
|
| // We'll have nothing more to report to the observers after this point.
|
| observers_.Clear();
|
|
|
| - DCHECK(save_page_downloads_.empty());
|
| -
|
| file_manager_ = NULL;
|
| if (delegate_)
|
| delegate_->Shutdown();
|
| @@ -540,8 +560,9 @@ DownloadItem* DownloadManagerImpl::CreateSavePackageDownloadItem(
|
|
|
| DCHECK(!ContainsKey(downloads_, download->GetId()));
|
| downloads_[download->GetId()] = download;
|
| - DCHECK(!ContainsKey(save_page_downloads_, download->GetId()));
|
| - save_page_downloads_[download->GetId()] = download;
|
| + DCHECK(!SavePageExternalData::Get(download));
|
| + new SavePageExternalData(download);
|
| + DCHECK(SavePageExternalData::Get(download));
|
|
|
| // Will notify the observer in the callback.
|
| if (delegate_)
|
| @@ -804,7 +825,6 @@ int DownloadManagerImpl::RemoveDownloadItems(
|
| ++it) {
|
| DownloadItem* download = *it;
|
| DCHECK(download);
|
| - save_page_downloads_.erase(download->GetId());
|
| downloads_.erase(download->GetId());
|
| }
|
|
|
| @@ -975,12 +995,16 @@ void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItem* download,
|
|
|
| void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
|
| int64 db_handle) {
|
| - if (save_page_downloads_.count(download_id)) {
|
| - OnSavePageItemAddedToPersistentStore(download_id, db_handle);
|
| - } else if (active_downloads_.count(download_id)) {
|
| - OnDownloadItemAddedToPersistentStore(download_id, db_handle);
|
| - }
|
| + DownloadItem* item = GetDownload(download_id);
|
| // It's valid that we don't find a matching item, i.e. on shutdown.
|
| + if (!item)
|
| + return;
|
| + AddDownloadItemToHistory(item, db_handle);
|
| + if (SavePageExternalData::Get(item)) {
|
| + OnSavePageItemAddedToPersistentStore(item);
|
| + } else {
|
| + OnDownloadItemAddedToPersistentStore(item);
|
| + }
|
| }
|
|
|
| // Once the new DownloadItem has been committed to the persistent store,
|
| @@ -990,17 +1014,12 @@ void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
|
| // item when it's created so they can observe it directly. Are there any
|
| // clients that actually need to know when the item is added to the history?).
|
| void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore(
|
| - int32 download_id, int64 db_handle) {
|
| + DownloadItem* item) {
|
| 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);
|
| -
|
| - AddDownloadItemToHistory(download, db_handle);
|
| + VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << item->GetDbHandle()
|
| + << " download_id = " << item->GetId()
|
| + << " download = " << item->DebugString(true);
|
|
|
| // If the download is still in progress, try to complete it.
|
| //
|
| @@ -1009,14 +1028,14 @@ void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore(
|
| // 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);
|
| + if (item->IsInProgress()) {
|
| + MaybeCompleteDownload(item);
|
| } else {
|
| - DCHECK(download->IsCancelled());
|
| - active_downloads_.erase(download_id);
|
| + DCHECK(item->IsCancelled());
|
| + active_downloads_.erase(item->GetId());
|
| if (delegate_)
|
| - delegate_->UpdateItemInPersistentStore(download);
|
| - download->UpdateObservers();
|
| + delegate_->UpdateItemInPersistentStore(item);
|
| + item->UpdateObservers();
|
| }
|
| }
|
|
|
| @@ -1077,10 +1096,9 @@ DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) {
|
| void DownloadManagerImpl::AssertContainersConsistent() const {
|
| #if !defined(NDEBUG)
|
| // Turn everything into sets.
|
| - const DownloadMap* input_maps[] = {&active_downloads_,
|
| - &save_page_downloads_};
|
| - DownloadSet active_set, save_page_set;
|
| - DownloadSet* all_sets[] = {&active_set, &save_page_set};
|
| + const DownloadMap* input_maps[] = {&active_downloads_};
|
| + DownloadSet active_set;
|
| + DownloadSet* all_sets[] = {&active_set};
|
| DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets));
|
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) {
|
| for (DownloadMap::const_iterator it = input_maps[i]->begin();
|
| @@ -1122,35 +1140,18 @@ void DownloadManagerImpl::AssertContainersConsistent() const {
|
| // to solve that without canceling on Remove (which would then update the DB).
|
|
|
| void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore(
|
| - int32 download_id, int64 db_handle) {
|
| + DownloadItem* item) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| - DownloadMap::const_iterator it = save_page_downloads_.find(download_id);
|
| - // This can happen if the download manager is shutting down and all maps
|
| - // have been cleared.
|
| - if (it == save_page_downloads_.end())
|
| - return;
|
| -
|
| - DownloadItem* download = it->second;
|
| - if (!download) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - AddDownloadItemToHistory(download, db_handle);
|
| -
|
| // Finalize this download if it finished before the history callback.
|
| - if (!download->IsInProgress())
|
| - SavePageDownloadFinished(download);
|
| + if (!item->IsInProgress())
|
| + SavePageDownloadFinished(item);
|
| }
|
|
|
| void DownloadManagerImpl::SavePageDownloadFinished(DownloadItem* download) {
|
| if (download->IsPersisted()) {
|
| if (delegate_)
|
| delegate_->UpdateItemInPersistentStore(download);
|
| - DCHECK(ContainsKey(save_page_downloads_, download->GetId()));
|
| - save_page_downloads_.erase(download->GetId());
|
| -
|
| if (download->IsComplete())
|
| content::NotificationService::current()->Notify(
|
| content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
|
|
|