Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1216)

Unified Diff: chrome/browser/download/download_request_limiter.cc

Issue 2561673003: Handle per-tab AUTOMATIC_DOWNLOADS setting in DownloadRequestLimiter. (Closed)
Patch Set: Handle per-tab AUTOMATIC_DOWNLOADS setting in DownloadRequestLimiter. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/download/download_request_limiter.cc
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc
index 00e471659f68a97fa98006c9ad3d006fdc7cc282..886f9cd32a2df9eaf1c6b90c296326382effc2c7 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -8,18 +8,17 @@
#include "base/stl_util.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
+#include "components/content_settings/core/browser/content_settings_details.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/notification_types.h"
+#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/web_contents.h"
@@ -37,6 +36,44 @@ using content::BrowserThread;
using content::NavigationController;
using content::NavigationEntry;
+namespace {
+
+ContentSetting GetSettingFromStatus(
+ DownloadRequestLimiter::DownloadStatus status) {
+ switch (status) {
+ case DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD:
+ case DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD:
+ return CONTENT_SETTING_ASK;
+ case DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS:
+ return CONTENT_SETTING_ALLOW;
+ case DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED:
+ return CONTENT_SETTING_BLOCK;
+ default:
+ NOTREACHED();
+ return CONTENT_SETTING_DEFAULT;
+ }
+}
+
+DownloadRequestLimiter::DownloadStatus GetStatusFromSetting(
+ ContentSetting setting) {
+ switch (setting) {
+ case CONTENT_SETTING_ALLOW:
+ return DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS;
+ case CONTENT_SETTING_BLOCK:
+ return DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED;
+ case CONTENT_SETTING_ASK:
+ case CONTENT_SETTING_DEFAULT:
Bernhard Bauer 2017/01/25 19:01:14 Are these content settings actually used? DEFAULT
alshabalin 2017/02/07 16:16:29 Added NOTREACHED() for SESSION_ONLY. But left the
+ case CONTENT_SETTING_SESSION_ONLY:
+ return DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD;
+ case CONTENT_SETTING_NUM_SETTINGS:
+ case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT:
+ NOTREACHED();
+ return DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD;
+ }
+}
+
+} // namespace
+
// TabDownloadState ------------------------------------------------------------
DownloadRequestLimiter::TabDownloadState::TabDownloadState(
@@ -48,9 +85,9 @@ DownloadRequestLimiter::TabDownloadState::TabDownloadState(
host_(host),
status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
download_count_(0),
+ observer_(this),
factory_(this) {
- registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
- content::Source<content::WebContents>(contents));
+ observer_.Add(DownloadRequestLimiter::GetContentSettings(contents));
Bernhard Bauer 2017/01/25 19:01:14 The DownloadRequestLimiter:: prefix doesn't seem n
alshabalin 2017/02/07 16:16:29 Done.
NavigationEntry* last_entry =
originating_web_contents
? originating_web_contents->GetController().GetLastCommittedEntry()
@@ -67,6 +104,22 @@ DownloadRequestLimiter::TabDownloadState::~TabDownloadState() {
DCHECK(!factory_.HasWeakPtrs());
}
+void DownloadRequestLimiter::TabDownloadState::SetDownloadStatusAndNotify(
+ DownloadRequestLimiter::DownloadStatus status) {
+ DownloadStatus last_status = status_;
+ status_ = status;
+ if (!web_contents())
+ return;
+ ContentSetting last_setting = GetSettingFromStatus(last_status);
+ ContentSetting current_setting = GetSettingFromStatus(status_);
+ if (current_setting == last_setting)
+ return;
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
+ content::Source<content::WebContents>(web_contents()),
+ content::NotificationService::NoDetails());
+}
+
void DownloadRequestLimiter::TabDownloadState::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame())
@@ -194,16 +247,22 @@ void DownloadRequestLimiter::TabDownloadState::SetContentSetting(
void DownloadRequestLimiter::TabDownloadState::Cancel() {
SetContentSetting(CONTENT_SETTING_BLOCK);
- NotifyCallbacks(false);
+ bool throttled = NotifyCallbacks(false);
+ SetDownloadStatusAndNotify(throttled ? PROMPT_BEFORE_DOWNLOAD
+ : DOWNLOADS_NOT_ALLOWED);
}
void DownloadRequestLimiter::TabDownloadState::CancelOnce() {
- NotifyCallbacks(false);
+ bool throttled = NotifyCallbacks(false);
+ SetDownloadStatusAndNotify(throttled ? PROMPT_BEFORE_DOWNLOAD
+ : DOWNLOADS_NOT_ALLOWED);
}
void DownloadRequestLimiter::TabDownloadState::Accept() {
SetContentSetting(CONTENT_SETTING_ALLOW);
- NotifyCallbacks(true);
+ bool throttled = NotifyCallbacks(true);
+ SetDownloadStatusAndNotify(throttled ? PROMPT_BEFORE_DOWNLOAD
+ : ALLOW_ALL_DOWNLOADS);
}
DownloadRequestLimiter::TabDownloadState::TabDownloadState()
@@ -211,17 +270,33 @@ DownloadRequestLimiter::TabDownloadState::TabDownloadState()
host_(NULL),
status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
download_count_(0),
+ observer_(this),
factory_(this) {}
bool DownloadRequestLimiter::TabDownloadState::is_showing_prompt() const {
return factory_.HasWeakPtrs();
}
-void DownloadRequestLimiter::TabDownloadState::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK_EQ(chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, type);
+void DownloadRequestLimiter::TabDownloadState::OnContentSettingChanged(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ std::string resource_identifier) {
+ if (content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS)
+ return;
+
+ // Analogous to TabSpecificContentSettings::OnContentSettingChanged:
+ const ContentSettingsDetails details(primary_pattern, secondary_pattern,
+ content_type, resource_identifier);
+ const NavigationController& controller = web_contents()->GetController();
+ // The visible NavigationEntry is the URL in the URL field of a tab.
+ // Currently this should be matched by the |primary_pattern|.
+ NavigationEntry* entry = controller.GetVisibleEntry();
+ GURL entry_url;
+ if (entry)
+ entry_url = entry->GetURL();
+ if (!details.update_all() && !details.primary_pattern().Matches(entry_url))
+ return;
// Content settings have been updated for our web contents, e.g. via the OIB
// or the settings page. Check to see if the automatic downloads setting is
@@ -231,45 +306,24 @@ void DownloadRequestLimiter::TabDownloadState::Observe(
//
// NotifyCallbacks is not called as this notification should be triggered when
// a download is not pending.
- content::WebContents* contents =
- content::Source<content::WebContents>(source).ptr();
- DCHECK_EQ(contents, web_contents());
-
+ //
// Fetch the content settings map for this web contents, and extract the
// automatic downloads permission value.
- HostContentSettingsMap* content_settings = GetContentSettings(contents);
+ HostContentSettingsMap* content_settings = GetContentSettings(web_contents());
if (!content_settings)
return;
ContentSetting setting = content_settings->GetContentSetting(
- contents->GetURL(), contents->GetURL(),
+ web_contents()->GetURL(), web_contents()->GetURL(),
CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string());
// Update the internal state to match if necessary.
- switch (setting) {
- case CONTENT_SETTING_ALLOW:
- set_download_status(ALLOW_ALL_DOWNLOADS);
- break;
- case CONTENT_SETTING_BLOCK:
- set_download_status(DOWNLOADS_NOT_ALLOWED);
- break;
- case CONTENT_SETTING_ASK:
- case CONTENT_SETTING_DEFAULT:
- case CONTENT_SETTING_SESSION_ONLY:
- set_download_status(PROMPT_BEFORE_DOWNLOAD);
- break;
- case CONTENT_SETTING_NUM_SETTINGS:
- case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT:
- NOTREACHED();
- return;
- }
+ SetDownloadStatusAndNotify(GetStatusFromSetting(setting));
Bernhard Bauer 2017/01/25 19:01:14 Here you convert the setting to a status, and the
alshabalin 2017/02/07 16:16:29 Added UpdateDownloadStatusAndNotify taking Content
}
-void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
- set_download_status(allow ? DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS
- : DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED);
+bool DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
std::vector<DownloadRequestLimiter::Callback> callbacks;
- bool change_status = false;
+ bool throttled = false;
// Selectively send first few notifications only if number of downloads exceed
// kMaxDownloadsAtOnce. In that case, we also retain the infobar instance and
@@ -285,7 +339,7 @@ void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
end = callbacks_.begin() + kMaxDownloadsAtOnce;
callbacks.assign(start, end);
callbacks_.erase(start, end);
- change_status = true;
+ throttled = true;
}
for (const auto& callback : callbacks) {
@@ -294,8 +348,7 @@ void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
base::Bind(callback, allow));
}
- if (change_status)
- set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD);
+ return throttled;
}
// DownloadRequestLimiter ------------------------------------------------------
@@ -406,13 +459,13 @@ void DownloadRequestLimiter::CanDownloadImpl(
if (state->download_count() &&
!(state->download_count() %
DownloadRequestLimiter::kMaxDownloadsAtOnce))
- state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
+ state->SetDownloadStatusAndNotify(PROMPT_BEFORE_DOWNLOAD);
callback.Run(true);
state->increment_download_count();
break;
case ALLOW_ONE_DOWNLOAD:
- state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
+ state->SetDownloadStatusAndNotify(PROMPT_BEFORE_DOWNLOAD);
callback.Run(true);
state->increment_download_count();
break;
@@ -431,19 +484,13 @@ void DownloadRequestLimiter::CanDownloadImpl(
CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string());
switch (setting) {
case CONTENT_SETTING_ALLOW: {
- TabSpecificContentSettings* settings =
- TabSpecificContentSettings::FromWebContents(originating_contents);
- if (settings)
- settings->SetDownloadsBlocked(false);
+ state->SetDownloadStatusAndNotify(ALLOW_ALL_DOWNLOADS);
callback.Run(true);
state->increment_download_count();
return;
}
case CONTENT_SETTING_BLOCK: {
- TabSpecificContentSettings* settings =
- TabSpecificContentSettings::FromWebContents(originating_contents);
- if (settings)
- settings->SetDownloadsBlocked(true);
+ state->SetDownloadStatusAndNotify(DOWNLOADS_NOT_ALLOWED);
callback.Run(false);
return;
}

Powered by Google App Engine
This is Rietveld 408576698