summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 19:29:28 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 19:29:28 +0000
commitb0ab1d465fb0dc6d8592bd8a8f16f1c0e9cbc7aa (patch)
treebabe2d723ff9a93f973bde63cfeddd809be7b1d7
parent9d9f653d7ac6a2f083dd9acd2ff7a12a5c202398 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/dom_ui/downloads_ui.cc5
-rw-r--r--chrome/browser/download/download_manager.cc101
-rw-r--r--chrome/browser/download/download_manager.h51
-rw-r--r--chrome/browser/download/download_util.cc1
-rw-r--r--chrome/browser/download/save_package.cc5
-rw-r--r--chrome/browser/resources/downloads.html5
6 files changed, 151 insertions, 17 deletions
diff --git a/chrome/browser/dom_ui/downloads_ui.cc b/chrome/browser/dom_ui/downloads_ui.cc
index 0a10bf3..a7ae595 100644
--- a/chrome/browser/dom_ui/downloads_ui.cc
+++ b/chrome/browser/dom_ui/downloads_ui.cc
@@ -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,8 +121,7 @@ void DownloadsUIHTMLSource::StartDataRequest(const std::string& path,
///////////////////////////////////////////////////////////////////////////////
DownloadsUI::DownloadsUI(TabContents* contents) : DOMUI(contents) {
- DownloadManager* dlm = GetProfile()->GetOriginalProfile()->
- GetDownloadManager();
+ DownloadManager* dlm = GetProfile()->GetDownloadManager();
DownloadsDOMHandler* handler = new DownloadsDOMHandler(dlm);
AddMessageHandler(handler);
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_);
diff --git a/chrome/browser/resources/downloads.html b/chrome/browser/resources/downloads.html
index de2922c..79e76ef 100644
--- a/chrome/browser/resources/downloads.html
+++ b/chrome/browser/resources/downloads.html
@@ -228,6 +228,11 @@ function Downloads() {
* @param {Object} download A backend download object (see downloads_ui.cc)
*/
Downloads.prototype.updated = function(download) {
+ // For now, simply don't display off the record downloads.
+ // http://crbug.com/36587
+ if (download.otr)
+ return;
+
var id = download.id;
if (!!this.downloads_[id]) {
this.downloads_[id].update(download);