summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-04 16:57:54 +0000
committerrdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-04 16:57:54 +0000
commit75e51b57f3c654ec88b3f8bd59f0b185f34576f6 (patch)
treed1874d3b0938e2ca000579d130f398fd6c513575 /chrome
parentd333dfc2314dae9f47f5d0a7bbdc62807be33ebb (diff)
downloadchromium_src-75e51b57f3c654ec88b3f8bd59f0b185f34576f6.zip
chromium_src-75e51b57f3c654ec88b3f8bd59f0b185f34576f6.tar.gz
chromium_src-75e51b57f3c654ec88b3f8bd59f0b185f34576f6.tar.bz2
Remove DownloadManager* dependency on DownloadStatusUpdater
by making DownloadStatusUpdater an observer of DownloadManager. BUG=107264 Review URL: http://codereview.chromium.org/9005027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120487 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc11
-rw-r--r--chrome/browser/automation/automation_provider_observers.h12
-rw-r--r--chrome/browser/browser_process_impl.cc2
-rw-r--r--chrome/browser/chromeos/imageburner/burn_controller.cc29
-rw-r--r--chrome/browser/chromeos/imageburner/burn_manager.cc4
-rw-r--r--chrome/browser/chromeos/imageburner/burn_manager.h6
-rw-r--r--chrome/browser/download/chrome_download_manager_delegate.cc2
-rw-r--r--chrome/browser/download/download_browsertest.cc5
-rw-r--r--chrome/browser/download/download_extension_api.cc8
-rw-r--r--chrome/browser/download/download_extension_api.h4
-rw-r--r--chrome/browser/download/download_file_picker.cc7
-rw-r--r--chrome/browser/download/download_file_picker.h6
-rw-r--r--chrome/browser/download/download_query_unittest.cc6
-rw-r--r--chrome/browser/download/download_service.cc11
-rw-r--r--chrome/browser/download/download_status_updater.cc101
-rw-r--r--chrome/browser/download/download_status_updater.h55
-rw-r--r--chrome/browser/download/download_status_updater_unittest.cc283
-rw-r--r--chrome/browser/download/download_test_observer.cc17
-rw-r--r--chrome/browser/download/download_test_observer.h9
-rw-r--r--chrome/browser/history/history_database.h4
-rw-r--r--chrome/browser/ui/cocoa/download/download_item_mac.h4
-rw-r--r--chrome/browser/ui/gtk/download/download_item_gtk.h4
-rw-r--r--chrome/browser/ui/panels/panel_browsertest.cc4
-rw-r--r--chrome/browser/ui/views/download/download_item_view.cc6
-rw-r--r--chrome/browser/ui/webui/active_downloads_ui.cc4
-rw-r--r--chrome/browser/ui/webui/downloads_dom_handler.cc136
-rw-r--r--chrome/browser/ui/webui/downloads_dom_handler.h17
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
29 files changed, 600 insertions, 160 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index ef8664b..fd8f69a 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -1592,7 +1592,10 @@ AutomationProviderDownloadModelChangedObserver(
AutomationProviderDownloadModelChangedObserver::
~AutomationProviderDownloadModelChangedObserver() {}
-void AutomationProviderDownloadModelChangedObserver::ModelChanged() {
+void AutomationProviderDownloadModelChangedObserver::ModelChanged(
+ DownloadManager* manager) {
+ DCHECK_EQ(manager, download_manager_);
+
download_manager_->RemoveObserver(this);
if (provider_)
@@ -1625,7 +1628,8 @@ AllDownloadsCompleteObserver::AllDownloadsCompleteObserver(
AllDownloadsCompleteObserver::~AllDownloadsCompleteObserver() {}
-void AllDownloadsCompleteObserver::ModelChanged() {
+void AllDownloadsCompleteObserver::ModelChanged(DownloadManager* manager) {
+ DCHECK_EQ(manager, download_manager_);
// The set of downloads in the download manager has changed. If there are
// any new downloads that are still in progress, add them to the pending list.
std::vector<DownloadItem*> downloads;
@@ -1641,8 +1645,7 @@ void AllDownloadsCompleteObserver::ModelChanged() {
ReplyIfNecessary();
}
-void AllDownloadsCompleteObserver::OnDownloadUpdated(
- content::DownloadItem* download) {
+void AllDownloadsCompleteObserver::OnDownloadUpdated(DownloadItem* download) {
// If the current download's status has changed to a final state (not state
// "in progress"), remove it from the pending list.
if (download->GetState() != DownloadItem::IN_PROGRESS) {
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 3a7472d..a5e681b 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -1117,7 +1117,7 @@ class AutomationProviderDownloadModelChangedObserver
content::DownloadManager* download_manager);
virtual ~AutomationProviderDownloadModelChangedObserver();
- virtual void ModelChanged();
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
private:
base::WeakPtr<AutomationProvider> provider_;
@@ -1139,12 +1139,12 @@ class AllDownloadsCompleteObserver
ListValue* pre_download_ids);
virtual ~AllDownloadsCompleteObserver();
- // DownloadManager::Observer.
- virtual void ModelChanged();
+ // content::DownloadManager::Observer.
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
- // DownloadItem::Observer.
- virtual void OnDownloadUpdated(content::DownloadItem* download);
- virtual void OnDownloadOpened(content::DownloadItem* download) {}
+ // content::DownloadItem::Observer.
+ virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
+ virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE {}
private:
void ReplyIfNecessary();
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index ba2bd92..f434f60 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -25,6 +25,7 @@
#include "chrome/browser/component_updater/component_updater_service.h"
#include "chrome/browser/debugger/remote_debugging_server.h"
#include "chrome/browser/download/download_request_limiter.h"
+#include "chrome/browser/download/download_status_updater.h"
#include "chrome/browser/extensions/extension_event_router_forwarder.h"
#include "chrome/browser/extensions/extension_tab_id_map.h"
#include "chrome/browser/extensions/network_delay_listener.h"
@@ -67,7 +68,6 @@
#include "chrome/common/url_constants.h"
#include "chrome/installer/util/google_update_constants.h"
#include "content/browser/child_process_security_policy.h"
-#include "content/browser/download/download_status_updater.h"
#include "content/browser/download/mhtml_generation_manager.h"
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/net/browser_online_state_observer.h"
diff --git a/chrome/browser/chromeos/imageburner/burn_controller.cc b/chrome/browser/chromeos/imageburner/burn_controller.cc
index 15f85c1..f2ae353 100644
--- a/chrome/browser/chromeos/imageburner/burn_controller.cc
+++ b/chrome/browser/chromeos/imageburner/burn_controller.cc
@@ -19,8 +19,6 @@
#include "grit/generated_resources.h"
#include "googleurl/src/gurl.h"
-using content::DownloadItem;
-
namespace chromeos {
namespace imageburner {
@@ -46,7 +44,7 @@ class BurnControllerImpl
public disks::DiskMountManager::Observer,
public BurnLibrary::Observer,
public NetworkLibrary::NetworkManagerObserver,
- public DownloadItem::Observer,
+ public content::DownloadItem::Observer,
public content::DownloadManager::Observer,
public Downloader::Listener,
public StateMachine::Observer,
@@ -143,8 +141,8 @@ class BurnControllerImpl
ProcessError(IDS_IMAGEBURN_NETWORK_ERROR);
}
- // DownloadItem::Observer interface.
- virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE {
+ // content::DownloadItem::Observer interface.
+ virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE {
if (download->IsCancelled()) {
DownloadCompleted(false);
DCHECK(!active_download_item_);
@@ -162,22 +160,22 @@ class BurnControllerImpl
}
}
- virtual void OnDownloadOpened(DownloadItem* download) OVERRIDE {
- if (download->GetSafetyState() == DownloadItem::DANGEROUS)
+ virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE {
+ if (download->GetSafetyState() == content::DownloadItem::DANGEROUS)
download->DangerousDownloadValidated();
}
- // DownloadManager::Observer interface.
- virtual void ModelChanged() OVERRIDE {
+ // content::DownloadManager::Observer interface.
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE {
+ DCHECK_EQ(download_manager_, manager);
// Find our item and observe it.
- std::vector<DownloadItem*> downloads;
+ std::vector<content::DownloadItem*> downloads;
download_manager_->GetTemporaryDownloads(
burn_manager_->GetImageDir(), &downloads);
if (active_download_item_)
return;
- for (std::vector<DownloadItem*>::const_iterator it = downloads.begin();
- it != downloads.end();
- ++it) {
+ for (std::vector<content::DownloadItem*>::const_iterator it =
+ downloads.begin(); it != downloads.end(); ++it) {
if ((*it)->GetOriginalUrl() == image_download_url_) {
(*it)->AddObserver(this);
active_download_item_ = *it;
@@ -379,7 +377,8 @@ class BurnControllerImpl
active_download_item_->RemoveObserver(this);
if (active_download_item_->IsPartialDownload())
active_download_item_->Cancel(true);
- active_download_item_->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
+ active_download_item_->Delete(
+ content::DownloadItem::DELETE_DUE_TO_USER_DISCARD);
active_download_item_ = NULL;
CleanupDownloadObjects();
}
@@ -440,7 +439,7 @@ class BurnControllerImpl
std::string image_file_name_;
content::WebContents* web_contents_;
content::DownloadManager* download_manager_;
- DownloadItem* active_download_item_;
+ content::DownloadItem* active_download_item_;
BurnManager* burn_manager_;
StateMachine* state_machine_;
bool observing_burn_lib_;
diff --git a/chrome/browser/chromeos/imageburner/burn_manager.cc b/chrome/browser/chromeos/imageburner/burn_manager.cc
index 3b8db3f..502b588 100644
--- a/chrome/browser/chromeos/imageburner/burn_manager.cc
+++ b/chrome/browser/chromeos/imageburner/burn_manager.cc
@@ -294,7 +294,9 @@ void BurnManager::OnConfigFileDownloaded() {
weak_ptr_factory_.GetWeakPtr())));
}
-void BurnManager::ModelChanged() {
+void BurnManager::ModelChanged(DownloadManager* manager) {
+ DCHECK_EQ(download_manager_, manager);
+
std::vector<DownloadItem*> downloads;
download_manager_->GetTemporaryDownloads(GetImageDir(), &downloads);
if (download_item_observer_added_)
diff --git a/chrome/browser/chromeos/imageburner/burn_manager.h b/chrome/browser/chromeos/imageburner/burn_manager.h
index 50e6d10..a819a6a 100644
--- a/chrome/browser/chromeos/imageburner/burn_manager.h
+++ b/chrome/browser/chromeos/imageburner/burn_manager.h
@@ -32,7 +32,7 @@ class Downloader {
class Listener : public base::SupportsWeakPtr<Listener> {
public:
// After download starts download status updates can be followed through
- // DownloadItem::Observer interface.
+ // content::DownloadItem::Observer interface.
virtual void OnBurnDownloadStarted(bool success) = 0;
};
@@ -225,7 +225,7 @@ class BurnManager
virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE {}
// content::DownloadManager::Observer interface.
- virtual void ModelChanged() OVERRIDE;
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
// Downloader::Listener interface.
virtual void OnBurnDownloadStarted(bool success) OVERRIDE;
@@ -306,5 +306,7 @@ class BurnManager
};
} // namespace imageburner
+
} // namespace chromeos
+
#endif // CHROME_BROWSER_CHROMEOS_IMAGEBURNER_BURN_MANAGER_H_
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index 9793901..04746e5 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/download/download_file_picker.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/download/download_status_updater.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/download/save_package_file_picker.h"
#include "chrome/browser/extensions/crx_installer.h"
@@ -32,7 +33,6 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/pref_names.h"
-#include "content/browser/download/download_status_updater.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 4759591..1cf1b05 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -254,7 +254,7 @@ static DownloadManager* DownloadManagerForBrowser(Browser* browser) {
// While an object of this class exists, it will mock out download
// opening for all downloads created on the specified download manager.
-class MockDownloadOpeningObserver : public content::DownloadManager::Observer {
+class MockDownloadOpeningObserver : public DownloadManager::Observer {
public:
explicit MockDownloadOpeningObserver(DownloadManager* manager)
: download_manager_(manager) {
@@ -266,7 +266,8 @@ class MockDownloadOpeningObserver : public content::DownloadManager::Observer {
}
// DownloadManager::Observer
- virtual void ModelChanged() {
+ virtual void ModelChanged(DownloadManager* manager) OVERRIDE {
+ DCHECK_EQ(manager, download_manager_);
std::vector<DownloadItem*> downloads;
download_manager_->SearchDownloads(string16(), &downloads);
diff --git a/chrome/browser/download/download_extension_api.cc b/chrome/browser/download/download_extension_api.cc
index 803404d..4d3fd55 100644
--- a/chrome/browser/download/download_extension_api.cc
+++ b/chrome/browser/download/download_extension_api.cc
@@ -884,10 +884,9 @@ ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() {
manager_->RemoveObserver(this);
}
-void ExtensionDownloadsEventRouter::ModelChanged() {
+void ExtensionDownloadsEventRouter::ModelChanged(DownloadManager* manager) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (manager_ == NULL)
- return;
+ DCHECK(manager_ == manager);
DownloadManager::DownloadVector current_vec;
manager_->SearchDownloads(string16(), &current_vec);
DownloadIdSet current_set;
@@ -929,7 +928,8 @@ void ExtensionDownloadsEventRouter::ModelChanged() {
downloads_.swap(current_set);
}
-void ExtensionDownloadsEventRouter::ManagerGoingDown() {
+void ExtensionDownloadsEventRouter::ManagerGoingDown(
+ DownloadManager* manager) {
manager_->RemoveObserver(this);
manager_ = NULL;
}
diff --git a/chrome/browser/download/download_extension_api.h b/chrome/browser/download/download_extension_api.h
index 348425e..0fc7be2 100644
--- a/chrome/browser/download/download_extension_api.h
+++ b/chrome/browser/download/download_extension_api.h
@@ -307,8 +307,8 @@ class ExtensionDownloadsEventRouter
explicit ExtensionDownloadsEventRouter(Profile* profile);
virtual ~ExtensionDownloadsEventRouter();
- virtual void ModelChanged() OVERRIDE;
- virtual void ManagerGoingDown() OVERRIDE;
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE;
private:
void Init(content::DownloadManager* manager);
diff --git a/chrome/browser/download/download_file_picker.cc b/chrome/browser/download/download_file_picker.cc
index 2451ce6..4db364b 100644
--- a/chrome/browser/download/download_file_picker.cc
+++ b/chrome/browser/download/download_file_picker.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -42,10 +42,11 @@ DownloadFilePicker::DownloadFilePicker(
DownloadFilePicker::~DownloadFilePicker() {
}
-void DownloadFilePicker::ModelChanged() {
+void DownloadFilePicker::ModelChanged(DownloadManager* manager) {
}
-void DownloadFilePicker::ManagerGoingDown() {
+void DownloadFilePicker::ManagerGoingDown(DownloadManager* manager) {
+ DCHECK_EQ(download_manager_, manager);
download_manager_ = NULL;
}
diff --git a/chrome/browser/download/download_file_picker.h b/chrome/browser/download/download_file_picker.h
index f7d7340..fdd16ad 100644
--- a/chrome/browser/download/download_file_picker.h
+++ b/chrome/browser/download/download_file_picker.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -27,8 +27,8 @@ class DownloadFilePicker : public content::DownloadManager::Observer,
private:
// content::DownloadManager::Observer implementation.
- virtual void ModelChanged() OVERRIDE;
- virtual void ManagerGoingDown() OVERRIDE;
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE;
// SelectFileDialog::Listener implementation.
virtual void FileSelected(const FilePath& path,
diff --git a/chrome/browser/download/download_query_unittest.cc b/chrome/browser/download/download_query_unittest.cc
index 2a5e465..2fb5e7b 100644
--- a/chrome/browser/download/download_query_unittest.cc
+++ b/chrome/browser/download/download_query_unittest.cc
@@ -49,11 +49,11 @@ class DownloadQueryTest : public testing::Test {
void CreateMocks(int count) {
for (int i = 0; i < count; ++i) {
- mocks_.push_back(new MockDownloadItem());
+ mocks_.push_back(new content::MockDownloadItem());
}
}
- MockDownloadItem& mock(int index) { return *mocks_[index]; }
+ content::MockDownloadItem& mock(int index) { return *mocks_[index]; }
DownloadQuery* query() { return &query_; }
@@ -67,7 +67,7 @@ class DownloadQueryTest : public testing::Test {
DownloadVector* results() { return &results_; }
private:
- std::vector<MockDownloadItem*> mocks_;
+ std::vector<content::MockDownloadItem*> mocks_;
DownloadQuery query_;
DownloadVector results_;
diff --git a/chrome/browser/download/download_service.cc b/chrome/browser/download/download_service.cc
index 65e1124..b58e0c2 100644
--- a/chrome/browser/download/download_service.cc
+++ b/chrome/browser/download/download_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/download/download_status_updater.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "content/public/browser/download_manager.h"
@@ -36,10 +37,14 @@ DownloadManager* DownloadService::GetDownloadManager() {
// SetDownloadManagerDelegateForTesting.
if (!manager_delegate_.get())
manager_delegate_ = new ChromeDownloadManagerDelegate(profile_);
- manager_ = DownloadManager::Create(
- manager_delegate_.get(), g_browser_process->download_status_updater());
+ manager_ = DownloadManager::Create(manager_delegate_.get());
manager_->Init(profile_);
manager_delegate_->SetDownloadManager(manager_);
+
+ // Include this download manager in the set monitored by the
+ // global status updater.
+ g_browser_process->download_status_updater()->AddManager(manager_);
+
download_manager_created_ = true;
for (std::vector<OnManagerCreatedCallback>::iterator cb
= on_manager_created_callbacks_.begin();
diff --git a/chrome/browser/download/download_status_updater.cc b/chrome/browser/download/download_status_updater.cc
new file mode 100644
index 0000000..d06df41
--- /dev/null
+++ b/chrome/browser/download/download_status_updater.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/download/download_status_updater.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+
+DownloadStatusUpdater::DownloadStatusUpdater() {
+}
+
+DownloadStatusUpdater::~DownloadStatusUpdater() {
+ for (std::set<content::DownloadManager*>::iterator it = managers_.begin();
+ it != managers_.end(); ++it)
+ (*it)->RemoveObserver(this);
+
+ for (std::set<content::DownloadItem*>::iterator it = items_.begin();
+ it != items_.end(); ++it)
+ (*it)->RemoveObserver(this);
+}
+
+bool DownloadStatusUpdater::GetProgress(float* progress,
+ int* download_count) const {
+ *progress = 0;
+ *download_count = items_.size();
+
+ int64 received_bytes = 0;
+ int64 total_bytes = 0;
+ for (std::set<content::DownloadItem*>::const_iterator it = items_.begin();
+ it != items_.end(); ++it) {
+ if ((*it)->GetTotalBytes() <= 0)
+ // We don't know how much more is coming down this pipe.
+ return false;
+ received_bytes += (*it)->GetReceivedBytes();
+ total_bytes += (*it)->GetTotalBytes();
+ }
+
+ if (total_bytes > 0)
+ *progress = static_cast<float>(received_bytes) / total_bytes;
+ return true;
+}
+
+void DownloadStatusUpdater::AddManager(content::DownloadManager* manager) {
+ DCHECK(!ContainsKey(managers_, manager));
+ managers_.insert(manager);
+ manager->AddObserver(this);
+}
+
+// Methods inherited from content::DownloadManager::Observer.
+void DownloadStatusUpdater::ModelChanged(content::DownloadManager* manager) {
+ std::vector<content::DownloadItem*> downloads;
+ manager->SearchDownloads(string16(), &downloads);
+
+ for (std::vector<content::DownloadItem*>::iterator it = downloads.begin();
+ it != downloads.end(); ++it) {
+ UpdateItem(*it);
+ }
+}
+
+void DownloadStatusUpdater::ManagerGoingDown(
+ content::DownloadManager* manager) {
+ DCHECK(ContainsKey(managers_, manager));
+ managers_.erase(manager);
+ manager->RemoveObserver(this);
+ // Item removal will be handled in response to DownloadItem REMOVING
+ // notification (in the !IN_PROGRESS conditional branch in UpdateItem).
+}
+
+void DownloadStatusUpdater::SelectFileDialogDisplayed(
+ content::DownloadManager* manager, int32 id) {
+}
+
+// Methods inherited from content::DownloadItem::Observer.
+void DownloadStatusUpdater::OnDownloadUpdated(
+ content::DownloadItem* download) {
+ UpdateItem(download);
+}
+
+void DownloadStatusUpdater::OnDownloadOpened(content::DownloadItem* download) {
+}
+
+// React to a transition that a download associated with one of our
+// download managers has made. Our goal is to have only IN_PROGRESS
+// items on our set list, as they're the only ones that have relevance
+// to GetProgress() return values.
+void DownloadStatusUpdater::UpdateItem(content::DownloadItem* download) {
+ if (download->GetState() == content::DownloadItem::IN_PROGRESS) {
+ if (!ContainsKey(items_, download)) {
+ items_.insert(download);
+ download->AddObserver(this);
+ }
+ } else {
+ if (ContainsKey(items_, download)) {
+ items_.erase(download);
+ download->RemoveObserver(this);
+ }
+ }
+}
diff --git a/chrome/browser/download/download_status_updater.h b/chrome/browser/download/download_status_updater.h
new file mode 100644
index 0000000..d220163
--- /dev/null
+++ b/chrome/browser/download/download_status_updater.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_STATUS_UPDATER_H_
+#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_STATUS_UPDATER_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "content/public/browser/download_item.h"
+#include "content/public/browser/download_manager.h"
+
+// Keeps track of download progress for the entire browser.
+class DownloadStatusUpdater
+ : public content::DownloadManager::Observer,
+ public content::DownloadItem::Observer {
+ public:
+ DownloadStatusUpdater();
+ virtual ~DownloadStatusUpdater();
+
+ // Fills in |*download_count| with the number of currently active downloads.
+ // If we know the final size of all downloads, this routine returns true
+ // with |*progress| set to the percentage complete of all in-progress
+ // downloads. Otherwise, it returns false.
+ bool GetProgress(float* progress, int* download_count) const;
+
+ // Add the specified DownloadManager to the list of managers for which
+ // this object reports status.
+ // The manager must not have previously been added to this updater.
+ // The updater will automatically disassociate itself from the
+ // manager when the manager is shutdown.
+ void AddManager(content::DownloadManager* manager);
+
+ // Methods inherited from content::DownloadManager::Observer.
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE;
+ virtual void SelectFileDialogDisplayed(
+ content::DownloadManager* manager, int32 id) OVERRIDE;
+
+ // Methods inherited from content::DownloadItem::Observer.
+ virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
+ virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE;
+
+ private:
+ // Update the internal state tracking an item.
+ void UpdateItem(content::DownloadItem* download);
+
+ std::set<content::DownloadManager*> managers_;
+ std::set<content::DownloadItem*> items_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadStatusUpdater);
+};
+
+#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_STATUS_UPDATER_H_
diff --git a/chrome/browser/download/download_status_updater_unittest.cc b/chrome/browser/download/download_status_updater_unittest.cc
new file mode 100644
index 0000000..31e6bac
--- /dev/null
+++ b/chrome/browser/download/download_status_updater_unittest.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "base/stl_util.h"
+#include "chrome/browser/download/download_status_updater.h"
+#include "content/browser/download/download_request_handle.h"
+#include "content/browser/download/download_types.h"
+#include "content/test/mock_download_item.h"
+#include "content/test/mock_download_manager.h"
+#include "content/test/test_browser_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+
+using ::testing::AtLeast;
+using ::testing::Mock;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::StrictMock;
+using ::testing::_;
+
+class DownloadStatusUpdaterTest : public testing::Test {
+ public:
+ DownloadStatusUpdaterTest()
+ : updater_(new DownloadStatusUpdater()),
+ ui_thread_(content::BrowserThread::UI, &loop_) {}
+
+ virtual ~DownloadStatusUpdaterTest() {
+ for (size_t mgr_idx = 0; mgr_idx < managers_.size(); ++mgr_idx) {
+ EXPECT_CALL(*Manager(mgr_idx), RemoveObserver(updater_));
+ for (size_t item_idx = 0; item_idx < manager_items_[mgr_idx].size();
+ ++item_idx) {
+ if (Item(mgr_idx, item_idx)->GetState() ==
+ content::DownloadItem::IN_PROGRESS)
+ EXPECT_CALL(*Item(mgr_idx, item_idx), RemoveObserver(updater_));
+ }
+ }
+
+ delete updater_;
+ updater_ = NULL;
+ VerifyAndClearExpectations();
+
+ managers_.clear();
+ for (std::vector<Items>::iterator it = manager_items_.begin();
+ it != manager_items_.end(); ++it)
+ STLDeleteContainerPointers(it->begin(), it->end());
+
+ loop_.RunAllPending(); // Allow DownloadManager destruction.
+ }
+
+ protected:
+ // Attach some number of DownloadManagers to the updater.
+ void SetupManagers(int manager_count) {
+ DCHECK_EQ(0U, managers_.size());
+ for (int i = 0; i < manager_count; ++i) {
+ content::MockDownloadManager* mgr =
+ new StrictMock<content::MockDownloadManager>;
+ managers_.push_back(make_scoped_refptr(mgr));
+ }
+ }
+
+ // Hook the specified manager into the updater.
+ void LinkManager(int i) {
+ content::MockDownloadManager* mgr = managers_[i].get();
+ EXPECT_CALL(*mgr, AddObserver(updater_));
+ updater_->AddManager(mgr);
+ updater_->ModelChanged(mgr);
+ }
+
+ // Add some number of Download items to a particular manager.
+ void AddItems(int manager_index, int item_count, int in_progress_count) {
+ DCHECK_GT(managers_.size(), static_cast<size_t>(manager_index));
+ content::MockDownloadManager* manager = managers_[manager_index].get();
+
+ if (manager_items_.size() <= static_cast<size_t>(manager_index))
+ manager_items_.resize(manager_index+1);
+
+ std::vector<content::DownloadItem*> item_list;
+ for (int i = 0; i < item_count; ++i) {
+ content::MockDownloadItem* item =
+ new StrictMock<content::MockDownloadItem>;
+ if (i < in_progress_count) {
+ EXPECT_CALL(*item, GetState())
+ .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
+ EXPECT_CALL(*item, AddObserver(updater_))
+ .WillOnce(Return());
+ } else {
+ EXPECT_CALL(*item, GetState())
+ .WillRepeatedly(Return(content::DownloadItem::COMPLETE));
+ }
+ manager_items_[manager_index].push_back(item);
+ }
+ EXPECT_CALL(*manager, SearchDownloads(string16(), _))
+ .WillOnce(SetArgPointee<1>(manager_items_[manager_index]));
+ }
+
+ // Return the specified manager.
+ content::MockDownloadManager* Manager(int manager_index) {
+ DCHECK_GT(managers_.size(), static_cast<size_t>(manager_index));
+ return managers_[manager_index].get();
+ }
+
+ // Return the specified item.
+ content::MockDownloadItem* Item(int manager_index, int item_index) {
+ DCHECK_GT(manager_items_.size(), static_cast<size_t>(manager_index));
+ DCHECK_GT(manager_items_[manager_index].size(),
+ static_cast<size_t>(item_index));
+ // All DownloadItems in manager_items_ are MockDownloadItems.
+ return static_cast<content::MockDownloadItem*>(
+ manager_items_[manager_index][item_index]);
+ }
+
+ // Set return values relevant to |DownloadStatusUpdater::GetProgress()|
+ // for the specified item
+ void SetItemValues(int manager_index, int item_index,
+ int received_bytes, int total_bytes) {
+ EXPECT_CALL(*Item(manager_index, item_index), GetReceivedBytes())
+ .WillRepeatedly(Return(received_bytes));
+ EXPECT_CALL(*Item(manager_index, item_index), GetTotalBytes())
+ .WillRepeatedly(Return(total_bytes));
+ }
+
+ // Transition specified item to completed.
+ void CompleteItem(int manager_index, int item_index) {
+ content::MockDownloadItem* item(Item(manager_index, item_index));
+ EXPECT_CALL(*item, GetState())
+ .WillRepeatedly(Return(content::DownloadItem::COMPLETE));
+ EXPECT_CALL(*item, RemoveObserver(updater_))
+ .WillOnce(Return());
+ updater_->OnDownloadUpdated(item);
+ }
+
+ // Verify and clear all mocks expectations.
+ void VerifyAndClearExpectations() {
+ for (std::vector<scoped_refptr<content::MockDownloadManager> >::iterator it
+ = managers_.begin(); it != managers_.end(); ++it)
+ Mock::VerifyAndClearExpectations(it->get());
+ for (std::vector<Items>::iterator it = manager_items_.begin();
+ it != manager_items_.end(); ++it)
+ for (Items::iterator sit = it->begin(); sit != it->end(); ++sit)
+ Mock::VerifyAndClearExpectations(*sit);
+ }
+
+ std::vector<scoped_refptr<content::MockDownloadManager> > managers_;
+ // DownloadItem so that it can be assigned to the result of SearchDownloads.
+ typedef std::vector<content::DownloadItem*> Items;
+ std::vector<Items> manager_items_;
+
+ // Pointer so we can verify that destruction triggers appropriate
+ // changes.
+ DownloadStatusUpdater *updater_;
+
+ // Thread so that the DownloadManager (which is a DeleteOnUIThread
+ // object) can be deleted.
+ // TODO(rdsmith): This can be removed when the DownloadManager
+ // is no longer required to be deleted on the UI thread.
+ MessageLoop loop_;
+ content::TestBrowserThread ui_thread_;
+};
+
+// Test null updater.
+TEST_F(DownloadStatusUpdaterTest, Basic) {
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ(0.0f, progress);
+ EXPECT_EQ(0, download_count);
+}
+
+// Test updater with null manager.
+TEST_F(DownloadStatusUpdaterTest, OneManagerNoItems) {
+ SetupManagers(1);
+ AddItems(0, 0, 0);
+ LinkManager(0);
+ VerifyAndClearExpectations();
+
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ(0.0f, progress);
+ EXPECT_EQ(0, download_count);
+}
+
+// Test updater with non-null manager, including transition an item to
+// |content::DownloadItem::COMPLETE| and adding a new item.
+TEST_F(DownloadStatusUpdaterTest, OneManagerManyItems) {
+ SetupManagers(1);
+ AddItems(0, 3, 2);
+ LinkManager(0);
+
+ // Prime items
+ SetItemValues(0, 0, 10, 20);
+ SetItemValues(0, 1, 50, 60);
+ SetItemValues(0, 2, 90, 90);
+
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ((10+50)/(20.0f+60), progress);
+ EXPECT_EQ(2, download_count);
+
+ // Transition one item to completed and confirm progress is updated
+ // properly.
+ CompleteItem(0, 0);
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ(50/60.0f, progress);
+ EXPECT_EQ(1, download_count);
+
+ // Add a new item to manager and confirm progress is updated properly.
+ AddItems(0, 1, 1);
+ updater_->ModelChanged(Manager(0));
+ SetItemValues(0, 3, 150, 200);
+
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ((50+150)/(60+200.0f), progress);
+ EXPECT_EQ(2, download_count);
+}
+
+// Confirm we recognize the situation where we have an unknown size.
+TEST_F(DownloadStatusUpdaterTest, UnknownSize) {
+ SetupManagers(1);
+ AddItems(0, 2, 2);
+ LinkManager(0);
+
+ // Prime items
+ SetItemValues(0, 0, 10, 20);
+ SetItemValues(0, 1, 50, -1);
+
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_FALSE(updater_->GetProgress(&progress, &download_count));
+}
+
+// Test many null managers.
+TEST_F(DownloadStatusUpdaterTest, ManyManagersNoItems) {
+ SetupManagers(1);
+ AddItems(0, 0, 0);
+ LinkManager(0);
+
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ(0.0f, progress);
+ EXPECT_EQ(0, download_count);
+}
+
+// Test many managers with all items complete.
+TEST_F(DownloadStatusUpdaterTest, ManyManagersEmptyItems) {
+ SetupManagers(2);
+ AddItems(0, 3, 0);
+ LinkManager(0);
+ AddItems(1, 3, 0);
+ LinkManager(1);
+
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ(0.0f, progress);
+ EXPECT_EQ(0, download_count);
+}
+
+// Test many managers with some non-complete items.
+TEST_F(DownloadStatusUpdaterTest, ManyManagersMixedItems) {
+ SetupManagers(2);
+ AddItems(0, 3, 2);
+ LinkManager(0);
+ AddItems(1, 3, 1);
+ LinkManager(1);
+
+ SetItemValues(0, 0, 10, 20);
+ SetItemValues(0, 1, 50, 60);
+ SetItemValues(1, 0, 80, 90);
+
+ float progress = -1;
+ int download_count = -1;
+ EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
+ EXPECT_FLOAT_EQ((10+50+80)/(20.0f+60+90), progress);
+ EXPECT_EQ(3, download_count);
+}
diff --git a/chrome/browser/download/download_test_observer.cc b/chrome/browser/download/download_test_observer.cc
index 06b7c47..c495a9f 100644
--- a/chrome/browser/download/download_test_observer.cc
+++ b/chrome/browser/download/download_test_observer.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -82,7 +82,7 @@ bool DownloadTestObserver::IsFinished() const {
return (finish_on_select_file_ && select_file_dialog_seen_);
}
-void DownloadTestObserver::OnDownloadUpdated(content::DownloadItem* download) {
+void DownloadTestObserver::OnDownloadUpdated(DownloadItem* download) {
// The REMOVING state indicates that the download is being destroyed.
// Stop observing. Do not do anything with it, as it is about to be gone.
if (download->GetState() == DownloadItem::REMOVING) {
@@ -134,7 +134,9 @@ void DownloadTestObserver::OnDownloadUpdated(content::DownloadItem* download) {
}
}
-void DownloadTestObserver::ModelChanged() {
+void DownloadTestObserver::ModelChanged(DownloadManager* manager) {
+ DCHECK_EQ(manager, download_manager_);
+
// Regenerate DownloadItem observers. If there are any download items
// in our final state, note them in |finished_downloads_|
// (done by |OnDownloadUpdated()|).
@@ -169,7 +171,9 @@ void DownloadTestObserver::ModelChanged() {
}
}
-void DownloadTestObserver::SelectFileDialogDisplayed(int32 /* id */) {
+void DownloadTestObserver::SelectFileDialogDisplayed(
+ DownloadManager* manager, int32 /* id */) {
+ DCHECK_EQ(manager, download_manager_);
select_file_dialog_seen_ = true;
SignalIfFinished();
}
@@ -206,13 +210,12 @@ void DownloadTestFlushObserver::WaitForFlush() {
ui_test_utils::RunMessageLoop();
}
-void DownloadTestFlushObserver::ModelChanged() {
+void DownloadTestFlushObserver::ModelChanged(DownloadManager* manager) {
// Model has changed, so there may be more DownloadItems to observe.
CheckDownloadsInProgress(true);
}
-void DownloadTestFlushObserver::OnDownloadUpdated(
- content::DownloadItem* download) {
+void DownloadTestFlushObserver::OnDownloadUpdated(DownloadItem* download) {
// The REMOVING state indicates that the download is being destroyed.
// Stop observing. Do not do anything with it, as it is about to be gone.
if (download->GetState() == DownloadItem::REMOVING) {
diff --git a/chrome/browser/download/download_test_observer.h b/chrome/browser/download/download_test_observer.h
index ad32ce4..3404f42 100644
--- a/chrome/browser/download/download_test_observer.h
+++ b/chrome/browser/download/download_test_observer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -66,9 +66,10 @@ class DownloadTestObserver : public content::DownloadManager::Observer,
virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE {}
// content::DownloadManager::Observer
- virtual void ModelChanged() OVERRIDE;
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
- virtual void SelectFileDialogDisplayed(int32 id) OVERRIDE;
+ virtual void SelectFileDialogDisplayed(
+ content::DownloadManager* manager, int32 id) OVERRIDE;
size_t NumDangerousDownloadsSeen() const;
@@ -150,7 +151,7 @@ class DownloadTestFlushObserver
void WaitForFlush();
// DownloadsManager observer methods.
- virtual void ModelChanged() OVERRIDE;
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
// DownloadItem observer methods.
virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index 70f3693..9a25949 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -92,7 +92,7 @@ class HistoryDatabase : public DownloadDatabase,
//
// We don't delete the downloads table, since there may be in progress
// downloads. We handle the download history clean up separately in:
- // DownloadManager::RemoveDownloadsFromHistoryBetween.
+ // content::DownloadManager::RemoveDownloadsFromHistoryBetween.
//
// Returns true on success. On failure, the caller should assume that the
// database is invalid. There could have been an error recreating a table.
diff --git a/chrome/browser/ui/cocoa/download/download_item_mac.h b/chrome/browser/ui/cocoa/download/download_item_mac.h
index 6b352de..9387f0a 100644
--- a/chrome/browser/ui/cocoa/download/download_item_mac.h
+++ b/chrome/browser/ui/cocoa/download/download_item_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -35,7 +35,7 @@ class DownloadItemMac : content::DownloadItem::Observer {
// Destructor.
virtual ~DownloadItemMac();
- // DownloadItem::Observer implementation
+ // content::DownloadItem::Observer implementation
virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE;
diff --git a/chrome/browser/ui/gtk/download/download_item_gtk.h b/chrome/browser/ui/gtk/download/download_item_gtk.h
index bb7a98e..eec8f52 100644
--- a/chrome/browser/ui/gtk/download/download_item_gtk.h
+++ b/chrome/browser/ui/gtk/download/download_item_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -48,7 +48,7 @@ class DownloadItemGtk : public content::DownloadItem::Observer,
// Destroys all widgets belonging to this DownloadItemGtk.
virtual ~DownloadItemGtk();
- // DownloadItem::Observer implementation.
+ // content::DownloadItem::Observer implementation.
virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE { }
diff --git a/chrome/browser/ui/panels/panel_browsertest.cc b/chrome/browser/ui/panels/panel_browsertest.cc
index 87c7693..1c4bbd1 100644
--- a/chrome/browser/ui/panels/panel_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_browsertest.cc
@@ -1718,7 +1718,9 @@ class DownloadObserver : public content::DownloadManager::Observer {
}
// DownloadManager::Observer
- virtual void ModelChanged() {
+ virtual void ModelChanged(DownloadManager* manager) {
+ DCHECK_EQ(download_manager_, manager);
+
std::vector<DownloadItem*> downloads;
download_manager_->SearchDownloads(string16(), &downloads);
if (downloads.empty())
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index c77c613..de29596 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -252,7 +252,7 @@ void DownloadItemView::OnExtractIconComplete(IconManager::Handle handle,
// Update the progress graphic on the icon and our text status label
// to reflect our current bytes downloaded, time remaining.
-void DownloadItemView::OnDownloadUpdated(content::DownloadItem* download) {
+void DownloadItemView::OnDownloadUpdated(DownloadItem* download) {
DCHECK(download == download_);
if (IsShowingWarningDialog() &&
@@ -315,7 +315,7 @@ void DownloadItemView::OnDownloadUpdated(content::DownloadItem* download) {
parent()->SchedulePaint();
}
-void DownloadItemView::OnDownloadOpened(content::DownloadItem* download) {
+void DownloadItemView::OnDownloadOpened(DownloadItem* download) {
disabled_while_opening_ = true;
SetEnabled(false);
MessageLoop::current()->PostDelayedTask(
diff --git a/chrome/browser/ui/webui/active_downloads_ui.cc b/chrome/browser/ui/webui/active_downloads_ui.cc
index d12bd50..f68020d 100644
--- a/chrome/browser/ui/webui/active_downloads_ui.cc
+++ b/chrome/browser/ui/webui/active_downloads_ui.cc
@@ -137,7 +137,7 @@ class ActiveDownloadsHandler
virtual void OnDownloadOpened(DownloadItem* item) OVERRIDE { }
// DownloadManager::Observer interface.
- virtual void ModelChanged() OVERRIDE;
+ virtual void ModelChanged(DownloadManager* manager) OVERRIDE;
// WebUI Callbacks.
void HandleGetDownloads(const ListValue* args);
@@ -247,7 +247,7 @@ void ActiveDownloadsHandler::ViewFile(const ListValue* args) {
false);
}
-void ActiveDownloadsHandler::ModelChanged() {
+void ActiveDownloadsHandler::ModelChanged(DownloadManager* manager) {
UpdateDownloadList();
}
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads_dom_handler.cc
index d93c50c..b340c08 100644
--- a/chrome/browser/ui/webui/downloads_dom_handler.cc
+++ b/chrome/browser/ui/webui/downloads_dom_handler.cc
@@ -44,8 +44,6 @@
#endif
using content::BrowserThread;
-using content::DownloadItem;
-using content::DownloadManager;
using content::UserMetricsAction;
namespace {
@@ -55,11 +53,12 @@ namespace {
static const int kMaxDownloads = 150;
// Sort DownloadItems into descending order by their start time.
-class DownloadItemSorter : public std::binary_function<DownloadItem*,
- DownloadItem*,
+class DownloadItemSorter : public std::binary_function<content::DownloadItem*,
+ content::DownloadItem*,
bool> {
public:
- bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) {
+ bool operator()(const content::DownloadItem* lhs,
+ const content::DownloadItem* rhs) {
return lhs->GetStartTime() > rhs->GetStartTime();
}
};
@@ -87,66 +86,37 @@ void CountDownloadsDOMEvents(DownloadsDOMEvent event) {
} // namespace
-class DownloadsDOMHandler::OriginalDownloadManagerObserver
- : public content::DownloadManager::Observer {
- public:
- explicit OriginalDownloadManagerObserver(
- DownloadManager::Observer* observer,
- Profile* original_profile)
- : observer_(observer) {
- original_profile_download_manager_ =
- DownloadServiceFactory::GetForProfile(
- original_profile)->GetDownloadManager();
- original_profile_download_manager_->AddObserver(this);
- }
-
- virtual ~OriginalDownloadManagerObserver() {
- if (original_profile_download_manager_)
- original_profile_download_manager_->RemoveObserver(this);
- }
-
- // Observer interface.
- virtual void ModelChanged() {
- observer_->ModelChanged();
- }
-
- virtual void ManagerGoingDown() {
- original_profile_download_manager_ = NULL;
- }
-
- private:
- // The DownloadsDOMHandler for the off-the-record profile.
- DownloadManager::Observer* observer_;
-
- // The original profile's download manager.
- DownloadManager* original_profile_download_manager_;
-};
-
-DownloadsDOMHandler::DownloadsDOMHandler(DownloadManager* dlm)
+DownloadsDOMHandler::DownloadsDOMHandler(content::DownloadManager* dlm)
: search_text_(),
- download_manager_(dlm) {
+ download_manager_(dlm),
+ original_profile_download_manager_(NULL) {
// Create our fileicon data source.
Profile::FromBrowserContext(dlm->GetBrowserContext())->
GetChromeURLDataManager()->AddDataSource(new FileIconSource());
+
+ // Figure out our parent DownloadManager, if any.
+ Profile* profile =
+ Profile::FromBrowserContext(download_manager_->GetBrowserContext());
+ Profile* original_profile = profile->GetOriginalProfile();
+ if (original_profile != profile) {
+ original_profile_download_manager_ = DownloadServiceFactory::GetForProfile(
+ original_profile)->GetDownloadManager();
+ }
}
DownloadsDOMHandler::~DownloadsDOMHandler() {
ClearDownloadItems();
download_manager_->RemoveObserver(this);
+ if (original_profile_download_manager_)
+ original_profile_download_manager_->RemoveObserver(this);
}
// DownloadsDOMHandler, public: -----------------------------------------------
void DownloadsDOMHandler::Init() {
download_manager_->AddObserver(this);
-
- Profile* profile =
- Profile::FromBrowserContext(download_manager_->GetBrowserContext());
- Profile* original_profile = profile->GetOriginalProfile();
- if (original_profile != profile) {
- original_download_manager_observer_.reset(
- new OriginalDownloadManagerObserver(this, original_profile));
- }
+ if (original_profile_download_manager_)
+ original_profile_download_manager_->AddObserver(this);
}
void DownloadsDOMHandler::RegisterMessages() {
@@ -199,7 +169,7 @@ void DownloadsDOMHandler::OnDownloadUpdated(content::DownloadItem* download) {
if (it == download_items_.end())
return;
- if (download->GetState() == DownloadItem::REMOVING) {
+ if (download->GetState() == content::DownloadItem::REMOVING) {
(*it)->RemoveObserver(this);
*it = NULL;
// A later ModelChanged() notification will change the WebUI's
@@ -216,17 +186,18 @@ void DownloadsDOMHandler::OnDownloadUpdated(content::DownloadItem* download) {
// A download has started or been deleted. Query our DownloadManager for the
// current set of downloads.
-void DownloadsDOMHandler::ModelChanged() {
+void DownloadsDOMHandler::ModelChanged(content::DownloadManager* manager) {
+ DCHECK(manager == download_manager_ ||
+ manager == original_profile_download_manager_);
+
ClearDownloadItems();
download_manager_->SearchDownloads(WideToUTF16(search_text_),
&download_items_);
- // If we have a parent profile, let it add its downloads to the results.
- Profile* profile =
- Profile::FromBrowserContext(download_manager_->GetBrowserContext());
- if (profile->GetOriginalProfile() != profile) {
- DownloadServiceFactory::GetForProfile(
- profile->GetOriginalProfile())->GetDownloadManager()->SearchDownloads(
- WideToUTF16(search_text_), &download_items_);
+ // If we have a parent DownloadManager, let it add its downloads to the
+ // results.
+ if (original_profile_download_manager_) {
+ original_profile_download_manager_->SearchDownloads(
+ WideToUTF16(search_text_), &download_items_);
}
sort(download_items_.begin(), download_items_.end(), DownloadItemSorter());
@@ -249,7 +220,7 @@ void DownloadsDOMHandler::ModelChanged() {
// fixed.
// We should never see anything that isn't already in the history.
CHECK(*it);
- CHECK_NE(DownloadItem::kUninitializedHandle, (*it)->GetDbHandle());
+ CHECK_NE(content::DownloadItem::kUninitializedHandle, (*it)->GetDbHandle());
(*it)->AddObserver(this);
}
@@ -257,12 +228,22 @@ void DownloadsDOMHandler::ModelChanged() {
SendCurrentDownloads();
}
+void DownloadsDOMHandler::ManagerGoingDown(content::DownloadManager* manager) {
+ // This should never happen. The lifetime of the DownloadsDOMHandler
+ // is tied to the tab in which downloads.html is displayed, which cannot
+ // outlive the Browser that contains it, which cannot outlive the Profile
+ // it is associated with. If that profile is an incognito profile,
+ // it cannot outlive its original profile. Thus this class should be
+ // destroyed before a ManagerGoingDown() notification occurs.
+ NOTREACHED();
+}
+
void DownloadsDOMHandler::HandleGetDownloads(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_GET_DOWNLOADS);
std::wstring new_search = UTF16ToWideHack(ExtractStringValue(args));
if (search_text_.compare(new_search) != 0) {
search_text_ = new_search;
- ModelChanged();
+ ModelChanged(download_manager_);
} else {
SendCurrentDownloads();
}
@@ -272,14 +253,14 @@ void DownloadsDOMHandler::HandleGetDownloads(const ListValue* args) {
void DownloadsDOMHandler::HandleOpenFile(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_OPEN_FILE);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file)
file->OpenDownload();
}
void DownloadsDOMHandler::HandleDrag(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_DRAG);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file) {
IconManager* im = g_browser_process->icon_manager();
gfx::Image* icon = im->LookupIcon(file->GetUserVerifiedFilePath(),
@@ -295,45 +276,45 @@ void DownloadsDOMHandler::HandleDrag(const ListValue* args) {
void DownloadsDOMHandler::HandleSaveDangerous(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_SAVE_DANGEROUS);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file)
file->DangerousDownloadValidated();
}
void DownloadsDOMHandler::HandleDiscardDangerous(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_DISCARD_DANGEROUS);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file)
- file->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
+ file->Delete(content::DownloadItem::DELETE_DUE_TO_USER_DISCARD);
}
void DownloadsDOMHandler::HandleShow(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_SHOW);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file)
file->ShowDownloadInShell();
}
void DownloadsDOMHandler::HandlePause(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_PAUSE);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file)
file->TogglePause();
}
void DownloadsDOMHandler::HandleRemove(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_REMOVE);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file) {
// TODO(rdsmith): Change to DCHECK when http://crbug.com/85408 is fixed.
- CHECK_NE(DownloadItem::kUninitializedHandle, file->GetDbHandle());
+ CHECK_NE(content::DownloadItem::kUninitializedHandle, file->GetDbHandle());
file->Remove();
}
}
void DownloadsDOMHandler::HandleCancel(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CANCEL);
- DownloadItem* file = GetDownloadByValue(args);
+ content::DownloadItem* file = GetDownloadByValue(args);
if (file)
file->Cancel(true);
}
@@ -342,14 +323,10 @@ void DownloadsDOMHandler::HandleClearAll(const ListValue* args) {
CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CLEAR_ALL);
download_manager_->RemoveAllDownloads();
- Profile* profile =
- Profile::FromBrowserContext(download_manager_->GetBrowserContext());
// If this is an incognito downloader, clear All should clear main download
// manager as well.
- if (profile->GetOriginalProfile() != profile)
- DownloadServiceFactory::GetForProfile(
- profile->GetOriginalProfile())->
- GetDownloadManager()->RemoveAllDownloads();
+ if (original_profile_download_manager_)
+ original_profile_download_manager_->RemoveAllDownloads();
}
void DownloadsDOMHandler::HandleOpenDownloadsFolder(const ListValue* args) {
@@ -386,7 +363,7 @@ void DownloadsDOMHandler::ClearDownloadItems() {
download_items_.clear();
}
-DownloadItem* DownloadsDOMHandler::GetDownloadById(int id) {
+content::DownloadItem* DownloadsDOMHandler::GetDownloadById(int id) {
for (OrderedDownloads::iterator it = download_items_.begin();
it != download_items_.end(); ++it) {
if (static_cast<int>(it - download_items_.begin() == id)) {
@@ -397,7 +374,8 @@ DownloadItem* DownloadsDOMHandler::GetDownloadById(int id) {
return NULL;
}
-DownloadItem* DownloadsDOMHandler::GetDownloadByValue(const ListValue* args) {
+content::DownloadItem* DownloadsDOMHandler::GetDownloadByValue(
+ const ListValue* args) {
int id;
if (ExtractIntegerValue(args, &id)) {
return GetDownloadById(id);
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.h b/chrome/browser/ui/webui/downloads_dom_handler.h
index d603094..e7ee3c7 100644
--- a/chrome/browser/ui/webui/downloads_dom_handler.h
+++ b/chrome/browser/ui/webui/downloads_dom_handler.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -31,12 +31,13 @@ class DownloadsDOMHandler : public content::WebUIMessageHandler,
// WebUIMessageHandler implementation.
virtual void RegisterMessages() OVERRIDE;
- // DownloadItem::Observer interface
+ // content::DownloadItem::Observer interface
virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE { }
- // DownloadManager::Observer interface
- virtual void ModelChanged() OVERRIDE;
+ // content::DownloadManager::Observer interface
+ virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE;
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE;
// Callback for the "getDownloads" message.
void HandleGetDownloads(const base::ListValue* args);
@@ -96,10 +97,10 @@ class DownloadsDOMHandler : public content::WebUIMessageHandler,
// Our model
content::DownloadManager* download_manager_;
- // The downloads webui for an off-the-record window also shows downloads from
- // the parent profile.
- scoped_ptr<OriginalDownloadManagerObserver>
- original_download_manager_observer_;
+ // If |download_manager_| belongs to an incognito profile than this
+ // is the DownloadManager for the original profile; otherwise, this is
+ // NULL.
+ content::DownloadManager* original_profile_download_manager_;
// The current set of visible DownloadItems for this view received from the
// DownloadManager. DownloadManager owns the DownloadItems. The vector is
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 127425f..211337c 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -948,6 +948,8 @@
'browser/download/download_shelf_context_menu.cc',
'browser/download/download_shelf_context_menu.h',
'browser/download/download_started_animation.h',
+ 'browser/download/download_status_updater.cc',
+ 'browser/download/download_status_updater.h',
'browser/download/download_throttling_resource_handler.cc',
'browser/download/download_throttling_resource_handler.h',
'browser/download/download_util.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index b4bcac5..cd0a070 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1398,6 +1398,7 @@
'browser/download/download_request_infobar_delegate_unittest.cc',
'browser/download/download_request_limiter_unittest.cc',
'browser/download/download_shelf_unittest.cc',
+ 'browser/download/download_status_updater_unittest.cc',
'browser/enumerate_modules_model_unittest_win.cc',
'browser/event_disposition.cc',
'browser/event_disposition.h',