diff options
author | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-04 16:57:54 +0000 |
---|---|---|
committer | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-04 16:57:54 +0000 |
commit | 75e51b57f3c654ec88b3f8bd59f0b185f34576f6 (patch) | |
tree | d1874d3b0938e2ca000579d130f398fd6c513575 /chrome | |
parent | d333dfc2314dae9f47f5d0a7bbdc62807be33ebb (diff) | |
download | chromium_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')
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(), ¤t_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', |