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

Unified Diff: chrome/browser/download/download_manager.cc

Issue 7192016: chrome.experimental.downloads (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: merged db_handle, id; onCreated, onErased 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_prefs.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/download/download_manager.cc
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index c61912a27dab764060b2dd4e824dca69c84f7245..4d7db4a8f21263f125597bd757f44437bbbcc909 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/download/download_manager.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/file_util.h"
#include "base/i18n/case_conversion.h"
@@ -23,6 +24,7 @@
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_item.h"
#include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/download/download_query.h"
#include "chrome/browser/download/download_request_handle.h"
#include "chrome/browser/download/download_safe_browsing_client.h"
#include "chrome/browser/download/download_status_updater.h"
@@ -84,49 +86,18 @@ void DownloadManager::Shutdown() {
AssertContainersConsistent();
- // Go through all downloads in downloads_. Dangerous ones we need to
- // remove on disk, and in progress ones we need to cancel.
- for (DownloadSet::iterator it = downloads_.begin(); it != downloads_.end();) {
- DownloadItem* download = *it;
-
- // Save iterator from potential erases in this set done by called code.
- // Iterators after an erasure point are still valid for lists and
- // associative containers such as sets.
- it++;
-
+ for (DownloadMap::iterator it = downloads_.begin(); it != downloads_.end();) {
+ DownloadItem* download = it->second;
+ ++it;
if (download->safety_state() == DownloadItem::DANGEROUS &&
download->IsPartialDownload()) {
- // The user hasn't accepted it, so we need to remove it
- // from the disk. This may or may not result in it being
- // removed from the DownloadManager queues and deleted
- // (specifically, DownloadManager::RemoveDownload only
- // removes and deletes it if it's known to the history service)
- // so the only thing we know after calling this function is that
- // the download was deleted if-and-only-if it was removed
- // from all queues.
download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN);
} else if (download->IsPartialDownload()) {
download->Cancel(false);
download_history_->UpdateEntry(download);
}
}
-
- // At this point, all dangerous downloads have had their files removed
- // 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.
- DownloadSet downloads_to_delete;
- downloads_to_delete.swap(downloads_);
-
- in_progress_.clear();
- active_downloads_.clear();
- history_downloads_.clear();
-#if !defined(NDEBUG)
- save_page_as_downloads_.clear();
-#endif
- STLDeleteElements(&downloads_to_delete);
+ STLValueDeleter<DownloadMap> delete_items(&downloads_);
file_manager_ = NULL;
@@ -137,90 +108,6 @@ void DownloadManager::Shutdown() {
download_history_.reset();
download_prefs_.reset();
-
- shutdown_needed_ = false;
-}
-
-void DownloadManager::GetTemporaryDownloads(
- const FilePath& dir_path, std::vector<DownloadItem*>* result) {
- DCHECK(result);
-
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
- if (it->second->is_temporary() &&
- it->second->full_path().DirName() == dir_path)
- result->push_back(it->second);
- }
-}
-
-void DownloadManager::GetAllDownloads(
- const FilePath& dir_path, std::vector<DownloadItem*>* result) {
- DCHECK(result);
-
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
- if (!it->second->is_temporary() &&
- (dir_path.empty() || it->second->full_path().DirName() == dir_path))
- result->push_back(it->second);
- }
-}
-
-void DownloadManager::GetCurrentDownloads(
- const FilePath& dir_path, std::vector<DownloadItem*>* result) {
- DCHECK(result);
-
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
- DownloadItem* item =it->second;
- // Skip temporary items.
- if (item->is_temporary())
- continue;
- // Skip items that have all their data, and are OK to save.
- if (!item->IsPartialDownload() &&
- (item->safety_state() != DownloadItem::DANGEROUS))
- continue;
- // Skip items that don't match |dir_path|.
- // If |dir_path| is empty, all remaining items match.
- if (!dir_path.empty() && (it->second->full_path().DirName() != dir_path))
- continue;
-
- result->push_back(item);
- }
-
- // If we have a parent profile, let it add its downloads to the results.
- Profile* original_profile = profile_->GetOriginalProfile();
- if (original_profile != profile_)
- original_profile->GetDownloadManager()->GetCurrentDownloads(dir_path,
- result);
-}
-
-void DownloadManager::SearchDownloads(const string16& query,
- std::vector<DownloadItem*>* result) {
- DCHECK(result);
-
- string16 query_lower(base::i18n::ToLower(query));
-
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
- DownloadItem* download_item = it->second;
-
- if (download_item->is_temporary() || download_item->is_extension_install())
- continue;
-
- // 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.
- if (profile_->IsOffTheRecord() != download_item->is_otr())
- continue;
-
- if (download_item->MatchesQuery(query_lower))
- result->push_back(download_item);
- }
-
- // If we have a parent profile, let it add its downloads to the results.
- Profile* original_profile = profile_->GetOriginalProfile();
- if (original_profile != profile_)
- original_profile->GetDownloadManager()->SearchDownloads(query, result);
}
// Query the history service for information about all persisted downloads.
@@ -263,6 +150,7 @@ void DownloadManager::StartDownload(int32 download_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetActiveDownloadItem(download_id);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download;
if (!download)
return;
@@ -280,8 +168,9 @@ void DownloadManager::StartDownload(int32 download_id) {
void DownloadManager::CheckForHistoryFilesRemoval() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
+ DVLOG(1) << __PRETTY_FUNCTION__;
+ for (DownloadMap::iterator it = downloads_.begin();
+ it != downloads_.end(); ++it) {
CheckForFileRemoval(it->second);
}
}
@@ -294,27 +183,30 @@ void DownloadManager::CheckForFileRemoval(DownloadItem* download_item) {
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(this,
&DownloadManager::CheckForFileRemovalOnFileThread,
- download_item->db_handle(),
+ download_item->id(),
download_item->GetTargetFilePath()));
}
}
void DownloadManager::CheckForFileRemovalOnFileThread(
- int64 db_handle, const FilePath& path) {
+ int64 id, const FilePath& path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (!file_util::PathExists(path)) {
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << id;
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(this,
&DownloadManager::OnFileRemovalDetected,
- db_handle));
+ id));
}
}
-void DownloadManager::OnFileRemovalDetected(int64 db_handle) {
+void DownloadManager::OnFileRemovalDetected(int64 id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadMap::iterator it = history_downloads_.find(db_handle);
- if (it != history_downloads_.end()) {
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << id;
+ DownloadMap::iterator it = downloads_.find(id);
+ if (it != downloads_.end()) {
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << id;
DownloadItem* download_item = it->second;
download_item->OnDownloadedFileRemoved();
}
@@ -325,6 +217,8 @@ void DownloadManager::CheckDownloadUrlDone(int32 download_id,
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetActiveDownloadItem(download_id);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " "
+ << is_dangerous_url << " " << download;
if (!download)
return;
@@ -342,6 +236,7 @@ void DownloadManager::CheckVisitedReferrerBeforeDone(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetActiveDownloadItem(download_id);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download;
if (!download)
return;
@@ -418,6 +313,7 @@ void DownloadManager::CheckIfSuggestedPathExists(int32 download_id,
DownloadStateInfo state,
const FilePath& default_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id;
// Make sure the default download directory exists.
// TODO(phajdan.jr): only create the directory when we're sure the user
@@ -508,6 +404,7 @@ void DownloadManager::OnPathExistenceAvailable(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetActiveDownloadItem(download_id);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download << " " << download_id;
if (!download)
return;
@@ -558,11 +455,11 @@ void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) {
DownloadItem* download = new DownloadItem(this, *info,
profile_->IsOffTheRecord());
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << info->download_id << " "
+ << download;
int32 download_id = info->download_id;
- DCHECK(!ContainsKey(in_progress_, download_id));
- DCHECK(!ContainsKey(active_downloads_, download_id));
- downloads_.insert(download);
- active_downloads_[download_id] = download;
+ DCHECK(!ContainsKey(downloads_, download_id));
+ downloads_[download_id] = download;
}
void DownloadManager::ContinueDownloadWithPath(DownloadItem* download,
@@ -571,12 +468,8 @@ void DownloadManager::ContinueDownloadWithPath(DownloadItem* download,
DCHECK(download);
int32 download_id = download->id();
-
- // NOTE(ahendrickson) Eventually |active_downloads_| will replace
- // |in_progress_|, but we don't want to change the semantics yet.
- DCHECK(!ContainsKey(in_progress_, download_id));
- DCHECK(ContainsKey(downloads_, download));
- DCHECK(ContainsKey(active_downloads_, download_id));
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download
+ << " " << chosen_file.value();
// Make sure the initial file name is set only once.
DCHECK(download->full_path().empty());
@@ -586,8 +479,7 @@ void DownloadManager::ContinueDownloadWithPath(DownloadItem* download,
VLOG(20) << __FUNCTION__ << "()"
<< " download = " << download->DebugString(true);
- in_progress_[download_id] = download;
- UpdateAppIcon(); // Reflect entry into in_progress_.
+ UpdateAppIcon(); // Reflect entry into .
// Rename to intermediate name.
FilePath download_path;
@@ -620,8 +512,8 @@ void DownloadManager::ContinueDownloadWithPath(DownloadItem* download,
void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadMap::iterator it = active_downloads_.find(download_id);
- if (it != active_downloads_.end()) {
+ DownloadMap::iterator it = downloads_.find(download_id);
+ if (it != downloads_.end()) {
DownloadItem* download = it->second;
if (download->IsInProgress()) {
download->Update(size);
@@ -653,16 +545,16 @@ void DownloadManager::OnResponseCompleted(int32 download_id,
void DownloadManager::OnAllDataSaved(int32 download_id,
int64 size,
const std::string& hash) {
- VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
+ DVLOG(1) << __FUNCTION__ << "()" << " download_id = " << download_id
<< " size = " << size;
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // If it's not in active_downloads_, that means it was cancelled; just
- // ignore the notification.
- if (active_downloads_.count(download_id) == 0)
+ DownloadItem* download = downloads_[download_id];
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << size << " "
+ << hash << " " << download;
+ if (!download) {
return;
-
- DownloadItem* download = active_downloads_[download_id];
+ }
download->OnAllDataSaved(size);
// When hash is not available, it means either it is not calculated
@@ -691,48 +583,20 @@ void DownloadManager::CheckDownloadHashDone(int32 download_id,
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DVLOG(1) << "CheckDownloadHashDone, download_id: " << download_id
<< " is dangerous_hash: " << is_dangerous_hash;
-
- // If it's not in active_downloads_, that means it was cancelled or
- // the download already finished.
- if (active_downloads_.count(download_id) == 0)
- return;
-
- DVLOG(1) << "CheckDownloadHashDone, url: "
- << active_downloads_[download_id]->GetURL().spec();
}
void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) {
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved.
- if (download->state() == DownloadItem::REMOVING) {
- CHECK(!ContainsKey(downloads_, download));
- CHECK(!ContainsKey(active_downloads_, download->id()));
- CHECK(!ContainsKey(in_progress_, download->id()));
- CHECK(!ContainsKey(history_downloads_, download->db_handle()));
- return;
- }
-
- // Should be in downloads_ if we're not REMOVING.
- CHECK(ContainsKey(downloads_, download));
-
- // Check history_downloads_ consistency.
- if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
- CHECK(ContainsKey(history_downloads_, download->db_handle()));
- } else {
- // TODO(rdsmith): Somewhat painful; make sure to disable in
- // release builds after resolution of http://crbug.com/85408.
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
- CHECK(it->second != download);
- }
- }
-
- CHECK(ContainsKey(active_downloads_, download->id()) ==
- (download->state() == DownloadItem::IN_PROGRESS));
- CHECK(ContainsKey(in_progress_, download->id()) ==
- (download->state() == DownloadItem::IN_PROGRESS));
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download;
}
bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) {
+ DVLOG(1) << __PRETTY_FUNCTION__ << " p=" << download << " id="
+ << download->id() << " data=" << download->all_data_saved()
+ << " safety=" << download->safety_state() << " path="
+ << download->full_path().value();
+ return download->all_data_saved() &&
+ download->safety_state() != DownloadItem::DANGEROUS &&
+ !download->full_path().value().empty();
// If we don't have all the data, the download is not ready for
// completion.
if (!download->all_data_saved())
@@ -743,24 +607,12 @@ bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) {
if (download->safety_state() == DownloadItem::DANGEROUS)
return false;
- // If the download isn't active (e.g. has been cancelled) it's not
- // ready for completion.
- if (active_downloads_.count(download->id()) == 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->db_handle() == DownloadHistory::kUninitializedHandle)
- return false;
-
return true;
}
void DownloadManager::MaybeCompleteDownload(DownloadItem* download) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- VLOG(20) << __FUNCTION__ << "()" << " download = "
- << download->DebugString(false);
+ DVLOG(1) << __FUNCTION__ << " " << download->DebugString(true);
if (!IsDownloadReadyForCompletion(download))
return;
@@ -770,24 +622,20 @@ void DownloadManager::MaybeCompleteDownload(DownloadItem* download) {
// transition on the DownloadItem.
// Confirm we're in the proper set of states to be here;
- // in in_progress_, have all data, have a history handle, (validated or safe).
+ // in , have all data, have a history handle, (validated or safe).
DCHECK_NE(DownloadItem::DANGEROUS, download->safety_state());
- DCHECK_EQ(1u, in_progress_.count(download->id()));
DCHECK(download->all_data_saved());
- DCHECK(download->db_handle() != DownloadHistory::kUninitializedHandle);
- DCHECK_EQ(1u, history_downloads_.count(download->db_handle()));
+ DCHECK(!download->full_path().value().empty());
- VLOG(20) << __FUNCTION__ << "()" << " executing: download = "
- << download->DebugString(false);
+ DVLOG(1) << __FUNCTION__ << " " << download->DebugString(true);
- // Remove the id from in_progress
- in_progress_.erase(download->id());
- UpdateAppIcon(); // Reflect removal from in_progress_.
+ UpdateAppIcon(); // Reflect removal from .
download_history_->UpdateEntry(download);
// Finish the download.
download->OnDownloadCompleting(file_manager_);
+ DVLOG(1) << __FUNCTION__ << " " << download->DebugString(true);
}
void DownloadManager::DownloadCompleted(int32 download_id) {
@@ -795,13 +643,12 @@ void DownloadManager::DownloadCompleted(int32 download_id) {
DownloadItem* download = GetDownloadItem(download_id);
DCHECK(download);
download_history_->UpdateEntry(download);
- active_downloads_.erase(download_id);
}
void DownloadManager::OnDownloadRenamedToFinalName(int download_id,
const FilePath& full_path,
int uniquifier) {
- VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
+ DVLOG(1) << __FUNCTION__ << "()" << " download_id = " << download_id
<< " full_path = \"" << full_path.value() << "\""
<< " uniquifier = " << uniquifier;
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -824,27 +671,17 @@ void DownloadManager::OnDownloadRenamedToFinalName(int download_id,
item->OnDownloadRenamedToFinalName(full_path);
download_history_->UpdateDownloadPath(item, full_path);
+ UpdateAppIcon();
}
void DownloadManager::DownloadCancelled(int32 download_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadMap::iterator it = in_progress_.find(download_id);
- if (it == in_progress_.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);
- }
-
+ DownloadItem* download = downloads_[download_id];
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download
+ << " " << (download ? download->DebugString(true) : "");
+ DCHECK(download);
+ UpdateAppIcon(); // Reflect removal from .
+ download_history_->UpdateEntry(download);
DownloadCancelledInternal(download_id, download->request_handle());
}
@@ -863,32 +700,13 @@ void DownloadManager::OnDownloadError(int32 download_id,
int64 size,
int os_error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadMap::iterator it = active_downloads_.find(download_id);
- // A cancel at the right time could remove the download from the
- // |active_downloads_| map before we get here.
- if (it == active_downloads_.end())
- return;
-
- DownloadItem* download = it->second;
-
- VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error
- << " at offset " << download->received_bytes()
- << " for download = " << download->DebugString(true);
-
+ DownloadItem* download = downloads_[download_id];
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download
+ << " " << (download ? download->DebugString(true) : "");
+ DCHECK(download);
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);
- }
-
+ UpdateAppIcon(); // Reflect removal from .
+ download_history_->UpdateEntry(download);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
@@ -900,74 +718,108 @@ 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())
+void DownloadManager::RemoveDownload(int64 id) {
+ DownloadMap::iterator it = downloads_.find(id);
+ scoped_ptr<DownloadItem> download(it->second);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << id << " " << download.get();
+ if (download.get() == NULL) {
return;
-
- // Make history update.
- DownloadItem* download = it->second;
- download_history_->RemoveEntry(download);
-
- // Remove from our tables and delete.
- history_downloads_.erase(it);
- int downloads_count = downloads_.erase(download);
- DCHECK_EQ(1, downloads_count);
-
- // Tell observers to refresh their views.
+ }
+ download_history_->RemoveEntry(download.get());
+ downloads_.erase(it);
NotifyModelChanged();
-
- delete download;
}
-int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin,
- const base::Time remove_end) {
- download_history_->RemoveEntriesBetween(remove_begin, remove_end);
-
- // All downloads visible to the user will be in the history,
- // so scan that map.
- DownloadMap::iterator it = history_downloads_.begin();
- std::vector<DownloadItem*> pending_deletes;
- while (it != history_downloads_.end()) {
- DownloadItem* download = it->second;
- if (download->start_time() >= remove_begin &&
- (remove_end.is_null() || download->start_time() < remove_end) &&
- (download->IsComplete() ||
- download->IsCancelled() ||
- download->IsInterrupted())) {
- AssertQueueStateConsistent(download);
+void DownloadManager::GetTemporaryDownloads(
+ const FilePath& dir_path, ItemVector* result) {
+ DCHECK(result);
+ Search(DOWNLOAD_QUERY_FILTER(item.is_temporary()).
+ filenameRegex("^" + dir_path.value() + "/.*"),
+ result);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << result->size();
+}
- // Remove from the map and move to the next in the list.
- history_downloads_.erase(it++);
+void DownloadManager::GetAllDownloads(
+ const FilePath& dir_path, ItemVector* result) {
+ DCHECK(result);
+ Search(DOWNLOAD_QUERY_FILTER(!item.is_temporary()).
+ filenameRegex("^" + dir_path.value() + "/.*"),
+ result);
+}
- // Also remove it from any completed dangerous downloads.
- pending_deletes.push_back(download);
+void DownloadManager::GetCurrentDownloads(
+ const FilePath& dir_path, ItemVector* result) {
+ DCHECK(result);
+ Search(DOWNLOAD_QUERY_FILTER(
+ !item.is_temporary() &&
+ (item.IsPartialDownload() ||
+ (item.safety_state() == DownloadItem::DANGEROUS))).
+ filenameRegex("^" + dir_path.value() + "/.*"),
+ result);
+}
- continue;
- }
+bool DownloadManager::Search(const download_util::DownloadQuery& query,
+ ItemVector* items,
+ bool merge_parent_manager,
+ std::string* error_msg,
+ ListValue* json_results) const {
+ ItemVector default_items;
+ if (items == NULL) {
+ items = &default_items;
+ }
+ MergeItems(merge_parent_manager, items);
+ return query.Search(items, error_msg, json_results);
+}
- ++it;
+void DownloadManager::MergeItems(
+ bool merge_parent_manager, ItemVector* items) const {
+ for (DownloadMap::const_iterator it = downloads_.begin();
+ it != downloads_.end(); ++it) items->push_back(it->second);
+ if (!merge_parent_manager ||
+ (profile_ == NULL)) return;
+ Profile* original_profile = profile_->GetOriginalProfile();
+ if ((profile_ != NULL) &&
+ (original_profile != NULL) &&
+ (original_profile != profile_) &&
+ (original_profile->GetDownloadManager() != NULL)) {
+ original_profile->GetDownloadManager()->MergeItems(
+ merge_parent_manager, items);
}
+}
- // If we aren't deleting anything, we're done.
- if (pending_deletes.empty())
- return 0;
+void DownloadManager::SearchDownloads(const string16& query,
+ ItemVector* result) {
+ DCHECK(result);
+ bool otr = false;
+ if (profile_ != NULL) otr = profile_->IsOffTheRecord();
+ Search(DOWNLOAD_QUERY_FILTER1(otr,
+ !item.is_temporary() &&
+ !item.is_extension_install() &&
+ (item.is_otr() == otr)).
+ query(UTF16ToASCII(query)),
+ result);
+}
- // Remove the chosen downloads from the main owning container.
- for (std::vector<DownloadItem*>::iterator it = pending_deletes.begin();
- it != pending_deletes.end(); it++) {
- downloads_.erase(*it);
+int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin,
+ const base::Time remove_end) {
+ download_history_->RemoveEntriesBetween(remove_begin, remove_end);
+ ItemVector pending_deletes;
+ STLElementDeleter<ItemVector> delete_pending_deletes(&pending_deletes);
+ const base::Time unix_epoch = base::Time::UnixEpoch();
+ Search(DOWNLOAD_QUERY_FILTER(
+ item.IsComplete() ||
+ item.IsCancelled() ||
+ item.IsInterrupted()).
+ startedAfter((remove_begin - unix_epoch).InMilliseconds()).
+ startedBefore((remove_end - unix_epoch).InMilliseconds()),
+ &pending_deletes);
+ if (pending_deletes.empty()) return 0;
+ for (ItemVector::const_iterator iter = pending_deletes.begin();
+ iter != pending_deletes.end(); ++iter) {
+ downloads_.erase(downloads_.find((*iter)->id()));
}
-
- // Tell observers to refresh their views.
NotifyModelChanged();
-
- // Delete the download items themselves.
int num_deleted = static_cast<int>(pending_deletes.size());
-
- STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end());
- pending_deletes.clear();
-
return num_deleted;
}
@@ -989,9 +841,9 @@ void DownloadManager::SavePageAsDownloadStarted(DownloadItem* download) {
#if !defined(NDEBUG)
save_page_as_downloads_.insert(download);
#endif
- downloads_.insert(download);
+ downloads_[download->id()] = download;
// Add to history and notify observers.
- AddDownloadItemToHistory(download, DownloadHistory::kUninitializedHandle);
+ AddDownloadItemToHistory(download);
NotifyModelChanged();
}
@@ -1048,36 +900,42 @@ bool DownloadManager::ShouldOpenFileBasedOnExtension(
}
bool DownloadManager::IsDownloadProgressKnown() {
- for (DownloadMap::iterator i = in_progress_.begin();
- i != in_progress_.end(); ++i) {
- if (i->second->total_bytes() <= 0)
+ for (DownloadMap::iterator i = downloads_.begin();
+ i != downloads_.end(); ++i) {
+ if (i->second->total_bytes() <= 0) {
return false;
+ }
}
-
return true;
}
-int64 DownloadManager::GetInProgressDownloadCount() {
- return in_progress_.size();
+int64 DownloadManager::GetInProgressDownloadCount() const {
+ ItemVector in_progress;
+ Search(download_util::DownloadQuery().state_enum(DownloadItem::IN_PROGRESS),
+ &in_progress);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << in_progress.size();
+ return in_progress.size();
}
int64 DownloadManager::GetReceivedDownloadBytes() {
DCHECK(IsDownloadProgressKnown());
int64 received_bytes = 0;
- for (DownloadMap::iterator i = in_progress_.begin();
- i != in_progress_.end(); ++i) {
+ for (DownloadMap::iterator i = downloads_.begin();
+ i != downloads_.end(); ++i) {
received_bytes += i->second->received_bytes();
}
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << received_bytes;
return received_bytes;
}
int64 DownloadManager::GetTotalDownloadBytes() {
DCHECK(IsDownloadProgressKnown());
int64 total_bytes = 0;
- for (DownloadMap::iterator i = in_progress_.begin();
- i != in_progress_.end(); ++i) {
+ for (DownloadMap::iterator i = downloads_.begin();
+ i != downloads_.end(); ++i) {
total_bytes += i->second->total_bytes();
}
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << total_bytes;
return total_bytes;
}
@@ -1164,56 +1022,36 @@ void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
// 'DownloadHistoryInfo's in sorted order (by ascending start_time).
void DownloadManager::OnQueryDownloadEntriesComplete(
std::vector<DownloadHistoryInfo>* entries) {
- for (size_t i = 0; i < entries->size(); ++i) {
- DownloadItem* download = new DownloadItem(this, entries->at(i));
- DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
- downloads_.insert(download);
- history_downloads_[download->db_handle()] = download;
- VLOG(20) << __FUNCTION__ << "()" << i << ">"
- << " download = " << download->DebugString(true);
+ for (std::vector<DownloadHistoryInfo>::iterator it = entries->begin();
+ it != entries->end(); ++it) {
+ DownloadItem* download = new DownloadItem(this, *it);
+ DVLOG(2) << __PRETTY_FUNCTION__ << " " << download->id() << " " << download;
+ DCHECK(!ContainsKey(downloads_, download->id()));
+ downloads_[download->id()] = download;
}
NotifyModelChanged();
CheckForHistoryFilesRemoval();
}
-void DownloadManager::AddDownloadItemToHistory(DownloadItem* download,
- int64 db_handle) {
+void DownloadManager::AddDownloadItemToHistory(DownloadItem* download) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // It's not immediately obvious, but HistoryBackend::CreateDownload() can
- // call this function with an invalid |db_handle|. For instance, this can
- // happen when the history database is offline. We cannot have multiple
- // DownloadItems with the same invalid db_handle, so we need to assign a
- // unique |db_handle| here.
- if (db_handle == DownloadHistory::kUninitializedHandle)
- db_handle = download_history_->GetNextFakeDbHandle();
-
- // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508
- // is fixed.
- CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle);
-
- DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
- download->set_db_handle(db_handle);
-
- DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
- history_downloads_[download->db_handle()] = download;
}
// Once the new DownloadItem's creation info has been committed to the history
// service, we associate the DownloadItem with the db handle, update our
// 'history_downloads_' map and inform observers.
-void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
- int64 db_handle) {
+void DownloadManager::OnCreateDownloadEntryComplete(
+ int32 download_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetActiveDownloadItem(download_id);
- if (!download)
- return;
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download;
+ if (download == NULL) return;
+ download->SetIsInHistory(true);
+ VLOG(20) << __FUNCTION__ << download->DebugString(true);
- VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
- << " download_id = " << download_id
- << " download = " << download->DebugString(true);
+ AddDownloadItemToHistory(download);
- AddDownloadItemToHistory(download, db_handle);
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download;
// Show in the appropriate browser UI.
// This includes buttons to save or cancel, for a dangerous download.
@@ -1232,16 +1070,14 @@ void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
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();
}
}
void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) {
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download << " " << download->id();
+
// The 'contents' may no longer exist if the user closed the tab before we
// get this start completion event. If it does, tell the origin TabContents
// to display its download shelf.
@@ -1276,67 +1112,29 @@ void DownloadManager::NotifyModelChanged() {
}
DownloadItem* DownloadManager::GetDownloadItem(int download_id) {
- // The |history_downloads_| map is indexed by the download's db_handle,
- // not its id, so we have to iterate.
- for (DownloadMap::iterator it = history_downloads_.begin();
- it != history_downloads_.end(); ++it) {
- DownloadItem* item = it->second;
- if (item->id() == download_id)
- return item;
- }
- return NULL;
+ DownloadItem* download = downloads_[download_id];
+ DVLOG(1) << __PRETTY_FUNCTION__ << " " << download_id << " " << download;
+ return download;
}
DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) {
- DCHECK(ContainsKey(active_downloads_, download_id));
- DownloadItem* download = active_downloads_[download_id];
- DCHECK(download != NULL);
- return download;
+ return GetDownloadItem(download_id);
}
-// Confirm that everything in all maps is also in |downloads_|, and that
-// everything in |downloads_| is also in some other map.
+// Confirm that there's only one of any download_id, and that they are all > -1
void DownloadManager::AssertContainersConsistent() const {
-#if !defined(NDEBUG)
- // Turn everything into sets.
- DownloadSet active_set, history_set;
- const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_};
- DownloadSet* local_sets[] = {&active_set, &history_set};
- DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets));
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) {
- for (DownloadMap::const_iterator it = input_maps[i]->begin();
- it != input_maps[i]->end(); it++) {
- local_sets[i]->insert(&*it->second);
- }
+ std::vector<int> ids;
+ for (DownloadMap::const_iterator iter = downloads_.begin();
+ iter != downloads_.end(); ++iter) {
+ ids.push_back(iter->second->id());
}
-
- // Check if each set is fully present in downloads, and create a union.
- const DownloadSet* all_sets[] = {&active_set, &history_set,
- &save_page_as_downloads_};
- DownloadSet downloads_union;
- for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) {
- DownloadSet remainder;
- std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin());
- std::set_difference(all_sets[i]->begin(), all_sets[i]->end(),
- downloads_.begin(), downloads_.end(),
- insert_it);
- DCHECK(remainder.empty());
- std::insert_iterator<DownloadSet>
- insert_union(downloads_union, downloads_union.end());
- std::set_union(downloads_union.begin(), downloads_union.end(),
- all_sets[i]->begin(), all_sets[i]->end(),
- insert_union);
+ std::sort(ids.begin(), ids.end());
+ int prev_id = -1;
+ for (std::vector<int>::const_iterator iter = ids.begin();
+ iter != ids.end(); ++iter) {
+ CHECK_GT(*iter, prev_id) << *iter << " " << prev_id;
+ prev_id = *iter;
}
-
- // Is everything in downloads_ present in one of the other sets?
- DownloadSet remainder;
- std::insert_iterator<DownloadSet>
- insert_remainder(remainder, remainder.begin());
- std::set_difference(downloads_.begin(), downloads_.end(),
- downloads_union.begin(), downloads_union.end(),
- insert_remainder);
- DCHECK(remainder.empty());
-#endif
}
// DownloadManager::OtherDownloadManagerObserver implementation ----------------
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_prefs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698