| OLD | NEW |
| 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/chrome_notification_types.h" |
| 10 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 10 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 11 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | |
| 12 #include "chrome/browser/infobars/infobar_service.h" | 11 #include "chrome/browser/infobars/infobar_service.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/tab_contents/tab_util.h" | 13 #include "chrome/browser/tab_contents/tab_util.h" |
| 14 #include "components/content_settings/core/browser/content_settings_details.h" |
| 15 #include "components/content_settings/core/browser/host_content_settings_map.h" | 15 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 16 #include "content/public/browser/browser_context.h" | 16 #include "content/public/browser/browser_context.h" |
| 17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "content/public/browser/navigation_controller.h" | 18 #include "content/public/browser/navigation_controller.h" |
| 19 #include "content/public/browser/navigation_entry.h" | 19 #include "content/public/browser/navigation_entry.h" |
| 20 #include "content/public/browser/navigation_handle.h" | 20 #include "content/public/browser/navigation_handle.h" |
| 21 #include "content/public/browser/notification_source.h" | 21 #include "content/public/browser/notification_service.h" |
| 22 #include "content/public/browser/notification_types.h" | |
| 23 #include "content/public/browser/render_process_host.h" | 22 #include "content/public/browser/render_process_host.h" |
| 24 #include "content/public/browser/resource_dispatcher_host.h" | 23 #include "content/public/browser/resource_dispatcher_host.h" |
| 25 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 26 #include "content/public/browser/web_contents_delegate.h" | 25 #include "content/public/browser/web_contents_delegate.h" |
| 27 #include "url/gurl.h" | 26 #include "url/gurl.h" |
| 28 | 27 |
| 29 #if defined(OS_ANDROID) | 28 #if defined(OS_ANDROID) |
| 30 #include "chrome/browser/download/download_request_infobar_delegate_android.h" | 29 #include "chrome/browser/download/download_request_infobar_delegate_android.h" |
| 31 #else | 30 #else |
| 32 #include "chrome/browser/download/download_permission_request.h" | 31 #include "chrome/browser/download/download_permission_request.h" |
| 33 #include "chrome/browser/permissions/permission_request_manager.h" | 32 #include "chrome/browser/permissions/permission_request_manager.h" |
| 34 #endif | 33 #endif |
| 35 | 34 |
| 36 using content::BrowserThread; | 35 using content::BrowserThread; |
| 37 using content::NavigationController; | 36 using content::NavigationController; |
| 38 using content::NavigationEntry; | 37 using content::NavigationEntry; |
| 39 | 38 |
| 39 namespace { |
| 40 |
| 41 ContentSetting GetSettingFromStatus( |
| 42 DownloadRequestLimiter::DownloadStatus status) { |
| 43 switch (status) { |
| 44 case DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD: |
| 45 case DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD: |
| 46 return CONTENT_SETTING_ASK; |
| 47 case DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS: |
| 48 return CONTENT_SETTING_ALLOW; |
| 49 case DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED: |
| 50 return CONTENT_SETTING_BLOCK; |
| 51 } |
| 52 NOTREACHED(); |
| 53 return CONTENT_SETTING_DEFAULT; |
| 54 } |
| 55 |
| 56 DownloadRequestLimiter::DownloadStatus GetStatusFromSetting( |
| 57 ContentSetting setting) { |
| 58 switch (setting) { |
| 59 case CONTENT_SETTING_ALLOW: |
| 60 return DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS; |
| 61 case CONTENT_SETTING_BLOCK: |
| 62 return DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED; |
| 63 case CONTENT_SETTING_DEFAULT: |
| 64 case CONTENT_SETTING_ASK: |
| 65 return DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD; |
| 66 case CONTENT_SETTING_SESSION_ONLY: |
| 67 case CONTENT_SETTING_NUM_SETTINGS: |
| 68 case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT: |
| 69 NOTREACHED(); |
| 70 return DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD; |
| 71 } |
| 72 NOTREACHED(); |
| 73 return DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD; |
| 74 } |
| 75 |
| 76 } // namespace |
| 77 |
| 40 // TabDownloadState ------------------------------------------------------------ | 78 // TabDownloadState ------------------------------------------------------------ |
| 41 | 79 |
| 42 DownloadRequestLimiter::TabDownloadState::TabDownloadState( | 80 DownloadRequestLimiter::TabDownloadState::TabDownloadState( |
| 43 DownloadRequestLimiter* host, | 81 DownloadRequestLimiter* host, |
| 44 content::WebContents* contents, | 82 content::WebContents* contents, |
| 45 content::WebContents* originating_web_contents) | 83 content::WebContents* originating_web_contents) |
| 46 : content::WebContentsObserver(contents), | 84 : content::WebContentsObserver(contents), |
| 47 web_contents_(contents), | 85 web_contents_(contents), |
| 48 host_(host), | 86 host_(host), |
| 49 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), | 87 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), |
| 50 download_count_(0), | 88 download_count_(0), |
| 89 observer_(this), |
| 51 factory_(this) { | 90 factory_(this) { |
| 52 registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, | 91 observer_.Add(GetContentSettings(contents)); |
| 53 content::Source<content::WebContents>(contents)); | |
| 54 NavigationEntry* last_entry = | 92 NavigationEntry* last_entry = |
| 55 originating_web_contents | 93 originating_web_contents |
| 56 ? originating_web_contents->GetController().GetLastCommittedEntry() | 94 ? originating_web_contents->GetController().GetLastCommittedEntry() |
| 57 : contents->GetController().GetLastCommittedEntry(); | 95 : contents->GetController().GetLastCommittedEntry(); |
| 58 if (last_entry) | 96 if (last_entry) |
| 59 initial_page_host_ = last_entry->GetURL().host(); | 97 initial_page_host_ = last_entry->GetURL().host(); |
| 60 } | 98 } |
| 61 | 99 |
| 62 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() { | 100 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() { |
| 63 // We should only be destroyed after the callbacks have been notified. | 101 // We should only be destroyed after the callbacks have been notified. |
| 64 DCHECK(callbacks_.empty()); | 102 DCHECK(callbacks_.empty()); |
| 65 | 103 |
| 66 // And we should have invalidated the back pointer. | 104 // And we should have invalidated the back pointer. |
| 67 DCHECK(!factory_.HasWeakPtrs()); | 105 DCHECK(!factory_.HasWeakPtrs()); |
| 68 } | 106 } |
| 69 | 107 |
| 108 void DownloadRequestLimiter::TabDownloadState::SetDownloadStatusAndNotify( |
| 109 DownloadStatus status) { |
| 110 SetDownloadStatusAndNotifyImpl(status, GetSettingFromStatus(status)); |
| 111 } |
| 112 |
| 70 void DownloadRequestLimiter::TabDownloadState::DidStartNavigation( | 113 void DownloadRequestLimiter::TabDownloadState::DidStartNavigation( |
| 71 content::NavigationHandle* navigation_handle) { | 114 content::NavigationHandle* navigation_handle) { |
| 72 if (!navigation_handle->IsInMainFrame()) | 115 if (!navigation_handle->IsInMainFrame()) |
| 73 return; | 116 return; |
| 74 | 117 |
| 75 // If the navigation is renderer-initiated (but not user-initiated), ensure | 118 // If the navigation is renderer-initiated (but not user-initiated), ensure |
| 76 // that a prompting or blocking limiter state is not reset, so | 119 // that a prompting or blocking limiter state is not reset, so |
| 77 // window.location.href or meta refresh can't be abused to avoid the limiter. | 120 // window.location.href or meta refresh can't be abused to avoid the limiter. |
| 78 // User-initiated navigations will trigger DidGetUserInteraction, which resets | 121 // User-initiated navigations will trigger DidGetUserInteraction, which resets |
| 79 // the limiter before the navigation starts. | 122 // the limiter before the navigation starts. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 DownloadRequestLimiter::GetContentSettings(web_contents_); | 230 DownloadRequestLimiter::GetContentSettings(web_contents_); |
| 188 if (!settings) | 231 if (!settings) |
| 189 return; | 232 return; |
| 190 settings->SetContentSettingDefaultScope( | 233 settings->SetContentSettingDefaultScope( |
| 191 web_contents_->GetURL(), GURL(), | 234 web_contents_->GetURL(), GURL(), |
| 192 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string(), setting); | 235 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string(), setting); |
| 193 } | 236 } |
| 194 | 237 |
| 195 void DownloadRequestLimiter::TabDownloadState::Cancel() { | 238 void DownloadRequestLimiter::TabDownloadState::Cancel() { |
| 196 SetContentSetting(CONTENT_SETTING_BLOCK); | 239 SetContentSetting(CONTENT_SETTING_BLOCK); |
| 197 NotifyCallbacks(false); | 240 bool throttled = NotifyCallbacks(false); |
| 241 SetDownloadStatusAndNotify(throttled ? PROMPT_BEFORE_DOWNLOAD |
| 242 : DOWNLOADS_NOT_ALLOWED); |
| 198 } | 243 } |
| 199 | 244 |
| 200 void DownloadRequestLimiter::TabDownloadState::CancelOnce() { | 245 void DownloadRequestLimiter::TabDownloadState::CancelOnce() { |
| 201 NotifyCallbacks(false); | 246 bool throttled = NotifyCallbacks(false); |
| 247 SetDownloadStatusAndNotify(throttled ? PROMPT_BEFORE_DOWNLOAD |
| 248 : DOWNLOADS_NOT_ALLOWED); |
| 202 } | 249 } |
| 203 | 250 |
| 204 void DownloadRequestLimiter::TabDownloadState::Accept() { | 251 void DownloadRequestLimiter::TabDownloadState::Accept() { |
| 205 SetContentSetting(CONTENT_SETTING_ALLOW); | 252 SetContentSetting(CONTENT_SETTING_ALLOW); |
| 206 NotifyCallbacks(true); | 253 bool throttled = NotifyCallbacks(true); |
| 254 SetDownloadStatusAndNotify(throttled ? PROMPT_BEFORE_DOWNLOAD |
| 255 : ALLOW_ALL_DOWNLOADS); |
| 207 } | 256 } |
| 208 | 257 |
| 209 DownloadRequestLimiter::TabDownloadState::TabDownloadState() | 258 DownloadRequestLimiter::TabDownloadState::TabDownloadState() |
| 210 : web_contents_(NULL), | 259 : web_contents_(NULL), |
| 211 host_(NULL), | 260 host_(NULL), |
| 212 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), | 261 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), |
| 213 download_count_(0), | 262 download_count_(0), |
| 263 observer_(this), |
| 214 factory_(this) {} | 264 factory_(this) {} |
| 215 | 265 |
| 216 bool DownloadRequestLimiter::TabDownloadState::is_showing_prompt() const { | 266 bool DownloadRequestLimiter::TabDownloadState::is_showing_prompt() const { |
| 217 return factory_.HasWeakPtrs(); | 267 return factory_.HasWeakPtrs(); |
| 218 } | 268 } |
| 219 | 269 |
| 220 void DownloadRequestLimiter::TabDownloadState::Observe( | 270 void DownloadRequestLimiter::TabDownloadState::OnContentSettingChanged( |
| 221 int type, | 271 const ContentSettingsPattern& primary_pattern, |
| 222 const content::NotificationSource& source, | 272 const ContentSettingsPattern& secondary_pattern, |
| 223 const content::NotificationDetails& details) { | 273 ContentSettingsType content_type, |
| 224 DCHECK_EQ(chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, type); | 274 std::string resource_identifier) { |
| 275 if (content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS) |
| 276 return; |
| 277 |
| 278 // Analogous to TabSpecificContentSettings::OnContentSettingChanged: |
| 279 const ContentSettingsDetails details(primary_pattern, secondary_pattern, |
| 280 content_type, resource_identifier); |
| 281 const NavigationController& controller = web_contents()->GetController(); |
| 282 |
| 283 // The visible NavigationEntry is the URL in the URL field of a tab. |
| 284 // Currently this should be matched by the |primary_pattern|. |
| 285 NavigationEntry* entry = controller.GetVisibleEntry(); |
| 286 GURL entry_url; |
| 287 if (entry) |
| 288 entry_url = entry->GetURL(); |
| 289 if (!details.update_all() && !details.primary_pattern().Matches(entry_url)) |
| 290 return; |
| 225 | 291 |
| 226 // Content settings have been updated for our web contents, e.g. via the OIB | 292 // Content settings have been updated for our web contents, e.g. via the OIB |
| 227 // or the settings page. Check to see if the automatic downloads setting is | 293 // or the settings page. Check to see if the automatic downloads setting is |
| 228 // different to our internal state, and update the internal state to match if | 294 // different to our internal state, and update the internal state to match if |
| 229 // necessary. If there is no content setting persisted, then retain the | 295 // necessary. If there is no content setting persisted, then retain the |
| 230 // current state and do nothing. | 296 // current state and do nothing. |
| 231 // | 297 // |
| 232 // NotifyCallbacks is not called as this notification should be triggered when | 298 // NotifyCallbacks is not called as this notification should be triggered when |
| 233 // a download is not pending. | 299 // a download is not pending. |
| 234 content::WebContents* contents = | 300 // |
| 235 content::Source<content::WebContents>(source).ptr(); | |
| 236 DCHECK_EQ(contents, web_contents()); | |
| 237 | |
| 238 // Fetch the content settings map for this web contents, and extract the | 301 // Fetch the content settings map for this web contents, and extract the |
| 239 // automatic downloads permission value. | 302 // automatic downloads permission value. |
| 240 HostContentSettingsMap* content_settings = GetContentSettings(contents); | 303 HostContentSettingsMap* content_settings = GetContentSettings(web_contents()); |
| 241 if (!content_settings) | 304 if (!content_settings) |
| 242 return; | 305 return; |
| 243 | 306 |
| 244 ContentSetting setting = content_settings->GetContentSetting( | 307 ContentSetting setting = content_settings->GetContentSetting( |
| 245 contents->GetURL(), contents->GetURL(), | 308 web_contents()->GetURL(), web_contents()->GetURL(), |
| 246 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string()); | 309 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string()); |
| 247 | 310 |
| 248 // Update the internal state to match if necessary. | 311 // Update the internal state to match if necessary. |
| 249 switch (setting) { | 312 SetDownloadStatusAndNotifyImpl(GetStatusFromSetting(setting), setting); |
| 250 case CONTENT_SETTING_ALLOW: | |
| 251 set_download_status(ALLOW_ALL_DOWNLOADS); | |
| 252 break; | |
| 253 case CONTENT_SETTING_BLOCK: | |
| 254 set_download_status(DOWNLOADS_NOT_ALLOWED); | |
| 255 break; | |
| 256 case CONTENT_SETTING_ASK: | |
| 257 case CONTENT_SETTING_DEFAULT: | |
| 258 case CONTENT_SETTING_SESSION_ONLY: | |
| 259 set_download_status(PROMPT_BEFORE_DOWNLOAD); | |
| 260 break; | |
| 261 case CONTENT_SETTING_NUM_SETTINGS: | |
| 262 case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT: | |
| 263 NOTREACHED(); | |
| 264 return; | |
| 265 } | |
| 266 } | 313 } |
| 267 | 314 |
| 268 void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) { | 315 bool DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) { |
| 269 set_download_status(allow ? DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS | |
| 270 : DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED); | |
| 271 std::vector<DownloadRequestLimiter::Callback> callbacks; | 316 std::vector<DownloadRequestLimiter::Callback> callbacks; |
| 272 bool change_status = false; | 317 bool throttled = false; |
| 273 | 318 |
| 274 // Selectively send first few notifications only if number of downloads exceed | 319 // Selectively send first few notifications only if number of downloads exceed |
| 275 // kMaxDownloadsAtOnce. In that case, we also retain the infobar instance and | 320 // kMaxDownloadsAtOnce. In that case, we also retain the infobar instance and |
| 276 // don't close it. If allow is false, we send all the notifications to cancel | 321 // don't close it. If allow is false, we send all the notifications to cancel |
| 277 // all remaining downloads and close the infobar. | 322 // all remaining downloads and close the infobar. |
| 278 if (!allow || (callbacks_.size() < kMaxDownloadsAtOnce)) { | 323 if (!allow || (callbacks_.size() < kMaxDownloadsAtOnce)) { |
| 279 // Null the generated weak pointer so we don't get notified again. | 324 // Null the generated weak pointer so we don't get notified again. |
| 280 factory_.InvalidateWeakPtrs(); | 325 factory_.InvalidateWeakPtrs(); |
| 281 callbacks.swap(callbacks_); | 326 callbacks.swap(callbacks_); |
| 282 } else { | 327 } else { |
| 283 std::vector<DownloadRequestLimiter::Callback>::iterator start, end; | 328 std::vector<DownloadRequestLimiter::Callback>::iterator start, end; |
| 284 start = callbacks_.begin(); | 329 start = callbacks_.begin(); |
| 285 end = callbacks_.begin() + kMaxDownloadsAtOnce; | 330 end = callbacks_.begin() + kMaxDownloadsAtOnce; |
| 286 callbacks.assign(start, end); | 331 callbacks.assign(start, end); |
| 287 callbacks_.erase(start, end); | 332 callbacks_.erase(start, end); |
| 288 change_status = true; | 333 throttled = true; |
| 289 } | 334 } |
| 290 | 335 |
| 291 for (const auto& callback : callbacks) { | 336 for (const auto& callback : callbacks) { |
| 292 // When callback runs, it can cause the WebContents to be destroyed. | 337 // When callback runs, it can cause the WebContents to be destroyed. |
| 293 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 338 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 294 base::Bind(callback, allow)); | 339 base::Bind(callback, allow)); |
| 295 } | 340 } |
| 296 | 341 |
| 297 if (change_status) | 342 return throttled; |
| 298 set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD); | 343 } |
| 344 |
| 345 void DownloadRequestLimiter::TabDownloadState::SetDownloadStatusAndNotifyImpl( |
| 346 DownloadStatus status, |
| 347 ContentSetting setting) { |
| 348 DCHECK((GetSettingFromStatus(status) == setting) || |
| 349 (GetStatusFromSetting(setting) == status)) |
| 350 << "status " << status << " and setting " << setting |
| 351 << " do not correspond to each other"; |
| 352 |
| 353 ContentSetting last_setting = GetSettingFromStatus(status_); |
| 354 status_ = status; |
| 355 if (!web_contents()) |
| 356 return; |
| 357 if (last_setting == setting) |
| 358 return; |
| 359 content::NotificationService::current()->Notify( |
| 360 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, |
| 361 content::Source<content::WebContents>(web_contents()), |
| 362 content::NotificationService::NoDetails()); |
| 299 } | 363 } |
| 300 | 364 |
| 301 // DownloadRequestLimiter ------------------------------------------------------ | 365 // DownloadRequestLimiter ------------------------------------------------------ |
| 302 | 366 |
| 303 HostContentSettingsMap* DownloadRequestLimiter::content_settings_ = NULL; | |
| 304 | |
| 305 void DownloadRequestLimiter::SetContentSettingsForTesting( | |
| 306 HostContentSettingsMap* content_settings) { | |
| 307 content_settings_ = content_settings; | |
| 308 } | |
| 309 | |
| 310 DownloadRequestLimiter::DownloadRequestLimiter() : factory_(this) {} | 367 DownloadRequestLimiter::DownloadRequestLimiter() : factory_(this) {} |
| 311 | 368 |
| 312 DownloadRequestLimiter::~DownloadRequestLimiter() { | 369 DownloadRequestLimiter::~DownloadRequestLimiter() { |
| 313 // All the tabs should have closed before us, which sends notification and | 370 // All the tabs should have closed before us, which sends notification and |
| 314 // removes from state_map_. As such, there should be no pending callbacks. | 371 // removes from state_map_. As such, there should be no pending callbacks. |
| 315 DCHECK(state_map_.empty()); | 372 DCHECK(state_map_.empty()); |
| 316 } | 373 } |
| 317 | 374 |
| 318 DownloadRequestLimiter::DownloadStatus | 375 DownloadRequestLimiter::DownloadStatus |
| 319 DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) { | 376 DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 if (!originating_contents || !allow) { | 437 if (!originating_contents || !allow) { |
| 381 orig_callback.Run(false); | 438 orig_callback.Run(false); |
| 382 return; | 439 return; |
| 383 } | 440 } |
| 384 | 441 |
| 385 CanDownloadImpl(originating_contents, request_method, orig_callback); | 442 CanDownloadImpl(originating_contents, request_method, orig_callback); |
| 386 } | 443 } |
| 387 | 444 |
| 388 HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings( | 445 HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings( |
| 389 content::WebContents* contents) { | 446 content::WebContents* contents) { |
| 390 return content_settings_ | 447 return HostContentSettingsMapFactory::GetForProfile( |
| 391 ? content_settings_ | 448 Profile::FromBrowserContext(contents->GetBrowserContext())); |
| 392 : HostContentSettingsMapFactory::GetForProfile( | |
| 393 Profile::FromBrowserContext(contents->GetBrowserContext())); | |
| 394 } | 449 } |
| 395 | 450 |
| 396 void DownloadRequestLimiter::CanDownloadImpl( | 451 void DownloadRequestLimiter::CanDownloadImpl( |
| 397 content::WebContents* originating_contents, | 452 content::WebContents* originating_contents, |
| 398 const std::string& request_method, | 453 const std::string& request_method, |
| 399 const Callback& callback) { | 454 const Callback& callback) { |
| 400 DCHECK(originating_contents); | 455 DCHECK(originating_contents); |
| 401 | 456 |
| 402 TabDownloadState* state = | 457 TabDownloadState* state = |
| 403 GetDownloadState(originating_contents, originating_contents, true); | 458 GetDownloadState(originating_contents, originating_contents, true); |
| 404 switch (state->download_status()) { | 459 switch (state->download_status()) { |
| 405 case ALLOW_ALL_DOWNLOADS: | 460 case ALLOW_ALL_DOWNLOADS: |
| 406 if (state->download_count() && | 461 if (state->download_count() && |
| 407 !(state->download_count() % | 462 !(state->download_count() % |
| 408 DownloadRequestLimiter::kMaxDownloadsAtOnce)) | 463 DownloadRequestLimiter::kMaxDownloadsAtOnce)) |
| 409 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); | 464 state->SetDownloadStatusAndNotify(PROMPT_BEFORE_DOWNLOAD); |
| 410 callback.Run(true); | 465 callback.Run(true); |
| 411 state->increment_download_count(); | 466 state->increment_download_count(); |
| 412 break; | 467 break; |
| 413 | 468 |
| 414 case ALLOW_ONE_DOWNLOAD: | 469 case ALLOW_ONE_DOWNLOAD: |
| 415 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); | 470 state->SetDownloadStatusAndNotify(PROMPT_BEFORE_DOWNLOAD); |
| 416 callback.Run(true); | 471 callback.Run(true); |
| 417 state->increment_download_count(); | 472 state->increment_download_count(); |
| 418 break; | 473 break; |
| 419 | 474 |
| 420 case DOWNLOADS_NOT_ALLOWED: | 475 case DOWNLOADS_NOT_ALLOWED: |
| 421 callback.Run(false); | 476 callback.Run(false); |
| 422 break; | 477 break; |
| 423 | 478 |
| 424 case PROMPT_BEFORE_DOWNLOAD: { | 479 case PROMPT_BEFORE_DOWNLOAD: { |
| 425 HostContentSettingsMap* content_settings = | 480 HostContentSettingsMap* content_settings = |
| 426 GetContentSettings(originating_contents); | 481 GetContentSettings(originating_contents); |
| 427 ContentSetting setting = CONTENT_SETTING_ASK; | 482 ContentSetting setting = CONTENT_SETTING_ASK; |
| 428 if (content_settings) | 483 if (content_settings) |
| 429 setting = content_settings->GetContentSetting( | 484 setting = content_settings->GetContentSetting( |
| 430 originating_contents->GetURL(), originating_contents->GetURL(), | 485 originating_contents->GetURL(), originating_contents->GetURL(), |
| 431 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string()); | 486 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string()); |
| 432 switch (setting) { | 487 switch (setting) { |
| 433 case CONTENT_SETTING_ALLOW: { | 488 case CONTENT_SETTING_ALLOW: { |
| 434 TabSpecificContentSettings* settings = | 489 state->SetDownloadStatusAndNotify(ALLOW_ALL_DOWNLOADS); |
| 435 TabSpecificContentSettings::FromWebContents(originating_contents); | |
| 436 if (settings) | |
| 437 settings->SetDownloadsBlocked(false); | |
| 438 callback.Run(true); | 490 callback.Run(true); |
| 439 state->increment_download_count(); | 491 state->increment_download_count(); |
| 440 return; | 492 return; |
| 441 } | 493 } |
| 442 case CONTENT_SETTING_BLOCK: { | 494 case CONTENT_SETTING_BLOCK: { |
| 443 TabSpecificContentSettings* settings = | 495 state->SetDownloadStatusAndNotify(DOWNLOADS_NOT_ALLOWED); |
| 444 TabSpecificContentSettings::FromWebContents(originating_contents); | |
| 445 if (settings) | |
| 446 settings->SetDownloadsBlocked(true); | |
| 447 callback.Run(false); | 496 callback.Run(false); |
| 448 return; | 497 return; |
| 449 } | 498 } |
| 450 case CONTENT_SETTING_DEFAULT: | 499 case CONTENT_SETTING_DEFAULT: |
| 451 case CONTENT_SETTING_ASK: | 500 case CONTENT_SETTING_ASK: |
| 452 case CONTENT_SETTING_SESSION_ONLY: | |
| 453 state->PromptUserForDownload(callback); | 501 state->PromptUserForDownload(callback); |
| 454 state->increment_download_count(); | 502 state->increment_download_count(); |
| 455 break; | 503 break; |
| 504 case CONTENT_SETTING_SESSION_ONLY: |
| 456 case CONTENT_SETTING_NUM_SETTINGS: | 505 case CONTENT_SETTING_NUM_SETTINGS: |
| 457 default: | 506 default: |
| 458 NOTREACHED(); | 507 NOTREACHED(); |
| 459 return; | 508 return; |
| 460 } | 509 } |
| 461 break; | 510 break; |
| 462 } | 511 } |
| 463 | 512 |
| 464 default: | 513 default: |
| 465 NOTREACHED(); | 514 NOTREACHED(); |
| 466 } | 515 } |
| 467 } | 516 } |
| 468 | 517 |
| 469 void DownloadRequestLimiter::Remove(TabDownloadState* state, | 518 void DownloadRequestLimiter::Remove(TabDownloadState* state, |
| 470 content::WebContents* contents) { | 519 content::WebContents* contents) { |
| 471 DCHECK(base::ContainsKey(state_map_, contents)); | 520 DCHECK(base::ContainsKey(state_map_, contents)); |
| 472 state_map_.erase(contents); | 521 state_map_.erase(contents); |
| 473 delete state; | 522 delete state; |
| 474 } | 523 } |
| OLD | NEW |