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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/download/download_request_limiter.h" 5 #include "chrome/browser/download/download_request_limiter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 10 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
10 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 11 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
11 #include "chrome/browser/infobars/infobar_service.h" 12 #include "chrome/browser/infobars/infobar_service.h"
12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/tab_contents/tab_util.h" 14 #include "chrome/browser/tab_contents/tab_util.h"
14 #include "chrome/common/features.h" 15 #include "chrome/common/features.h"
15 #include "components/content_settings/core/browser/host_content_settings_map.h" 16 #include "components/content_settings/core/browser/host_content_settings_map.h"
16 #include "content/public/browser/browser_context.h" 17 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/navigation_controller.h" 19 #include "content/public/browser/navigation_controller.h"
(...skipping 22 matching lines...) Expand all
41 DownloadRequestLimiter::TabDownloadState::TabDownloadState( 42 DownloadRequestLimiter::TabDownloadState::TabDownloadState(
42 DownloadRequestLimiter* host, 43 DownloadRequestLimiter* host,
43 content::WebContents* contents, 44 content::WebContents* contents,
44 content::WebContents* originating_web_contents) 45 content::WebContents* originating_web_contents)
45 : content::WebContentsObserver(contents), 46 : content::WebContentsObserver(contents),
46 web_contents_(contents), 47 web_contents_(contents),
47 host_(host), 48 host_(host),
48 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), 49 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
49 download_count_(0), 50 download_count_(0),
50 factory_(this) { 51 factory_(this) {
51 content::Source<NavigationController> notification_source( 52 registrar_.Add(
52 &contents->GetController()); 53 this, content::NOTIFICATION_NAV_ENTRY_PENDING,
53 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 54 content::Source<NavigationController>(&contents->GetController()));
54 notification_source); 55 registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
56 content::Source<content::WebContents>(contents));
55 NavigationEntry* last_entry = originating_web_contents ? 57 NavigationEntry* last_entry = originating_web_contents ?
56 originating_web_contents->GetController().GetLastCommittedEntry() : 58 originating_web_contents->GetController().GetLastCommittedEntry() :
57 contents->GetController().GetLastCommittedEntry(); 59 contents->GetController().GetLastCommittedEntry();
58 if (last_entry) 60 if (last_entry)
59 initial_page_host_ = last_entry->GetURL().host(); 61 initial_page_host_ = last_entry->GetURL().host();
60 } 62 }
61 63
62 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() { 64 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() {
63 // We should only be destroyed after the callbacks have been notified. 65 // We should only be destroyed after the callbacks have been notified.
64 DCHECK(callbacks_.empty()); 66 DCHECK(callbacks_.empty());
(...skipping 11 matching lines...) Expand all
76 // When the user reloads the page without responding to the infobar, they 78 // When the user reloads the page without responding to the infobar, they
77 // are expecting DownloadRequestLimiter to behave as if they had just 79 // are expecting DownloadRequestLimiter to behave as if they had just
78 // initially navigated to this page. See http://crbug.com/171372 80 // initially navigated to this page. See http://crbug.com/171372
79 NotifyCallbacks(false); 81 NotifyCallbacks(false);
80 host_->Remove(this, web_contents()); 82 host_->Remove(this, web_contents());
81 // WARNING: We've been deleted. 83 // WARNING: We've been deleted.
82 break; 84 break;
83 case DOWNLOADS_NOT_ALLOWED: 85 case DOWNLOADS_NOT_ALLOWED:
84 case ALLOW_ALL_DOWNLOADS: 86 case ALLOW_ALL_DOWNLOADS:
85 // Don't drop this information. The user has explicitly said that they 87 // Don't drop this information. The user has explicitly said that they
86 // do/don't want downloads from this host. If they accidentally Accepted 88 // do/don't want downloads from this host. If they accidentally Accepted
87 // or Canceled, tough luck, they don't get another chance. They can copy 89 // or Canceled, they can adjust the limiter state by adjusting the
88 // the URL into a new tab, which will make a new DownloadRequestLimiter. 90 // automatic downloads content settings. Alternatively, they can copy the
91 // URL into a new tab, which will make a new DownloadRequestLimiter.
89 // See also the initial_page_host_ logic in Observe() for 92 // See also the initial_page_host_ logic in Observe() for
90 // NOTIFICATION_NAV_ENTRY_PENDING. 93 // NOTIFICATION_NAV_ENTRY_PENDING.
91 break; 94 break;
92 default: 95 default:
93 NOTREACHED(); 96 NOTREACHED();
94 } 97 }
95 } 98 }
96 99
97 void DownloadRequestLimiter::TabDownloadState::DidGetUserGesture() { 100 void DownloadRequestLimiter::TabDownloadState::DidGetUserGesture() {
98 if (is_showing_prompt()) { 101 if (is_showing_prompt()) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 193 }
191 194
192 bool DownloadRequestLimiter::TabDownloadState::is_showing_prompt() const { 195 bool DownloadRequestLimiter::TabDownloadState::is_showing_prompt() const {
193 return factory_.HasWeakPtrs(); 196 return factory_.HasWeakPtrs();
194 } 197 }
195 198
196 void DownloadRequestLimiter::TabDownloadState::Observe( 199 void DownloadRequestLimiter::TabDownloadState::Observe(
197 int type, 200 int type,
198 const content::NotificationSource& source, 201 const content::NotificationSource& source,
199 const content::NotificationDetails& details) { 202 const content::NotificationDetails& details) {
200 DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_PENDING, type); 203 DCHECK(type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED ||
204 type == content::NOTIFICATION_NAV_ENTRY_PENDING);
205
206 // Content settings have been updated for our web contents, e.g. via the OIB
207 // or the settings page. Check to see if the automatic downloads setting is
208 // different to our internal state, and update the internal state to match if
209 // necessary. If there is no content setting persisted, then retain the
210 // current state and do nothing.
211 //
212 // NotifyCallbacks is not called as this notification should be triggered when
213 // a download is not pending.
214 if (type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED) {
215 content::WebContents* contents =
216 content::Source<content::WebContents>(source).ptr();
217 DCHECK_EQ(contents, web_contents());
218
219 // Fetch the content settings map for this web contents, and extract the
220 // automatic downloads permission value.
221 HostContentSettingsMap* content_settings = GetContentSettings(contents);
222 if (content_settings) {
223 ContentSetting setting = content_settings->GetContentSetting(
224 contents->GetURL(), contents->GetURL(),
225 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string());
226
227 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
228 // Case 1: downloads are explicitly allowed in content settings.
229 set_download_status(ALLOW_ALL_DOWNLOADS);
230 } else if (setting == CONTENT_SETTING_BLOCK) {
231 // Case 2: downloads are explicitly blocked in content settings.
232 set_download_status(DOWNLOADS_NOT_ALLOWED);
233 } else if (setting == CONTENT_SETTING_ASK) {
234 // Case 3: downloads are set to ask in content settings.
235 set_download_status(PROMPT_BEFORE_DOWNLOAD);
236 }
237 }
238 return;
239 }
240
241 // Otherwise, there is a pending navigation entry.
201 content::NavigationController* controller = &web_contents()->GetController(); 242 content::NavigationController* controller = &web_contents()->GetController();
202 DCHECK_EQ(controller, content::Source<NavigationController>(source).ptr()); 243 DCHECK_EQ(controller, content::Source<NavigationController>(source).ptr());
203 244
204 // NOTE: Resetting state on a pending navigate isn't ideal. In particular it 245 // NOTE: Resetting state on a pending navigate isn't ideal. In particular it
205 // is possible that queued up downloads for the page before the pending 246 // is possible that queued up downloads for the page before the pending
206 // navigation will be delivered to us after we process this request. If this 247 // navigation will be delivered to us after we process this request. If this
207 // happens we may let a download through that we shouldn't have. But this is 248 // happens we may let a download through that we shouldn't have. But this is
208 // rather rare, and it is difficult to get 100% right, so we don't deal with 249 // rather rare, and it is difficult to get 100% right, so we don't deal with
209 // it. 250 // it.
210 NavigationEntry* entry = controller->GetPendingEntry(); 251 NavigationEntry* entry = controller->GetPendingEntry();
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 NOTREACHED(); 479 NOTREACHED();
439 } 480 }
440 } 481 }
441 482
442 void DownloadRequestLimiter::Remove(TabDownloadState* state, 483 void DownloadRequestLimiter::Remove(TabDownloadState* state,
443 content::WebContents* contents) { 484 content::WebContents* contents) {
444 DCHECK(ContainsKey(state_map_, contents)); 485 DCHECK(ContainsKey(state_map_, contents));
445 state_map_.erase(contents); 486 state_map_.erase(contents);
446 delete state; 487 delete state;
447 } 488 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698