Chromium Code Reviews| 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()); |