diff options
-rw-r--r-- | chrome/browser/download/download_request_infobar_delegate.cc | 4 | ||||
-rw-r--r-- | chrome/browser/download/download_request_manager.cc | 38 | ||||
-rw-r--r-- | chrome/browser/download/download_request_manager.h | 14 |
3 files changed, 47 insertions, 9 deletions
diff --git a/chrome/browser/download/download_request_infobar_delegate.cc b/chrome/browser/download/download_request_infobar_delegate.cc index 3a6aa5d..88c83fc 100644 --- a/chrome/browser/download/download_request_infobar_delegate.cc +++ b/chrome/browser/download/download_request_infobar_delegate.cc @@ -51,9 +51,9 @@ std::wstring DownloadRequestInfoBarDelegate::GetButtonLabel( bool DownloadRequestInfoBarDelegate::Accept() { if (host_) { host_->Accept(); - host_ = NULL; } - return true; + // Accept() call will nullify host_ if no furthur prompts are required. + return !host_; } bool DownloadRequestInfoBarDelegate::Cancel() { diff --git a/chrome/browser/download/download_request_manager.cc b/chrome/browser/download/download_request_manager.cc index 4498233..9e86736 100644 --- a/chrome/browser/download/download_request_manager.cc +++ b/chrome/browser/download/download_request_manager.cc @@ -135,18 +135,37 @@ void DownloadRequestManager::TabDownloadState::Observe( } void DownloadRequestManager::TabDownloadState::NotifyCallbacks(bool allow) { - if (infobar_) { - // Reset the delegate so we don't get notified again. - infobar_->set_host(NULL); - infobar_ = NULL; - } status_ = allow ? DownloadRequestManager::ALLOW_ALL_DOWNLOADS : DownloadRequestManager::DOWNLOADS_NOT_ALLOWED; std::vector<DownloadRequestManager::Callback*> callbacks; - callbacks.swap(callbacks_); - for (size_t i = 0; i < callbacks.size(); ++i) + bool change_status = false; + + // Selectively send first few notifications only if number of downloads exceed + // kMaxDownloadsAtOnce. In that case, we also retain the infobar instance and + // don't close it. If allow is false, we send all the notifications to cancel + // all remaining downloads and close the infobar. + if (!allow || (callbacks_.size() < kMaxDownloadsAtOnce)) { + if (infobar_) { + // Reset the delegate so we don't get notified again. + infobar_->set_host(NULL); + infobar_ = NULL; + } + callbacks.swap(callbacks_); + } else { + std::vector<DownloadRequestManager::Callback*>::iterator start, end; + start = callbacks_.begin(); + end = callbacks_.begin() + kMaxDownloadsAtOnce; + callbacks.assign(start, end); + callbacks_.erase(start, end); + change_status = true; + } + + for (size_t i = 0; i < callbacks.size(); ++i) { host_->ScheduleNotification(callbacks[i], allow); + } + if (change_status) + status_ = DownloadRequestManager::PROMPT_BEFORE_DOWNLOAD; } // DownloadRequestManager ------------------------------------------------------ @@ -247,7 +266,11 @@ void DownloadRequestManager::CanDownloadImpl( &effective_tab->controller(), &originating_tab->controller(), true); switch (state->download_status()) { case ALLOW_ALL_DOWNLOADS: + if (state->download_count() && !(state->download_count() % + DownloadRequestManager::kMaxDownloadsAtOnce)) + state->set_download_status(PROMPT_BEFORE_DOWNLOAD); ScheduleNotification(callback, true); + state->increment_download_count(); break; case ALLOW_ONE_DOWNLOAD: @@ -261,6 +284,7 @@ void DownloadRequestManager::CanDownloadImpl( case PROMPT_BEFORE_DOWNLOAD: state->PromptUserForDownload(effective_tab, callback); + state->increment_download_count(); break; default: diff --git a/chrome/browser/download/download_request_manager.h b/chrome/browser/download/download_request_manager.h index cea0536..97fa7f8 100644 --- a/chrome/browser/download/download_request_manager.h +++ b/chrome/browser/download/download_request_manager.h @@ -51,6 +51,9 @@ class DownloadRequestManager DOWNLOADS_NOT_ALLOWED }; + // Max number of downloads before a "Prompt Before Download" Dialog is shown. + static const size_t kMaxDownloadsAtOnce = 50; + // The callback from CanDownloadOnIOThread. This is invoked on the io thread. class Callback { public: @@ -87,6 +90,14 @@ class DownloadRequestManager return status_; } + // Number of "ALLOWED" downloads. + void increment_download_count() { + download_count_++; + } + size_t download_count() const { + return download_count_; + } + // Invoked when a user gesture occurs (mouse click, enter or space). This // may result in invoking Remove on DownloadRequestManager. void OnUserGesture(); @@ -114,6 +125,7 @@ class DownloadRequestManager : host_(NULL), controller_(NULL), status_(DownloadRequestManager::ALLOW_ONE_DOWNLOAD), + download_count_(0), infobar_(NULL) { } @@ -136,6 +148,8 @@ class DownloadRequestManager DownloadRequestManager::DownloadStatus status_; + size_t download_count_; + // Callbacks we need to notify. This is only non-empty if we're showing a // dialog. // See description above CanDownloadOnIOThread for details on lifetime of |