diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 19:29:28 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 19:29:28 +0000 |
commit | b0ab1d465fb0dc6d8592bd8a8f16f1c0e9cbc7aa (patch) | |
tree | babe2d723ff9a93f973bde63cfeddd809be7b1d7 /chrome/browser/download | |
parent | 9d9f653d7ac6a2f083dd9acd2ff7a12a5c202398 (diff) | |
download | chromium_src-b0ab1d465fb0dc6d8592bd8a8f16f1c0e9cbc7aa.zip chromium_src-b0ab1d465fb0dc6d8592bd8a8f16f1c0e9cbc7aa.tar.gz chromium_src-b0ab1d465fb0dc6d8592bd8a8f16f1c0e9cbc7aa.tar.bz2 |
This change makes incognito downloads show up in the downloads page of an incognito window. These downloads are not persisted to history; hence they do not persist between incognito sessions.
There is no special UI for the incognito downloads. That can be added later.
BUG=28702
Review URL: http://codereview.chromium.org/650065
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39910 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/download')
-rw-r--r-- | chrome/browser/download/download_manager.cc | 101 | ||||
-rw-r--r-- | chrome/browser/download/download_manager.h | 51 | ||||
-rw-r--r-- | chrome/browser/download/download_util.cc | 1 | ||||
-rw-r--r-- | chrome/browser/download/save_package.cc | 5 |
4 files changed, 144 insertions, 14 deletions
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 2eb8f54..ab72b11 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -116,6 +116,11 @@ static bool DownloadPathIsDangerous(const FilePath& download_path) { return (download_path == desktop_dir); } +// Used to sort download items based on descending start time. +bool CompareStartTime(DownloadItem* first, DownloadItem* second) { + return first->start_time() > second->start_time(); +} + } // namespace // DownloadItem implementation ------------------------------------------------- @@ -142,6 +147,7 @@ DownloadItem::DownloadItem(const DownloadCreateInfo& info) render_process_id_(-1), request_id_(-1), save_as_(false), + is_otr_(false), is_extension_install_(info.is_extension_install), name_finalized_(false), is_temporary_(false) { @@ -164,6 +170,7 @@ DownloadItem::DownloadItem(int32 download_id, int request_id, bool is_dangerous, bool save_as, + bool is_otr, bool is_extension_install, bool is_temporary) : id_(download_id), @@ -187,6 +194,7 @@ DownloadItem::DownloadItem(int32 download_id, render_process_id_(render_process_id), request_id_(request_id), save_as_(save_as), + is_otr_(is_otr), is_extension_install_(is_extension_install), name_finalized_(false), is_temporary_(is_temporary) { @@ -377,6 +385,8 @@ DownloadManager::DownloadManager() } DownloadManager::~DownloadManager() { + FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown()); + if (shutdown_needed_) Shutdown(); } @@ -453,17 +463,41 @@ void DownloadManager::Shutdown() { // is empty, return all downloads that we know about. void DownloadManager::GetDownloads(Observer* observer, const std::wstring& search_text) { + std::vector<DownloadItem*> otr_downloads; + + if (profile_->IsOffTheRecord() && search_text.empty()) { + // List all incognito downloads and add that to the downloads the parent + // profile lists. + otr_downloads.reserve(downloads_.size()); + for (DownloadMap::iterator it = downloads_.begin(); + it != downloads_.end(); ++it) { + DownloadItem* download = it->second; + if (download->is_otr() && !download->is_extension_install() && + !download->is_temporary()) { + otr_downloads.push_back(download); + } + } + } + + profile_->GetOriginalProfile()->GetDownloadManager()-> + DoGetDownloads(observer, search_text, otr_downloads); +} + +void DownloadManager::DoGetDownloads( + Observer* observer, + const std::wstring& search_text, + std::vector<DownloadItem*>& otr_downloads) { DCHECK(observer); // Return a empty list if we've not yet received the set of downloads from the // history system (we'll update all observers once we get that list in // OnQueryDownloadEntriesComplete), or if there are no downloads at all. - std::vector<DownloadItem*> download_copy; if (downloads_.empty()) { - observer->SetDownloads(download_copy); + observer->SetDownloads(otr_downloads); return; } + std::vector<DownloadItem*> download_copy; // We already know all the downloads and there is no filter, so just return a // copy to the observer. if (search_text.empty()) { @@ -474,11 +508,20 @@ void DownloadManager::GetDownloads(Observer* observer, download_copy.push_back(it->second); } + // Merge sort based on start time. + std::vector<DownloadItem*> merged_downloads; + std::merge(otr_downloads.begin(), otr_downloads.end(), + download_copy.begin(), download_copy.end(), + std::back_inserter(merged_downloads), + CompareStartTime); + // We retain ownership of the DownloadItems. - observer->SetDownloads(download_copy); + observer->SetDownloads(merged_downloads); return; } + DCHECK(otr_downloads.empty()); + // Issue a request to the history service for a list of downloads matching // our search text. HistoryService* hs = @@ -558,6 +601,9 @@ bool DownloadManager::Init(Profile* profile) { auto_open_.insert(FilePath::FromWStringHack(extensions[i]).value()); } + other_download_manager_observer_.reset( + new OtherDownloadManagerObserver(this)); + return true; } @@ -747,6 +793,7 @@ void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info, info->request_id, info->is_dangerous, info->save_as, + profile_->IsOffTheRecord(), info->is_extension_install, !info->save_info.file_path.empty()); download->set_manager(this); @@ -781,7 +828,7 @@ void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info, // handles, so we use a negative value. Eventually, they could overlap, but // you'd have to do enough downloading that your ISP would likely stab you in // the neck first. YMMV. - if (profile_->IsOffTheRecord() || download->is_extension_install() || + if (download->is_otr() || download->is_extension_install() || download->is_temporary()) { OnCreateDownloadEntryComplete(*info, fake_db_handle_.GetNext()); } else { @@ -1144,7 +1191,7 @@ void DownloadManager::RemoveDownload(int64 download_handle) { dangerous_finished_.erase(it); // Tell observers to refresh their views. - FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); + NotifyModelChanged(); delete download; } @@ -1171,6 +1218,7 @@ int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, dangerous_finished_.erase(dit); pending_deletes.push_back(download); + // Observer interface. continue; } @@ -1181,7 +1229,7 @@ int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, // Tell observers to refresh their views. int num_deleted = static_cast<int>(pending_deletes.size()); if (num_deleted > 0) - FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); + NotifyModelChanged(); // Delete the download items after updating the observers. STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end()); @@ -1638,7 +1686,7 @@ void DownloadManager::OnQueryDownloadEntriesComplete( downloads_[download->db_handle()] = download; download->set_manager(this); } - FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); + NotifyModelChanged(); } // Once the new DownloadItem's creation info has been committed to the history @@ -1670,7 +1718,7 @@ void DownloadManager::OnCreateDownloadEntryComplete(DownloadCreateInfo info, ShowDownloadInBrowser(info, download); // Inform interested objects about the new download. - FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); + NotifyModelChanged(); // If this download has been completed before we've received the db handle, // post one final message to the history service so that it can be properly @@ -1730,3 +1778,40 @@ void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, void DownloadManager::ClearLastDownloadPath() { last_download_path_ = FilePath(); } + +void DownloadManager::NotifyModelChanged() { + FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); +} + +// DownloadManager::OtherDownloadManagerObserver implementation ---------------- + +DownloadManager::OtherDownloadManagerObserver::OtherDownloadManagerObserver( + DownloadManager* observing_download_manager) + : observing_download_manager_(observing_download_manager), + observed_download_manager_(NULL) { + if (observing_download_manager->profile_->GetOriginalProfile() == + observing_download_manager->profile_) { + return; + } + + observed_download_manager_ = observing_download_manager_-> + profile_->GetOriginalProfile()->GetDownloadManager(); + observed_download_manager_->AddObserver(this); +} + +DownloadManager::OtherDownloadManagerObserver::~OtherDownloadManagerObserver() { + if (observed_download_manager_) + observed_download_manager_->RemoveObserver(this); +} + +void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { + observing_download_manager_->NotifyModelChanged(); +} + +void DownloadManager::OtherDownloadManagerObserver::SetDownloads( + std::vector<DownloadItem*>& downloads) { +} + +void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { + observed_download_manager_ = NULL; +} diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h index bd51c0e..4b253bc 100644 --- a/chrome/browser/download/download_manager.h +++ b/chrome/browser/download/download_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. // @@ -121,6 +121,7 @@ class DownloadItem { int request_id, bool is_dangerous, bool save_as, + bool is_otr, bool is_extension_install, bool is_temporary); @@ -222,6 +223,7 @@ class DownloadItem { FilePath original_name() const { return original_name_; } void set_original_name(const FilePath& name) { original_name_ = name; } bool save_as() const { return save_as_; } + bool is_otr() const { return is_otr_; } bool is_extension_install() const { return is_extension_install_; } bool name_finalized() const { return name_finalized_; } void set_name_finalized(bool name_finalized) { @@ -314,6 +316,9 @@ class DownloadItem { // True if the item was downloaded as a result of 'save as...' bool save_as_; + // True if the download was initiated in an incognito window. + bool is_otr_; + // True if the item was downloaded for an extension installation. bool is_extension_install_; @@ -353,17 +358,28 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // own the individual DownloadItems, when this call is made. virtual void SetDownloads(std::vector<DownloadItem*>& downloads) = 0; + // Called when the DownloadManager is being destroyed to prevent Observers + // from calling back to a stale pointer. + virtual void ManagerGoingDown() {} + protected: virtual ~Observer() {} }; // Public API + // If this download manager has an incognito profile, find all incognito + // downloads and pass them along to the parent profile's download manager + // via DoGetDownloads. Otherwise, just call DoGetDownloads(). + void GetDownloads(Observer* observer, + const std::wstring& search_text); + // Begin a search for all downloads matching 'search_text'. If 'search_text' // is empty, return all known downloads. The results are returned in the // 'SetDownloads' observer callback. - void GetDownloads(Observer* observer, - const std::wstring& search_text); + void DoGetDownloads(Observer* observer, + const std::wstring& search_text, + std::vector<DownloadItem*>& otr_downloads); // Return all temporary downloads that reside in the specified directory. void GetTemporaryDownloads(Observer* observer, @@ -509,7 +525,6 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, FilePath* generated_name); private: - class FakeDbHandleGenerator { public: explicit FakeDbHandleGenerator(int64 start_value) : value_(start_value) {} @@ -519,7 +534,30 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, int64 value_; }; + // This class is used to let an incognito DownloadManager observe changes to + // a normal DownloadManager, to propagate ModelChanged() calls from the parent + // DownloadManager to the observers of the incognito DownloadManager. + class OtherDownloadManagerObserver : public Observer { + public: + explicit OtherDownloadManagerObserver( + DownloadManager* observing_download_manager); + virtual ~OtherDownloadManagerObserver(); + + // Observer interface. + virtual void ModelChanged(); + virtual void SetDownloads(std::vector<DownloadItem*>& downloads); + virtual void ManagerGoingDown(); + + private: + // The incognito download manager. + DownloadManager* observing_download_manager_; + + // The original profile's download manager. + DownloadManager* observed_download_manager_; + }; + friend class base::RefCountedThreadSafe<DownloadManager>; + friend class OtherDownloadManagerObserver; ~DownloadManager(); @@ -608,6 +646,9 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // the change to the history system. void RenameDownload(DownloadItem* download, const FilePath& new_path); + // Inform observers that the model has changed. + void NotifyModelChanged(); + // 'downloads_' is map of all downloads in this profile. The key is the handle // returned by the history system, which is unique across sessions. This map // owns all the DownloadItems once they have been created in the history @@ -689,6 +730,8 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>, // automatically decrement the handle value on every use. FakeDbHandleGenerator fake_db_handle_; + scoped_ptr<OtherDownloadManagerObserver> other_download_manager_observer_; + DISALLOW_COPY_AND_ASSIGN(DownloadManager); }; diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index 611b199..8ea8f10 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -319,6 +319,7 @@ DictionaryValue* CreateDownloadItemValue(DownloadItem* download, int id) { l10n_util::WrapStringWithLTRFormatting(&file_name); file_value->SetString(L"file_name", file_name); file_value->SetString(L"url", download->url().spec()); + file_value->SetBoolean(L"otr", download->is_otr()); if (download->state() == DownloadItem::IN_PROGRESS) { if (download->safety_state() == DownloadItem::DANGEROUS) { diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index a124b3e..5c089ac 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -304,7 +304,8 @@ bool SavePackage::Init() { // Create the fake DownloadItem and display the view. download_ = new DownloadItem(1, saved_main_file_path_, 0, page_url_, GURL(), - "", FilePath(), Time::Now(), 0, -1, -1, false, false, false, false); + "", FilePath(), Time::Now(), 0, -1, -1, false, false, + profile->IsOffTheRecord(), false, false); download_->set_manager(tab_contents_->profile()->GetDownloadManager()); tab_contents_->OnStartDownload(download_); |