summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-22 20:59:53 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-22 20:59:53 +0000
commit2588ea9deaa629c3d249b231c6111c02f691f36a (patch)
tree49e44712f89bb4d9973a4e23a2493c118a46f0ae
parent04386e72c18b3368b82dff1c261021163d859d5b (diff)
downloadchromium_src-2588ea9deaa629c3d249b231c6111c02f691f36a.zip
chromium_src-2588ea9deaa629c3d249b231c6111c02f691f36a.tar.gz
chromium_src-2588ea9deaa629c3d249b231c6111c02f691f36a.tar.bz2
Move DownloadHistory ownership and usage out from content to chrome. DownloadManager talks to the history system through its delegate interface. I'll move the DownloadHistoryInfo struct from chrome to content in a future change.
BUG=82782 Review URL: http://codereview.chromium.org/7704004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97731 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/download/chrome_download_manager_delegate.cc55
-rw-r--r--chrome/browser/download/chrome_download_manager_delegate.h21
-rw-r--r--chrome/browser/download/download_history.cc15
-rw-r--r--chrome/browser/download/download_history.h4
-rw-r--r--chrome/browser/download/download_manager_unittest.cc2
-rw-r--r--chrome/browser/download/mock_download_manager_delegate.cc24
-rw-r--r--chrome/browser/download/mock_download_manager_delegate.h10
-rw-r--r--chrome/browser/download/save_page_browsertest.cc6
-rw-r--r--chrome/browser/profiles/profile.cc2
-rw-r--r--chrome/browser/profiles/profile_impl.cc2
-rw-r--r--chrome/browser/ui/webui/downloads_dom_handler.cc4
-rw-r--r--content/browser/download/download_file_manager.cc8
-rw-r--r--content/browser/download/download_file_manager.h7
-rw-r--r--content/browser/download/download_item.cc17
-rw-r--r--content/browser/download/download_item.h7
-rw-r--r--content/browser/download/download_manager.cc96
-rw-r--r--content/browser/download/download_manager.h42
-rw-r--r--content/browser/download/download_manager_delegate.h30
-rw-r--r--content/browser/download/save_file_manager.h4
-rw-r--r--content/browser/download/save_package.cc8
20 files changed, 245 insertions, 119 deletions
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index c28fb16..0e624d9 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -42,6 +42,18 @@ ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
}
+void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
+ download_manager_ = dm;
+ download_history_.reset(new DownloadHistory(profile_));
+ download_history_->Load(
+ NewCallback(dm, &DownloadManager::OnPersistentStoreQueryComplete));
+}
+
+void ChromeDownloadManagerDelegate::Shutdown() {
+ download_history_.reset();
+ download_prefs_.reset();
+}
+
bool ChromeDownloadManagerDelegate::ShouldStartDownload(int32 download_id) {
// We create a download item and store it in our download map, and inform the
// history system of a new download. Since this method can be called while the
@@ -108,6 +120,35 @@ bool ChromeDownloadManagerDelegate::GenerateFileHash() {
#endif
}
+void ChromeDownloadManagerDelegate::AddItemToPersistentStore(
+ DownloadItem* item) {
+ download_history_->AddEntry(item,
+ NewCallback(this,
+ &ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore));
+}
+
+void ChromeDownloadManagerDelegate::UpdateItemInPersistentStore(
+ DownloadItem* item) {
+ download_history_->UpdateEntry(item);
+}
+
+void ChromeDownloadManagerDelegate::UpdatePathForItemInPersistentStore(
+ DownloadItem* item,
+ const FilePath& new_path) {
+ download_history_->UpdateDownloadPath(item, new_path);
+}
+
+void ChromeDownloadManagerDelegate::RemoveItemFromPersistentStore(
+ DownloadItem* item) {
+ download_history_->RemoveEntry(item);
+}
+
+void ChromeDownloadManagerDelegate::RemoveItemsFromPersistentStoreBetween(
+ const base::Time remove_begin,
+ const base::Time remove_end) {
+ download_history_->RemoveEntriesBetween(remove_begin, remove_end);
+}
+
void ChromeDownloadManagerDelegate::GetSaveDir(TabContents* tab_contents,
FilePath* website_save_dir,
FilePath* download_save_dir) {
@@ -168,7 +209,7 @@ void ChromeDownloadManagerDelegate::CheckDownloadUrlDone(
if (is_dangerous_url)
download->MarkUrlDangerous();
- download_manager_->download_history()->CheckVisitedReferrerBefore(
+ download_history_->CheckVisitedReferrerBefore(
download_id,
download->referrer_url(),
NewCallback(this,
@@ -381,3 +422,15 @@ bool ChromeDownloadManagerDelegate::IsDangerousFile(
}
return false;
}
+
+void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore(
+ int32 download_id, int64 db_handle) {
+ // 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 == DownloadItem::kUninitializedHandle)
+ db_handle = download_history_->GetNextFakeDbHandle();
+ download_manager_->OnItemAddedToPersistentStore(download_id, db_handle);
+}
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h
index d32bdfa..94fdf8d 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.h
+++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -12,10 +12,12 @@
#include "base/task.h"
#include "content/browser/download/download_manager_delegate.h"
+class DownloadHistory;
class DownloadItem;
class DownloadManager;
class DownloadPrefs;
class Profile;
+struct DownloadHistoryInfo;
struct DownloadStateInfo;
// This is the Chrome side helper for the download system.
@@ -25,6 +27,9 @@ class ChromeDownloadManagerDelegate
public:
explicit ChromeDownloadManagerDelegate(Profile* profile);
+ void SetDownloadManager(DownloadManager* dm);
+
+ virtual void Shutdown() OVERRIDE;
virtual bool ShouldStartDownload(int32 download_id) OVERRIDE;
virtual void ChooseDownloadPath(TabContents* tab_contents,
const FilePath& suggested_path,
@@ -32,6 +37,15 @@ class ChromeDownloadManagerDelegate
virtual TabContents* GetAlternativeTabContentsToNotifyForDownload() OVERRIDE;
virtual bool ShouldOpenFileBasedOnExtension(const FilePath& path) OVERRIDE;
virtual bool GenerateFileHash() OVERRIDE;
+ virtual void AddItemToPersistentStore(DownloadItem* item) OVERRIDE;
+ virtual void UpdateItemInPersistentStore(DownloadItem* item) OVERRIDE;
+ virtual void UpdatePathForItemInPersistentStore(
+ DownloadItem* item,
+ const FilePath& new_path) OVERRIDE;
+ virtual void RemoveItemFromPersistentStore(DownloadItem* item) OVERRIDE;
+ virtual void RemoveItemsFromPersistentStoreBetween(
+ const base::Time remove_begin,
+ const base::Time remove_end) OVERRIDE;
virtual void GetSaveDir(TabContents* tab_contents,
FilePath* website_save_dir,
FilePath* download_save_dir) OVERRIDE;
@@ -40,9 +54,8 @@ class ChromeDownloadManagerDelegate
bool can_save_as_complete) OVERRIDE;
virtual void DownloadProgressUpdated() OVERRIDE;
- void set_download_manager(DownloadManager* dm) { download_manager_ = dm; }
-
DownloadPrefs* download_prefs() { return download_prefs_.get(); }
+ DownloadHistory* download_history() { return download_history_.get(); }
private:
friend class base::RefCountedThreadSafe<ChromeDownloadManagerDelegate>;
@@ -76,9 +89,13 @@ class ChromeDownloadManagerDelegate
const DownloadStateInfo& state,
bool visited_referrer_before);
+ // Callback from history system.
+ void OnItemAddedToPersistentStore(int32 download_id, int64 db_handle);
+
Profile* profile_;
scoped_refptr<DownloadManager> download_manager_;
scoped_ptr<DownloadPrefs> download_prefs_;
+ scoped_ptr<DownloadHistory> download_history_;
DISALLOW_COPY_AND_ASSIGN(ChromeDownloadManagerDelegate);
};
diff --git a/chrome/browser/download/download_history.cc b/chrome/browser/download/download_history.cc
index 4ced900..8ca6e74 100644
--- a/chrome/browser/download/download_history.cc
+++ b/chrome/browser/download/download_history.cc
@@ -10,16 +10,9 @@
#include "chrome/browser/profiles/profile.h"
#include "content/browser/download/download_item.h"
-// Our download table ID starts at 1, so we use 0 to represent a download that
-// has started, but has not yet had its data persisted in the table. We use fake
-// database handles in incognito mode starting at -1 and progressively getting
-// more negative.
-// static
-const int DownloadHistory::kUninitializedHandle = 0;
-
DownloadHistory::DownloadHistory(Profile* profile)
: profile_(profile),
- next_fake_db_handle_(kUninitializedHandle - 1) {
+ next_fake_db_handle_(DownloadItem::kUninitializedHandle - 1) {
DCHECK(profile);
}
@@ -97,7 +90,7 @@ void DownloadHistory::AddEntry(
void DownloadHistory::UpdateEntry(DownloadItem* download_item) {
// Don't store info in the database if the download was initiated while in
// incognito mode or if it hasn't been initialized in our database table.
- if (download_item->db_handle() <= kUninitializedHandle)
+ if (download_item->db_handle() <= DownloadItem::kUninitializedHandle)
return;
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
@@ -112,7 +105,7 @@ void DownloadHistory::UpdateEntry(DownloadItem* download_item) {
void DownloadHistory::UpdateDownloadPath(DownloadItem* download_item,
const FilePath& new_path) {
// No update necessary if the download was initiated while in incognito mode.
- if (download_item->db_handle() <= kUninitializedHandle)
+ if (download_item->db_handle() <= DownloadItem::kUninitializedHandle)
return;
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
@@ -122,7 +115,7 @@ void DownloadHistory::UpdateDownloadPath(DownloadItem* download_item,
void DownloadHistory::RemoveEntry(DownloadItem* download_item) {
// No update necessary if the download was initiated while in incognito mode.
- if (download_item->db_handle() <= kUninitializedHandle)
+ if (download_item->db_handle() <= DownloadItem::kUninitializedHandle)
return;
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
diff --git a/chrome/browser/download/download_history.h b/chrome/browser/download/download_history.h
index f4b4881..6d6b237 100644
--- a/chrome/browser/download/download_history.h
+++ b/chrome/browser/download/download_history.h
@@ -24,10 +24,6 @@ class DownloadHistory {
public:
typedef Callback2<int32, bool>::Type VisitedBeforeDoneCallback;
- // A fake download table ID which represents a download that has started,
- // but is not yet in the table.
- static const int kUninitializedHandle;
-
explicit DownloadHistory(Profile* profile);
~DownloadHistory();
diff --git a/chrome/browser/download/download_manager_unittest.cc b/chrome/browser/download/download_manager_unittest.cc
index 101db74..cd1a66c 100644
--- a/chrome/browser/download/download_manager_unittest.cc
+++ b/chrome/browser/download/download_manager_unittest.cc
@@ -50,8 +50,8 @@ class DownloadManagerTest : public TestingBrowserProcessTest {
download_manager_delegate_, &download_status_updater_)),
ui_thread_(BrowserThread::UI, &message_loop_),
file_thread_(BrowserThread::FILE, &message_loop_) {
- download_manager_delegate_->set_download_manager(download_manager_);
download_manager_->Init(profile_.get());
+ download_manager_delegate_->SetDownloadManager(download_manager_);
}
~DownloadManagerTest() {
diff --git a/chrome/browser/download/mock_download_manager_delegate.cc b/chrome/browser/download/mock_download_manager_delegate.cc
index b597f61..dba9613b 100644
--- a/chrome/browser/download/mock_download_manager_delegate.cc
+++ b/chrome/browser/download/mock_download_manager_delegate.cc
@@ -7,6 +7,9 @@
MockDownloadManagerDelegate::~MockDownloadManagerDelegate() {
}
+void MockDownloadManagerDelegate::Shutdown() {
+}
+
bool MockDownloadManagerDelegate::ShouldStartDownload(int32 download_id) {
return true;
}
@@ -31,6 +34,27 @@ bool MockDownloadManagerDelegate::GenerateFileHash() {
return false;
}
+void MockDownloadManagerDelegate::AddItemToPersistentStore(DownloadItem* item) {
+}
+
+void MockDownloadManagerDelegate::UpdateItemInPersistentStore(
+ DownloadItem* item) {
+}
+
+void MockDownloadManagerDelegate::UpdatePathForItemInPersistentStore(
+ DownloadItem* item,
+ const FilePath& new_path) {
+}
+
+void MockDownloadManagerDelegate::RemoveItemFromPersistentStore(
+ DownloadItem* item) {
+}
+
+void MockDownloadManagerDelegate::RemoveItemsFromPersistentStoreBetween(
+ const base::Time remove_begin,
+ const base::Time remove_end) {
+}
+
void MockDownloadManagerDelegate::GetSaveDir(
TabContents* tab_contents,
FilePath* website_save_dir,
diff --git a/chrome/browser/download/mock_download_manager_delegate.h b/chrome/browser/download/mock_download_manager_delegate.h
index f68c7d5..68389d4 100644
--- a/chrome/browser/download/mock_download_manager_delegate.h
+++ b/chrome/browser/download/mock_download_manager_delegate.h
@@ -12,6 +12,7 @@
class MockDownloadManagerDelegate : public DownloadManagerDelegate {
public:
virtual ~MockDownloadManagerDelegate();
+ virtual void Shutdown() OVERRIDE;
virtual bool ShouldStartDownload(int32 download_id) OVERRIDE;
virtual void ChooseDownloadPath(TabContents* tab_contents,
const FilePath& suggested_path,
@@ -19,6 +20,15 @@ class MockDownloadManagerDelegate : public DownloadManagerDelegate {
virtual TabContents* GetAlternativeTabContentsToNotifyForDownload() OVERRIDE;
virtual bool ShouldOpenFileBasedOnExtension(const FilePath& path) OVERRIDE;
virtual bool GenerateFileHash() OVERRIDE;
+ virtual void AddItemToPersistentStore(DownloadItem* item) OVERRIDE;
+ virtual void UpdateItemInPersistentStore(DownloadItem* item) OVERRIDE;
+ virtual void UpdatePathForItemInPersistentStore(
+ DownloadItem* item,
+ const FilePath& new_path) OVERRIDE;
+ virtual void RemoveItemFromPersistentStore(DownloadItem* item) OVERRIDE;
+ virtual void RemoveItemsFromPersistentStoreBetween(
+ const base::Time remove_begin,
+ const base::Time remove_end) OVERRIDE;
virtual void GetSaveDir(TabContents* tab_contents,
FilePath* website_save_dir,
FilePath* download_save_dir) OVERRIDE;
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index 2562d6a..288c6462 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -7,6 +7,7 @@
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/history/download_history_info.h"
#include "chrome/browser/profiles/profile.h"
@@ -112,7 +113,10 @@ class SavePageBrowserTest : public InProcessBrowserTest {
void QueryDownloadHistory() {
// Query the history system.
- GetDownloadManager()->download_history()->Load(
+ ChromeDownloadManagerDelegate* delegate =
+ static_cast<ChromeDownloadManagerDelegate*>(
+ GetDownloadManager()->delegate());
+ delegate->download_history()->Load(
NewCallback(this,
&SavePageBrowserTest::OnQueryDownloadEntriesComplete));
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 5a03192..8ba3294 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -468,8 +468,8 @@ class OffTheRecordProfileImpl : public Profile,
scoped_refptr<DownloadManager> dlm(
new DownloadManager(download_manager_delegate_,
g_browser_process->download_status_updater()));
- download_manager_delegate_->set_download_manager(dlm);
dlm->Init(this);
+ download_manager_delegate_->SetDownloadManager(dlm);
download_manager_.swap(dlm);
}
return download_manager_.get();
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index b8b89a8..746e0ce 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1255,8 +1255,8 @@ DownloadManager* ProfileImpl::GetDownloadManager() {
scoped_refptr<DownloadManager> dlm(
new DownloadManager(download_manager_delegate_,
g_browser_process->download_status_updater()));
- download_manager_delegate_->set_download_manager(dlm);
dlm->Init(this);
+ download_manager_delegate_->SetDownloadManager(dlm);
created_download_manager_ = true;
download_manager_.swap(dlm);
}
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads_dom_handler.cc
index 6c9b208..4d6670d 100644
--- a/chrome/browser/ui/webui/downloads_dom_handler.cc
+++ b/chrome/browser/ui/webui/downloads_dom_handler.cc
@@ -197,7 +197,7 @@ void DownloadsDOMHandler::ModelChanged() {
// fixed.
// We should never see anything that isn't already in the history.
CHECK(*it);
- CHECK_NE(DownloadHistory::kUninitializedHandle, (*it)->db_handle());
+ CHECK_NE(DownloadItem::kUninitializedHandle, (*it)->db_handle());
(*it)->AddObserver(this);
}
@@ -266,7 +266,7 @@ void DownloadsDOMHandler::HandleRemove(const ListValue* args) {
DownloadItem* file = GetDownloadByValue(args);
if (file) {
// TODO(rdsmith): Change to DCHECK when http://crbug.com/84508 is fixed.
- CHECK_NE(DownloadHistory::kUninitializedHandle, file->db_handle());
+ CHECK_NE(DownloadItem::kUninitializedHandle, file->db_handle());
file->Remove();
}
}
diff --git a/content/browser/download/download_file_manager.cc b/content/browser/download/download_file_manager.cc
index 09bb2ba..399f72b 100644
--- a/content/browser/download/download_file_manager.cc
+++ b/content/browser/download/download_file_manager.cc
@@ -28,8 +28,7 @@ const int kUpdatePeriodMs = 500;
} // namespace
DownloadFileManager::DownloadFileManager(ResourceDispatcherHost* rdh)
- : next_id_(0),
- resource_dispatcher_host_(rdh) {
+ : resource_dispatcher_host_(rdh) {
}
DownloadFileManager::~DownloadFileManager() {
@@ -114,11 +113,8 @@ void DownloadFileManager::UpdateInProgressDownloads() {
}
}
-// Called on the IO thread once the ResourceDispatcherHost has decided that a
-// request is a download.
int DownloadFileManager::GetNextId() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- return next_id_++;
+ return next_id_.GetNext();
}
void DownloadFileManager::StartDownload(DownloadCreateInfo* info) {
diff --git a/content/browser/download/download_file_manager.h b/content/browser/download/download_file_manager.h
index 45cef5e..0c14dca 100644
--- a/content/browser/download/download_file_manager.h
+++ b/content/browser/download/download_file_manager.h
@@ -42,6 +42,7 @@
#include <map>
+#include "base/atomic_sequence_num.h"
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/hash_tables.h"
@@ -72,7 +73,7 @@ class DownloadFileManager
// Called on shutdown on the UI thread.
void Shutdown();
- // Called on the IO thread
+ // Called on the IO or UI threads.
int GetNextId();
// Called on UI thread to make DownloadFileManager start the download.
@@ -153,8 +154,8 @@ class DownloadFileManager
// it from the maps.
void EraseDownload(int id);
- // Unique ID for each DownloadFile.
- int next_id_;
+ // Unique ID for each DownloadItem.
+ base::AtomicSequenceNumber next_id_;
typedef base::hash_map<int, DownloadFile*> DownloadFileMap;
diff --git a/content/browser/download/download_item.cc b/content/browser/download/download_item.cc
index 6423110..2fdf2a3 100644
--- a/content/browser/download/download_item.cc
+++ b/content/browser/download/download_item.cc
@@ -16,7 +16,6 @@
#include "net/base/net_util.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/download/download_extensions.h"
-#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/history/download_history_info.h"
@@ -116,6 +115,13 @@ DownloadItem::DangerType GetDangerType(bool dangerous_file,
} // namespace
+// Our download table ID starts at 1, so we use 0 to represent a download that
+// has started, but has not yet had its data persisted in the table. We use fake
+// database handles in incognito mode starting at -1 and progressively getting
+// more negative.
+// static
+const int DownloadItem::kUninitializedHandle = 0;
+
// Constructor for reading from the history service.
DownloadItem::DownloadItem(DownloadManager* download_manager,
const DownloadHistoryInfo& info)
@@ -171,7 +177,7 @@ DownloadItem::DownloadItem(DownloadManager* download_manager,
start_tick_(base::TimeTicks::Now()),
state_(IN_PROGRESS),
start_time_(info.start_time),
- db_handle_(DownloadHistory::kUninitializedHandle),
+ db_handle_(DownloadItem::kUninitializedHandle),
download_manager_(download_manager),
is_paused_(false),
open_when_complete_(false),
@@ -190,8 +196,9 @@ DownloadItem::DownloadItem(DownloadManager* download_manager,
DownloadItem::DownloadItem(DownloadManager* download_manager,
const FilePath& path,
const GURL& url,
- bool is_otr)
- : download_id_(download_manager->GetNextSavePageId()),
+ bool is_otr,
+ int download_id)
+ : download_id_(download_id),
full_path_(path),
url_chain_(1, url),
referrer_url_(GURL()),
@@ -201,7 +208,7 @@ DownloadItem::DownloadItem(DownloadManager* download_manager,
start_tick_(base::TimeTicks::Now()),
state_(IN_PROGRESS),
start_time_(base::Time::Now()),
- db_handle_(DownloadHistory::kUninitializedHandle),
+ db_handle_(DownloadItem::kUninitializedHandle),
download_manager_(download_manager),
is_paused_(false),
open_when_complete_(false),
diff --git a/content/browser/download/download_item.h b/content/browser/download/download_item.h
index a2fd5d4..72046f8 100644
--- a/content/browser/download/download_item.h
+++ b/content/browser/download/download_item.h
@@ -94,6 +94,10 @@ class DownloadItem : public NotificationObserver {
DELETE_DUE_TO_USER_DISCARD
};
+ // A fake download table ID which represents a download that has started,
+ // but is not yet in the table.
+ static const int kUninitializedHandle;
+
// Interface that observers of a particular download must implement in order
// to receive updates to the download's status.
class Observer {
@@ -120,7 +124,8 @@ class DownloadItem : public NotificationObserver {
DownloadItem(DownloadManager* download_manager,
const FilePath& path,
const GURL& url,
- bool is_otr);
+ bool is_otr,
+ int download_id);
virtual ~DownloadItem();
diff --git a/content/browser/download/download_manager.cc b/content/browser/download/download_manager.cc
index 4fc121f..1e20f1a 100644
--- a/content/browser/download/download_manager.cc
+++ b/content/browser/download/download_manager.cc
@@ -13,7 +13,6 @@
#include "base/stl_util.h"
#include "base/task.h"
#include "build/build_config.h"
-#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/history/download_history_info.h"
#include "chrome/browser/profiles/profile.h"
@@ -61,7 +60,6 @@ DownloadManager::DownloadManager(DownloadManagerDelegate* delegate,
browser_context_(NULL),
file_manager_(NULL),
status_updater_(status_updater->AsWeakPtr()),
- next_save_page_id_(0),
delegate_(delegate) {
if (status_updater_)
status_updater_->AddDelegate(this);
@@ -114,7 +112,7 @@ void DownloadManager::Shutdown() {
download->Delete(DownloadItem::DELETE_DUE_TO_BROWSER_SHUTDOWN);
} else if (download->IsPartialDownload()) {
download->Cancel(false);
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
}
}
@@ -135,8 +133,7 @@ void DownloadManager::Shutdown() {
DCHECK(save_page_downloads_.empty());
file_manager_ = NULL;
-
- download_history_.reset();
+ delegate_->Shutdown();
shutdown_needed_ = false;
}
@@ -194,10 +191,6 @@ bool DownloadManager::Init(content::BrowserContext* browser_context) {
shutdown_needed_ = true;
browser_context_ = browser_context;
- download_history_.reset(new DownloadHistory(
- Profile::FromBrowserContext(browser_context)));
- download_history_->Load(
- NewCallback(this, &DownloadManager::OnQueryDownloadEntriesComplete));
// In test mode, there may be no ResourceDispatcherHost. In this case it's
// safe to avoid setting |file_manager_| because we only call a small set of
@@ -356,8 +349,7 @@ void DownloadManager::ContinueDownloadWithPath(DownloadItem* download,
download->Rename(download_path);
- download_history_->AddEntry(download,
- NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete));
+ delegate_->AddItemToPersistentStore(download);
}
void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
@@ -368,7 +360,7 @@ void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
if (download->IsInProgress()) {
download->Update(size);
UpdateDownloadProgress(); // Reflect size updates.
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
}
}
}
@@ -422,7 +414,7 @@ void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) {
CHECK(ContainsKey(downloads_, download));
// Check history_downloads_ consistency.
- if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
+ if (download->db_handle() != DownloadItem::kUninitializedHandle) {
CHECK(ContainsKey(history_downloads_, download->db_handle()));
} else {
// TODO(rdsmith): Somewhat painful; make sure to disable in
@@ -458,7 +450,7 @@ bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) {
// 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)
+ if (download->db_handle() == DownloadItem::kUninitializedHandle)
return false;
return true;
@@ -481,7 +473,7 @@ void DownloadManager::MaybeCompleteDownload(DownloadItem* download) {
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(download->db_handle() != DownloadItem::kUninitializedHandle);
DCHECK_EQ(1u, history_downloads_.count(download->db_handle()));
VLOG(20) << __FUNCTION__ << "()" << " executing: download = "
@@ -491,7 +483,7 @@ void DownloadManager::MaybeCompleteDownload(DownloadItem* download) {
in_progress_.erase(download->id());
UpdateDownloadProgress(); // Reflect removal from in_progress_.
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
// Finish the download.
download->OnDownloadCompleting(file_manager_);
@@ -501,7 +493,7 @@ void DownloadManager::DownloadCompleted(int32 download_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetDownloadItem(download_id);
DCHECK(download);
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
active_downloads_.erase(download_id);
}
@@ -530,7 +522,7 @@ void DownloadManager::OnDownloadRenamedToFinalName(int download_id,
item->set_path_uniquifier(uniquifier);
item->OnDownloadRenamedToFinalName(full_path);
- download_history_->UpdateDownloadPath(item, full_path);
+ delegate_->UpdatePathForItemInPersistentStore(item, full_path);
}
void DownloadManager::DownloadCancelled(int32 download_id) {
@@ -545,11 +537,11 @@ void DownloadManager::DownloadCancelled(int32 download_id) {
// 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) {
+ if (download->db_handle() != DownloadItem::kUninitializedHandle) {
in_progress_.erase(it);
active_downloads_.erase(download_id);
UpdateDownloadProgress(); // Reflect removal from in_progress_.
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
}
DownloadCancelledInternal(download_id, download->request_handle());
@@ -589,11 +581,11 @@ void DownloadManager::OnDownloadError(int32 download_id,
//
// 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) {
+ if (download->db_handle() != DownloadItem::kUninitializedHandle) {
in_progress_.erase(download_id);
active_downloads_.erase(download_id);
UpdateDownloadProgress(); // Reflect removal from in_progress_.
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
}
BrowserThread::PostTask(
@@ -638,7 +630,7 @@ void DownloadManager::RemoveDownload(int64 download_handle) {
// Make history update.
DownloadItem* download = it->second;
- download_history_->RemoveEntry(download);
+ delegate_->RemoveItemFromPersistentStore(download);
// Remove from our tables and delete.
int downloads_count = RemoveDownloadItems(DownloadVector(1, download));
@@ -647,7 +639,7 @@ void DownloadManager::RemoveDownload(int64 download_handle) {
int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin,
const base::Time remove_end) {
- download_history_->RemoveEntriesBetween(remove_begin, remove_end);
+ delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end);
// All downloads visible to the user will be in the history,
// so scan that map.
@@ -792,7 +784,7 @@ void DownloadManager::FileSelectionCanceled(void* params) {
// The history service has retrieved all download entries. 'entries' contains
// 'DownloadHistoryInfo's in sorted order (by ascending start_time).
-void DownloadManager::OnQueryDownloadEntriesComplete(
+void DownloadManager::OnPersistentStoreQueryComplete(
std::vector<DownloadHistoryInfo>* entries) {
for (size_t i = 0; i < entries->size(); ++i) {
DownloadItem* download = new DownloadItem(this, entries->at(i));
@@ -810,19 +802,11 @@ void DownloadManager::AddDownloadItemToHistory(DownloadItem* download,
int64 db_handle) {
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);
+ CHECK_NE(DownloadItem::kUninitializedHandle, db_handle);
- DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
+ DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle);
download->set_db_handle(db_handle);
DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
@@ -836,11 +820,22 @@ void DownloadManager::AddDownloadItemToHistory(DownloadItem* download,
NotifyModelChanged();
}
+
+void DownloadManager::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);
+ }
+ // It's valid that we don't find a matching item, i.e. on shutdown.
+}
+
// 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::OnDownloadItemAddedToPersistentStore(int32 download_id,
+ int64 db_handle) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* download = GetActiveDownloadItem(download_id);
if (!download)
@@ -866,7 +861,7 @@ void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
<< " download = " << download->DebugString(true);
in_progress_.erase(download_id);
active_downloads_.erase(download_id);
- download_history_->UpdateEntry(download);
+ delegate_->UpdateItemInPersistentStore(download);
download->UpdateObservers();
}
}
@@ -966,16 +961,15 @@ void DownloadManager::SavePageDownloadStarted(DownloadItem* download) {
// Add this entry to the history service.
// Additionally, the UI is notified in the callback.
- download_history_->AddEntry(download,
- NewCallback(this, &DownloadManager::OnSavePageDownloadEntryAdded));
+ delegate_->AddItemToPersistentStore(download);
}
// SavePackage will call SavePageDownloadFinished upon completion/cancellation.
-// The history callback will call OnSavePageDownloadEntryAdded.
+// The history callback will call OnSavePageItemAddedToPersistentStore.
// If the download finishes before the history callback,
-// OnSavePageDownloadEntryAdded calls SavePageDownloadFinished, ensuring that
-// the history event is update regardless of the order in which these two events
-// complete.
+// 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
@@ -984,8 +978,8 @@ void DownloadManager::SavePageDownloadStarted(DownloadItem* download) {
// Initiation -> History Callback -> Removal -> Completion), but there's no way
// to solve that without canceling on Remove (which would then update the DB).
-void DownloadManager::OnSavePageDownloadEntryAdded(int32 download_id,
- int64 db_handle) {
+void DownloadManager::OnSavePageItemAddedToPersistentStore(int32 download_id,
+ int64 db_handle) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadMap::const_iterator it = save_page_downloads_.find(download_id);
@@ -1008,8 +1002,8 @@ void DownloadManager::OnSavePageDownloadEntryAdded(int32 download_id,
}
void DownloadManager::SavePageDownloadFinished(DownloadItem* download) {
- if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
- download_history_->UpdateEntry(download);
+ if (download->db_handle() != DownloadItem::kUninitializedHandle) {
+ delegate_->UpdateItemInPersistentStore(download);
DCHECK(ContainsKey(save_page_downloads_, download->id()));
save_page_downloads_.erase(download->id());
@@ -1020,9 +1014,3 @@ void DownloadManager::SavePageDownloadFinished(DownloadItem* download) {
Details<DownloadItem>(download));
}
}
-
-int32 DownloadManager::GetNextSavePageId() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return next_save_page_id_++;
-}
-
diff --git a/content/browser/download/download_manager.h b/content/browser/download/download_manager.h
index 0720989..8c8767b 100644
--- a/content/browser/download/download_manager.h
+++ b/content/browser/download/download_manager.h
@@ -48,14 +48,12 @@
#include "content/browser/download/download_status_updater_delegate.h"
class DownloadFileManager;
-class DownloadHistory;
class DownloadManagerDelegate;
class DownloadStatusUpdater;
class GURL;
class ResourceDispatcherHost;
class TabContents;
struct DownloadCreateInfo;
-struct DownloadHistoryInfo;
struct DownloadSaveInfo;
namespace content {
@@ -181,10 +179,14 @@ class DownloadManager
// Remove a download observer from ourself.
void RemoveObserver(Observer* observer);
- // Methods called on completion of a query sent to the history system.
- void OnQueryDownloadEntriesComplete(
+ // Called by the embedder, after creating the download manager, to let it know
+ // about downloads from previous runs of the browser.
+ void OnPersistentStoreQueryComplete(
std::vector<DownloadHistoryInfo>* entries);
- void OnCreateDownloadEntryComplete(int32 download_id, int64 db_handle);
+
+ // Called by the embedder, in response to
+ // DownloadManagerDelegate::AddItemToPersistentStore.
+ void OnItemAddedToPersistentStore(int32 download_id, int64 db_handle);
// Display a new download in the appropriate browser UI.
void ShowDownloadInBrowser(DownloadItem* download);
@@ -196,8 +198,6 @@ class DownloadManager
content::BrowserContext* browser_context() { return browser_context_; }
- DownloadHistory* download_history() { return download_history_.get(); }
-
FilePath last_download_path() { return last_download_path_; }
// Creates the download item. Must be called on the UI thread.
@@ -242,15 +242,9 @@ class DownloadManager
// to the DownloadManager.
void SavePageDownloadStarted(DownloadItem* download);
- // Callback when Save Page As entry is commited to the history system.
- void OnSavePageDownloadEntryAdded(int32 download_id, int64 db_handle);
-
// Called when Save Page download is done.
void SavePageDownloadFinished(DownloadItem* download);
- // Download Id for next Save Page.
- int32 GetNextSavePageId();
-
// Get the download item from the active map. Useful when the item is not
// yet in the history map.
DownloadItem* GetActiveDownloadItem(int id);
@@ -312,13 +306,19 @@ class DownloadManager
// Remove from internal maps.
int RemoveDownloadItems(const DownloadVector& pending_deletes);
+ // Called when a download entry is committed to the persistent store.
+ void OnDownloadItemAddedToPersistentStore(int32 download_id, int64 db_handle);
+
+ // Called when Save Page As entry is commited to the persistent store.
+ void OnSavePageItemAddedToPersistentStore(int32 download_id, int64 db_handle);
+
// |downloads_| is the owning set for all downloads known to the
// DownloadManager. This includes downloads started by the user in
// this session, downloads initialized from the history system, and
// "save page as" downloads. All other DownloadItem containers in
// the DownloadManager are maps; they do not own the DownloadItems.
// Note that this is the only place (with any functional implications;
- // see save_page_as_downloads_ below) that "save page as" downloads are
+ // see save_page_downloads_ below) that "save page as" downloads are
// kept, as the DownloadManager's only job is to hold onto those
// until destruction.
//
@@ -327,16 +327,17 @@ class DownloadManager
// sessions.
//
// |active_downloads_| is a map of all downloads that are currently being
- // processed. The key is the ID assigned by the ResourceDispatcherHost,
+ // processed. The key is the ID assigned by the DownloadFileManager,
// which is unique for the current session.
//
// |in_progress_| is a map of all downloads that are in progress and that have
// not yet received a valid history handle. The key is the ID assigned by the
- // ResourceDispatcherHost, which is unique for the current session.
+ // DownloadFileManager, which is unique for the current session.
//
- // |save_page_as_downloads_| (if defined) is a collection of all the
+ // |save_page_downloads_| (if defined) is a collection of all the
// downloads the "save page as" system has given to us to hold onto
- // until we are destroyed. It is only used for debugging.
+ // until we are destroyed. They key is DownloadFileManager, so it is unique
+ // compared to download item. It is only used for debugging.
//
// When a download is created through a user action, the corresponding
// DownloadItem* is placed in |active_downloads_| and remains there until the
@@ -364,8 +365,6 @@ class DownloadManager
// The current active browser context.
content::BrowserContext* browser_context_;
- scoped_ptr<DownloadHistory> download_history_;
-
// Non-owning pointer for handling file writing on the download_thread_.
DownloadFileManager* file_manager_;
@@ -376,9 +375,6 @@ class DownloadManager
// user wants us to prompt for a save location for each download.
FilePath last_download_path_;
- // Download Id for next Save Page.
- int32 next_save_page_id_;
-
// Allows an embedder to control behavior. Guaranteed to outlive this object.
DownloadManagerDelegate* delegate_;
diff --git a/content/browser/download/download_manager_delegate.h b/content/browser/download/download_manager_delegate.h
index b969d1a..fd2e2d6 100644
--- a/content/browser/download/download_manager_delegate.h
+++ b/content/browser/download/download_manager_delegate.h
@@ -8,7 +8,9 @@
#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
+#include "base/time.h"
+class DownloadItem;
class FilePath;
class TabContents;
class SavePackage;
@@ -16,6 +18,9 @@ class SavePackage;
// Browser's download manager: manages all downloads and destination view.
class DownloadManagerDelegate {
public:
+ // Lets the delegate know that the download manager is shutting down.
+ virtual void Shutdown() = 0;
+
// Notifies the delegate that a download is starting. The delegate can return
// false to delay the start of the download, in which case it should call
// DownloadManager::RestartDownload when it's ready.
@@ -39,6 +44,31 @@ class DownloadManagerDelegate {
// Returns true if we need to generate a binary hash for downloads.
virtual bool GenerateFileHash() = 0;
+ // Notifies the embedder that a new download item is created. The
+ // DownloadManager waits for the embedder to add information about this
+ // download to its persistent store. When the embedder is done, it calls
+ // DownloadManager::OnDownloadItemAddedToPersistentStore.
+ virtual void AddItemToPersistentStore(DownloadItem* item) = 0;
+
+ // Notifies the embedder that information about the given download has change,
+ // so that it can update its persistent store.
+ virtual void UpdateItemInPersistentStore(DownloadItem* item) = 0;
+
+ // Notifies the embedder that path for the download item has changed, so that
+ // it can update its persistent store.
+ virtual void UpdatePathForItemInPersistentStore(
+ DownloadItem* item,
+ const FilePath& new_path) = 0;
+
+ // Notifies the embedder that it should remove the download item from its
+ // persistent store.
+ virtual void RemoveItemFromPersistentStore(DownloadItem* item) = 0;
+
+ // Notifies the embedder to remove downloads from the given time range.
+ virtual void RemoveItemsFromPersistentStoreBetween(
+ const base::Time remove_begin,
+ const base::Time remove_end) = 0;
+
// Retrieve the directories to save html pages and downloads to.
virtual void GetSaveDir(TabContents* tab_contents,
FilePath* website_save_dir,
diff --git a/content/browser/download/save_file_manager.h b/content/browser/download/save_file_manager.h
index fb6a9a2..5f555ed 100644
--- a/content/browser/download/save_file_manager.h
+++ b/content/browser/download/save_file_manager.h
@@ -89,7 +89,9 @@ class SaveFileManager
// Lifetime management.
void Shutdown();
- // Called on the IO thread
+ // Called on the IO thread. This generates unique IDs for
+ // SaveFileResourceHandler objects (there's one per file in a SavePackage).
+ // Note that this is different from the SavePackage's id.
int GetNextId();
// Save the specified URL. Called on the UI thread and forwarded to the
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index 80da266..5cb56df 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -21,6 +21,7 @@
#include "content/browser/browser_context.h"
#include "content/browser/browser_thread.h"
#include "content/browser/content_browser_client.h"
+#include "content/browser/download/download_file_manager.h"
#include "content/browser/download/download_item.h"
#include "content/browser/download/download_manager.h"
#include "content/browser/download/download_manager_delegate.h"
@@ -262,12 +263,15 @@ bool SavePackage::Init() {
return false;
}
- DCHECK(download_manager_);
+ ResourceDispatcherHost* rdh =
+ content::GetContentClient()->browser()->GetResourceDispatcherHost();
+
// Create the download item, and add ourself as an observer.
download_ = new DownloadItem(download_manager_,
saved_main_file_path_,
page_url_,
- browser_context->IsOffTheRecord());
+ browser_context->IsOffTheRecord(),
+ rdh->download_file_manager()->GetNextId());
download_->AddObserver(this);
// Transfer ownership to the download manager.