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

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

Issue 1675533002: Make the download request limiter listen to content settings changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 10 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 4650c7a49485a29a5079650993f624dec33fca98..d718ac4f56fe8b67339b1244d20eea76c2cd6e92 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#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"
@@ -48,10 +49,11 @@ DownloadRequestLimiter::TabDownloadState::TabDownloadState(
status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
download_count_(0),
factory_(this) {
- content::Source<NavigationController> notification_source(
- &contents->GetController());
- registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
- notification_source);
+ registrar_.Add(
+ this, content::NOTIFICATION_NAV_ENTRY_PENDING,
+ content::Source<NavigationController>(&contents->GetController()));
+ registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
+ content::Source<content::WebContents>(contents));
NavigationEntry* last_entry = originating_web_contents ?
originating_web_contents->GetController().GetLastCommittedEntry() :
contents->GetController().GetLastCommittedEntry();
@@ -83,9 +85,10 @@ void DownloadRequestLimiter::TabDownloadState::DidNavigateMainFrame(
case DOWNLOADS_NOT_ALLOWED:
case ALLOW_ALL_DOWNLOADS:
// Don't drop this information. The user has explicitly said that they
- // do/don't want downloads from this host. If they accidentally Accepted
- // or Canceled, tough luck, they don't get another chance. They can copy
- // the URL into a new tab, which will make a new DownloadRequestLimiter.
+ // do/don't want downloads from this host. If they accidentally Accepted
+ // or Canceled, they can adjust the limiter state by adjusting the
+ // automatic downloads content settings. Alternatively, they can copy the
+ // URL into a new tab, which will make a new DownloadRequestLimiter.
// See also the initial_page_host_ logic in Observe() for
// NOTIFICATION_NAV_ENTRY_PENDING.
break;
@@ -197,7 +200,45 @@ void DownloadRequestLimiter::TabDownloadState::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_PENDING, type);
+ DCHECK(type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED ||
+ type == content::NOTIFICATION_NAV_ENTRY_PENDING);
+
+ // 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
+ // different to our internal state, and update the internal state to match if
+ // necessary. If there is no content setting persisted, then retain the
+ // current state and do nothing.
+ //
+ // NotifyCallbacks is not called as this notification should be triggered when
+ // a download is not pending.
+ if (type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED) {
+ 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);
+ if (content_settings) {
+ ContentSetting setting = content_settings->GetContentSetting(
+ contents->GetURL(), contents->GetURL(),
+ CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string());
+
+ if (setting == CONTENT_SETTING_ALLOW) {
asanka 2016/02/08 15:02:14 Nit: use a switch and cover all the settings so th
dominickn 2016/02/11 01:25:53 Done - made this consistent with DownloadRequestLi
+ // Case 1: downloads are explicitly allowed in content settings.
+ set_download_status(ALLOW_ALL_DOWNLOADS);
+ } else if (setting == CONTENT_SETTING_BLOCK) {
+ // Case 2: downloads are explicitly blocked in content settings.
+ set_download_status(DOWNLOADS_NOT_ALLOWED);
+ } else if (setting == CONTENT_SETTING_ASK) {
+ // Case 3: downloads are set to ask in content settings.
+ set_download_status(PROMPT_BEFORE_DOWNLOAD);
+ }
+ }
+ return;
+ }
+
+ // Otherwise, there is a pending navigation entry.
content::NavigationController* controller = &web_contents()->GetController();
DCHECK_EQ(controller, content::Source<NavigationController>(source).ptr());

Powered by Google App Engine
This is Rietveld 408576698