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

Unified Diff: content/browser/download/download_manager_impl.cc

Issue 10665049: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 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 side-by-side diff with in-line comments
Download patch
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 c1e983e7d4e310ce3406ac075ecb612c23c9110e..605a58c1353677f13570cef8ee49e2ad7b33d09c 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -52,26 +52,26 @@ using content::WebContents;
namespace {
// This is just used to remember which DownloadItems come from SavePage.
-class SavePageExternalData : public DownloadItem::ExternalData {
+class SavePageData : public base::SupportsUserData::Data {
public:
// A spoonful of syntactic sugar.
static bool Get(DownloadItem* item) {
- return item->GetExternalData(kKey) != NULL;
+ return item->GetUserData(kKey) != NULL;
}
- explicit SavePageExternalData(DownloadItem* item) {
- item->SetExternalData(kKey, this);
+ explicit SavePageData(DownloadItem* item) {
+ item->SetUserData(kKey, this);
}
- virtual ~SavePageExternalData() {}
+ virtual ~SavePageData() {}
private:
static const char kKey[];
- DISALLOW_COPY_AND_ASSIGN(SavePageExternalData);
+ DISALLOW_COPY_AND_ASSIGN(SavePageData);
};
-const char SavePageExternalData::kKey[] = "DownloadItem SavePageExternalData";
+const char SavePageData::kKey[] = "DownloadItem SavePageData";
void BeginDownload(content::DownloadUrlParameters* params) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -312,8 +312,6 @@ void DownloadManagerImpl::Shutdown() {
download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN);
} else if (download->IsPartialDownload()) {
download->Cancel(false);
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
}
}
@@ -321,13 +319,9 @@ void DownloadManagerImpl::Shutdown() {
// and all in progress downloads have been cancelled. We can now delete
// anything left.
- // Copy downloads_ to separate container so as not to set off checks
- // in DownloadItem destruction.
- DownloadMap downloads_to_delete;
- downloads_to_delete.swap(downloads_);
-
active_downloads_.clear();
- STLDeleteValues(&downloads_to_delete);
+ STLDeleteValues(&downloads_);
+ downloads_.clear();
// We'll have nothing more to report to the observers after this point.
observers_.Clear();
@@ -345,9 +339,7 @@ void DownloadManagerImpl::GetTemporaryDownloads(
for (DownloadMap::iterator it = downloads_.begin();
it != downloads_.end(); ++it) {
DownloadItemImpl* item = it->second;
- // TODO(benjhayden): Don't check IsPersisted().
if (item->IsTemporary() &&
- item->IsPersisted() &&
(dir_path.empty() ||
item->GetTargetFilePath().DirName() == dir_path))
result->push_back(item);
@@ -361,9 +353,7 @@ void DownloadManagerImpl::GetAllDownloads(
for (DownloadMap::iterator it = downloads_.begin();
it != downloads_.end(); ++it) {
DownloadItemImpl* item = it->second;
- // TODO(benjhayden): Don't check IsPersisted().
if (!item->IsTemporary() &&
- item->IsPersisted() &&
(dir_path.empty() ||
item->GetTargetFilePath().DirName() == dir_path))
result->push_back(item);
@@ -380,9 +370,7 @@ void DownloadManagerImpl::SearchDownloads(const string16& query,
// Display Incognito downloads only in Incognito window, and vice versa.
// The Incognito Downloads page will get the list of non-Incognito downloads
// from its parent profile.
- // TODO(benjhayden): Don't check IsPersisted().
if (!download_item->IsTemporary() &&
- download_item->IsPersisted() &&
(browser_context_->IsOffTheRecord() == download_item->IsOtr()) &&
download_item->MatchesQuery(query_lower)) {
result->push_back(download_item);
@@ -468,13 +456,20 @@ void DownloadManagerImpl::OnDownloadTargetDetermined(
content::DownloadDangerType danger_type,
const FilePath& intermediate_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadMap::iterator download_iter = active_downloads_.find(download_id);
- if (download_iter != active_downloads_.end()) {
- // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a
- // DownloadRenamedToIntermediateName() callback. This is necessary for the
- // download to proceed.
- download_iter->second->OnDownloadTargetDetermined(
- target_path, disposition, danger_type, intermediate_path);
+ DownloadMap::iterator download_iter = downloads_.find(download_id);
+ if (download_iter == downloads_.end())
+ return;
+
+ // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a
+ // DownloadRenamedToIntermediateName() callback. This is necessary for the
+ // download to proceed.
+ DownloadItemImpl* item = download_iter->second;
+ item->OnDownloadTargetDetermined(
+ target_path, disposition, danger_type, intermediate_path);
+ ShowDownloadInBrowser(item);
+ NotifyModelChanged();
+ if (!SavePageData::Get(item)) {
+ MaybeCompleteDownload(item);
}
}
@@ -483,8 +478,7 @@ void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
for (DownloadMap::iterator it = downloads_.begin();
it != downloads_.end(); ++it) {
DownloadItemImpl* item = it->second;
- if (item->IsPersisted())
- CheckForFileRemoval(item);
+ CheckForFileRemoval(item);
}
}
@@ -553,7 +547,7 @@ DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
DownloadItem::Observer* observer) {
net::BoundNetLog bound_net_log =
net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
- DownloadItemImpl* download = factory_->CreateSavePageItem(
+ DownloadItemImpl* download_item = factory_->CreateSavePageItem(
this,
main_file_path,
page_url,
@@ -561,24 +555,16 @@ DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
GetNextId(),
mime_type,
bound_net_log);
-
- download->AddObserver(observer);
-
- DCHECK(!ContainsKey(downloads_, download->GetId()));
- downloads_[download->GetId()] = download;
- DCHECK(!SavePageExternalData::Get(download));
- new SavePageExternalData(download);
- DCHECK(SavePageExternalData::Get(download));
-
- // TODO(benjhayden): Fire OnDownloadCreated for SavePackage downloads when
- // we're comfortable with the user interacting with them.
- // FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
-
- // Will notify the observer in the callback.
- if (delegate_)
- delegate_->AddItemToPersistentStore(download);
-
- return download;
+ download_item->AddObserver(observer);
+ DCHECK(!ContainsKey(downloads_, download_item->GetId()));
+ downloads_[download_item->GetId()] = download_item;
+ DCHECK(!SavePageData::Get(download_item));
+ new SavePageData(download_item);
+ DCHECK(SavePageData::Get(download_item));
+ // TODO(benjhayden) XXX occam test showing SavePackage DownloadItems in ui
+ FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(
+ this, download_item));
+ return download_item;
}
void DownloadManagerImpl::UpdateDownload(int32 download_id,
@@ -591,8 +577,6 @@ void DownloadManagerImpl::UpdateDownload(int32 download_id,
DownloadItemImpl* download = it->second;
if (download->IsInProgress()) {
download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state);
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
}
}
}
@@ -617,23 +601,10 @@ void DownloadManagerImpl::OnResponseCompleted(int32 download_id,
void DownloadManagerImpl::AssertStateConsistent(
DownloadItemImpl* download) const {
- if (download->GetState() == DownloadItem::REMOVING) {
- DCHECK(!ContainsKey(downloads_, download->GetId()));
- DCHECK(!ContainsKey(active_downloads_, download->GetId()));
- return;
- }
-
- // Should be in downloads_ if we're not REMOVING.
CHECK(ContainsKey(downloads_, download->GetId()));
int64 state = download->GetState();
base::debug::Alias(&state);
- if (ContainsKey(active_downloads_, download->GetId())) {
- if (download->IsPersisted())
- CHECK_EQ(DownloadItem::IN_PROGRESS, download->GetState());
- if (DownloadItem::IN_PROGRESS != download->GetState())
- CHECK_EQ(DownloadItem::kUninitializedHandle, download->GetDbHandle());
- }
if (DownloadItem::IN_PROGRESS == download->GetState())
CHECK(ContainsKey(active_downloads_, download->GetId()));
}
@@ -655,12 +626,6 @@ bool DownloadManagerImpl::IsDownloadReadyForCompletion(
if (active_downloads_.count(download->GetId()) == 0)
return false;
- // If the download hasn't been inserted into the history system
- // (which occurs strictly after file name determination, intermediate
- // file rename, and UI display) then it's not ready for completion.
- if (!download->IsPersisted())
- return false;
-
return true;
}
@@ -692,7 +657,6 @@ void DownloadManagerImpl::MaybeCompleteDownload(
DCHECK(download->IsInProgress());
DCHECK_NE(DownloadItem::DANGEROUS, download->GetSafetyState());
DCHECK(download->AllDataSaved());
- DCHECK(download->IsPersisted());
// Give the delegate a chance to override. It's ok to keep re-setting the
// delegate's |complete_callback| cb as long as there isn't another call-point
@@ -707,8 +671,6 @@ void DownloadManagerImpl::MaybeCompleteDownload(
VLOG(20) << __FUNCTION__ << "()" << " executing: download = "
<< download->DebugString(false);
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
download->OnDownloadCompleting();
}
@@ -720,8 +682,6 @@ void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) {
void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(download);
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
active_downloads_.erase(download->GetId());
AssertStateConsistent(download);
}
@@ -761,14 +721,7 @@ void DownloadManagerImpl::OnDownloadInterrupted(
void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(download);
-
- // Clean up will happen when the history system create callback runs if we
- // don't have a valid db_handle yet.
- if (download->IsPersisted()) {
- active_downloads_.erase(download->GetId());
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
- }
+ active_downloads_.erase(download->GetId());
}
bool DownloadManagerImpl::GenerateFileHash() {
@@ -782,20 +735,16 @@ int DownloadManagerImpl::RemoveDownloadItems(
// Delete from internal maps.
for (DownloadItemImplVector::const_iterator it = pending_deletes.begin();
- it != pending_deletes.end();
- ++it) {
+ it != pending_deletes.end();
+ ++it) {
DownloadItemImpl* download = *it;
DCHECK(download);
- downloads_.erase(download->GetId());
+ int32 download_id = download->GetId();
+ delete download;
+ downloads_.erase(download_id);
}
-
- // Tell observers to refresh their views.
NotifyModelChanged();
-
- // Delete the download items themselves.
- const int num_deleted = static_cast<int>(pending_deletes.size());
- STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end());
- return num_deleted;
+ return static_cast<int>(pending_deletes.size());
}
void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) {
@@ -803,14 +752,6 @@ void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) {
downloads_.find(download->GetId()) == downloads_.end())
return;
- // TODO(benjhayden,rdsmith): Remove this.
- if (!download->IsPersisted())
- return;
-
- // Make history update.
- if (delegate_)
- delegate_->RemoveItemFromPersistentStore(download);
-
// Remove from our tables and delete.
int downloads_count =
RemoveDownloadItems(DownloadItemImplVector(1, download));
@@ -819,21 +760,16 @@ void DownloadManagerImpl::DownloadRemoved(DownloadItemImpl* download) {
int DownloadManagerImpl::RemoveDownloadsBetween(base::Time remove_begin,
base::Time remove_end) {
- if (delegate_)
- delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end);
-
- // All downloads visible to the user will be in the history,
- // so scan that map.
DownloadItemImplVector pending_deletes;
for (DownloadMap::const_iterator it = downloads_.begin();
it != downloads_.end();
++it) {
DownloadItemImpl* download = it->second;
- if (download->IsPersisted() &&
- download->GetStartTime() >= remove_begin &&
+ if (download->GetStartTime() >= remove_begin &&
(remove_end.is_null() || download->GetStartTime() < remove_end) &&
(download->IsComplete() || download->IsCancelled())) {
AssertStateConsistent(download);
+ download->NotifyRemoved();
pending_deletes.push_back(download);
}
}
@@ -882,9 +818,6 @@ void DownloadManagerImpl::OnPersistentStoreQueryComplete(
std::vector<DownloadPersistentStoreInfo>* entries) {
history_size_ = entries->size();
for (size_t i = 0; i < entries->size(); ++i) {
- int64 db_handle = entries->at(i).db_handle;
- base::debug::Alias(&db_handle);
-
net::BoundNetLog bound_net_log =
net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
DownloadItemImpl* download = factory_->CreatePersistedItem(
@@ -899,73 +832,6 @@ void DownloadManagerImpl::OnPersistentStoreQueryComplete(
CheckForHistoryFilesRemoval();
}
-void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItemImpl* download,
- int64 db_handle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK_NE(DownloadItem::kUninitializedHandle, db_handle);
- DCHECK(!download->IsPersisted());
- download->SetDbHandle(db_handle);
- download->SetIsPersisted();
-
- download_stats::RecordHistorySize(history_size_);
- // Not counting |download|.
- ++history_size_;
-
- // Show in the appropriate browser UI.
- // This includes buttons to save or cancel, for a dangerous download.
- ShowDownloadInBrowser(download);
-
- // Inform interested objects about the new download.
- NotifyModelChanged();
-}
-
-
-void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
- int64 db_handle) {
- // It's valid that we don't find a matching item, i.e. on shutdown.
- if (!ContainsKey(downloads_, download_id))
- return;
-
- DownloadItemImpl* item = downloads_[download_id];
- AddDownloadItemToHistory(item, db_handle);
- if (SavePageExternalData::Get(item)) {
- OnSavePageItemAddedToPersistentStore(item);
- } else {
- OnDownloadItemAddedToPersistentStore(item);
- }
-}
-
-// Once the new DownloadItem has been committed to the persistent store,
-// associate it with its db_handle (TODO(benjhayden) merge db_handle with id),
-// show it in the browser (TODO(benjhayden) the ui should observe us instead),
-// and notify observers (TODO(benjhayden) observers should be able to see the
-// 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(
- DownloadItemImpl* item) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- 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.
- //
- // 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 (item->IsInProgress()) {
- MaybeCompleteDownload(item);
- } else {
- DCHECK(item->IsCancelled());
- active_downloads_.erase(item->GetId());
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(item);
- item->UpdateObservers();
- }
-}
-
void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) {
// The 'contents' may no longer exist if the user closed the contents before
// we get this start completion event.
@@ -998,9 +864,9 @@ void DownloadManagerImpl::NotifyModelChanged() {
FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this));
}
+// TODO(benjhayden): Kill this method premailing XXX occam
DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) {
- DownloadItem* download = GetDownload(download_id);
- return (download && download->IsPersisted()) ? download : NULL;
+ return GetDownload(download_id);
}
DownloadItem* DownloadManagerImpl::GetDownload(int download_id) {
@@ -1047,45 +913,16 @@ void DownloadManagerImpl::AssertContainersConsistent() const {
#endif
}
-// SavePackage will call SavePageDownloadFinished upon completion/cancellation.
-// The history callback will call OnSavePageItemAddedToPersistentStore.
-// If the download finishes before the history callback,
-// OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring
-// that the history event is update regardless of the order in which these two
-// events complete.
-// If something removes the download item from the download manager (Remove,
-// Shutdown) the result will be that the SavePage system will not be able to
-// properly update the download item (which no longer exists) or the download
-// history, but the action will complete properly anyway. This may lead to the
-// history entry being wrong on a reload of chrome (specifically in the case of
-// Initiation -> History Callback -> Removal -> Completion), but there's no way
-// to solve that without canceling on Remove (which would then update the DB).
-
-void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore(
- DownloadItemImpl* item) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // Finalize this download if it finished before the history callback.
- if (!item->IsInProgress())
- SavePageDownloadFinished(item);
-}
-
void DownloadManagerImpl::SavePageDownloadFinished(
content::DownloadItem* download) {
- if (download->IsPersisted()) {
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
- if (download->IsComplete())
- content::NotificationService::current()->Notify(
- content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- content::Source<DownloadManager>(this),
- content::Details<DownloadItem>(download));
- }
+ if (download->IsComplete())
+ content::NotificationService::current()->Notify(
+ content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
+ content::Source<DownloadManager>(this),
+ content::Details<DownloadItem>(download));
}
void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) {
- if (delegate_)
- delegate_->UpdateItemInPersistentStore(download);
int num_unopened = 0;
for (DownloadMap::iterator it = downloads_.begin();
it != downloads_.end(); ++it) {
@@ -1097,28 +934,18 @@ void DownloadManagerImpl::DownloadOpened(DownloadItemImpl* download) {
download_stats::RecordOpensOutstanding(num_unopened);
}
+// TODO(benjhayden) this should be a method on DI
void DownloadManagerImpl::DownloadRenamedToIntermediateName(
DownloadItemImpl* download) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // download->GetFullPath() is only expected to be meaningful after this
- // callback is received. Therefore we can now add the download to a persistent
- // store. If the rename failed, we receive an OnDownloadInterrupted() call
- // before we receive the DownloadRenamedToIntermediateName() call.
- if (delegate_) {
- delegate_->AddItemToPersistentStore(download);
- } else {
- OnItemAddedToPersistentStore(download->GetId(),
- DownloadItem::kUninitializedHandle);
- }
+ download->UpdateObservers();
}
+// TODO(benjhayden) this should be a method on DI
void DownloadManagerImpl::DownloadRenamedToFinalName(
DownloadItemImpl* download) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// If the rename failed, we receive an OnDownloadInterrupted() call before we
// receive the DownloadRenamedToFinalName() call.
- if (delegate_) {
- delegate_->UpdatePathForItemInPersistentStore(
- download, download->GetFullPath());
- }
+ download->UpdateObservers();
}

Powered by Google App Engine
This is Rietveld 408576698