Chromium Code Reviews| 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/content_settings/tab_specific_content_settings.h" | 9 #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
| 10 #include "chrome/browser/download/download_permission_request.h" | 10 #include "chrome/browser/download/download_permission_request.h" |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 // removes from state_map_. As such, there should be no pending callbacks. | 272 // removes from state_map_. As such, there should be no pending callbacks. |
| 273 DCHECK(state_map_.empty()); | 273 DCHECK(state_map_.empty()); |
| 274 } | 274 } |
| 275 | 275 |
| 276 DownloadRequestLimiter::DownloadStatus | 276 DownloadRequestLimiter::DownloadStatus |
| 277 DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) { | 277 DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) { |
| 278 TabDownloadState* state = GetDownloadState(web_contents, NULL, false); | 278 TabDownloadState* state = GetDownloadState(web_contents, NULL, false); |
| 279 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD; | 279 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD; |
| 280 } | 280 } |
| 281 | 281 |
| 282 void DownloadRequestLimiter::CanDownloadOnIOThread( | |
| 283 int render_process_host_id, | |
| 284 int render_view_id, | |
| 285 const GURL& url, | |
| 286 const std::string& request_method, | |
| 287 const Callback& callback) { | |
| 288 // This is invoked on the IO thread. Schedule the task to run on the UI | |
| 289 // thread so that we can query UI state. | |
| 290 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 291 BrowserThread::PostTask( | |
| 292 BrowserThread::UI, FROM_HERE, | |
| 293 base::Bind(&DownloadRequestLimiter::CanDownload, this, | |
| 294 render_process_host_id, render_view_id, url, | |
| 295 request_method, callback)); | |
| 296 } | |
| 297 | |
| 298 DownloadRequestLimiter::TabDownloadState* | 282 DownloadRequestLimiter::TabDownloadState* |
| 299 DownloadRequestLimiter::GetDownloadState( | 283 DownloadRequestLimiter::GetDownloadState( |
| 300 content::WebContents* web_contents, | 284 content::WebContents* web_contents, |
| 301 content::WebContents* originating_web_contents, | 285 content::WebContents* originating_web_contents, |
| 302 bool create) { | 286 bool create) { |
| 303 DCHECK(web_contents); | 287 DCHECK(web_contents); |
| 304 StateMap::iterator i = state_map_.find(web_contents); | 288 StateMap::iterator i = state_map_.find(web_contents); |
| 305 if (i != state_map_.end()) | 289 if (i != state_map_.end()) |
| 306 return i->second; | 290 return i->second; |
| 307 | 291 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 318 int render_view_id, | 302 int render_view_id, |
| 319 const GURL& url, | 303 const GURL& url, |
| 320 const std::string& request_method, | 304 const std::string& request_method, |
| 321 const Callback& callback) { | 305 const Callback& callback) { |
| 322 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 306 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 323 | 307 |
| 324 content::WebContents* originating_contents = | 308 content::WebContents* originating_contents = |
| 325 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); | 309 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); |
| 326 if (!originating_contents) { | 310 if (!originating_contents) { |
| 327 // The WebContents was closed, don't allow the download. | 311 // The WebContents was closed, don't allow the download. |
| 328 ScheduleNotification(callback, false); | 312 callback.Run(false); |
| 329 return; | 313 return; |
| 330 } | 314 } |
| 331 | 315 |
| 332 if (!originating_contents->GetDelegate()) { | 316 if (!originating_contents->GetDelegate()) { |
| 333 ScheduleNotification(callback, false); | 317 callback.Run(false); |
| 334 return; | 318 return; |
| 335 } | 319 } |
| 336 | 320 |
| 337 // Note that because |originating_contents| might go away before | 321 // Note that because |originating_contents| might go away before |
| 338 // OnCanDownloadDecided is invoked, we look it up by |render_process_host_id| | 322 // OnCanDownloadDecided is invoked, we look it up by |render_process_host_id| |
| 339 // and |render_view_id|. | 323 // and |render_view_id|. |
| 340 base::Callback<void(bool)> can_download_callback = base::Bind( | 324 base::Callback<void(bool)> can_download_callback = base::Bind( |
| 341 &DownloadRequestLimiter::OnCanDownloadDecided, | 325 &DownloadRequestLimiter::OnCanDownloadDecided, |
| 342 factory_.GetWeakPtr(), | 326 factory_.GetWeakPtr(), |
| 343 render_process_host_id, | 327 render_process_host_id, |
| 344 render_view_id, | 328 render_view_id, |
| 345 request_method, | 329 request_method, |
| 346 callback); | 330 callback); |
| 347 | 331 |
| 348 originating_contents->GetDelegate()->CanDownload( | 332 originating_contents->GetDelegate()->CanDownload( |
| 349 url, | 333 url, |
| 350 request_method, | 334 request_method, |
| 351 can_download_callback); | 335 can_download_callback); |
| 352 } | 336 } |
| 353 | 337 |
| 354 void DownloadRequestLimiter::OnCanDownloadDecided( | 338 void DownloadRequestLimiter::OnCanDownloadDecided( |
| 355 int render_process_host_id, | 339 int render_process_host_id, |
| 356 int render_view_id, | 340 int render_view_id, |
| 357 const std::string& request_method, | 341 const std::string& request_method, |
| 358 const Callback& orig_callback, bool allow) { | 342 const Callback& orig_callback, bool allow) { |
| 359 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 343 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 360 content::WebContents* originating_contents = | 344 content::WebContents* originating_contents = |
| 361 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); | 345 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); |
| 362 if (!originating_contents || !allow) { | 346 if (!originating_contents || !allow) { |
| 363 ScheduleNotification(orig_callback, false); | 347 orig_callback.Run(false); |
| 364 return; | 348 return; |
| 365 } | 349 } |
| 366 | 350 |
| 367 CanDownloadImpl(originating_contents, | 351 CanDownloadImpl(originating_contents, |
| 368 request_method, | 352 request_method, |
| 369 orig_callback); | 353 orig_callback); |
| 370 } | 354 } |
| 371 | 355 |
| 372 HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings( | 356 HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings( |
| 373 content::WebContents* contents) { | 357 content::WebContents* contents) { |
| 374 return content_settings_ ? content_settings_ : Profile::FromBrowserContext( | 358 return content_settings_ ? content_settings_ : Profile::FromBrowserContext( |
| 375 contents->GetBrowserContext())->GetHostContentSettingsMap(); | 359 contents->GetBrowserContext())->GetHostContentSettingsMap(); |
| 376 } | 360 } |
| 377 | 361 |
| 378 void DownloadRequestLimiter::CanDownloadImpl( | 362 void DownloadRequestLimiter::CanDownloadImpl( |
| 379 content::WebContents* originating_contents, | 363 content::WebContents* originating_contents, |
| 380 const std::string& request_method, | 364 const std::string& request_method, |
| 381 const Callback& callback) { | 365 const Callback& callback) { |
| 382 DCHECK(originating_contents); | 366 DCHECK(originating_contents); |
| 383 | 367 |
| 384 TabDownloadState* state = GetDownloadState( | 368 TabDownloadState* state = GetDownloadState( |
| 385 originating_contents, originating_contents, true); | 369 originating_contents, originating_contents, true); |
| 386 switch (state->download_status()) { | 370 switch (state->download_status()) { |
| 387 case ALLOW_ALL_DOWNLOADS: | 371 case ALLOW_ALL_DOWNLOADS: |
| 388 if (state->download_count() && !(state->download_count() % | 372 if (state->download_count() && !(state->download_count() % |
| 389 DownloadRequestLimiter::kMaxDownloadsAtOnce)) | 373 DownloadRequestLimiter::kMaxDownloadsAtOnce)) |
| 390 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); | 374 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); |
| 391 ScheduleNotification(callback, true); | 375 callback.Run(true); |
| 392 state->increment_download_count(); | 376 state->increment_download_count(); |
| 393 break; | 377 break; |
| 394 | 378 |
| 395 case ALLOW_ONE_DOWNLOAD: | 379 case ALLOW_ONE_DOWNLOAD: |
| 396 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); | 380 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); |
| 397 ScheduleNotification(callback, true); | 381 callback.Run(true); |
| 398 state->increment_download_count(); | 382 state->increment_download_count(); |
| 399 break; | 383 break; |
| 400 | 384 |
| 401 case DOWNLOADS_NOT_ALLOWED: | 385 case DOWNLOADS_NOT_ALLOWED: |
| 402 ScheduleNotification(callback, false); | 386 callback.Run(false); |
| 403 break; | 387 break; |
| 404 | 388 |
| 405 case PROMPT_BEFORE_DOWNLOAD: { | 389 case PROMPT_BEFORE_DOWNLOAD: { |
| 406 HostContentSettingsMap* content_settings = GetContentSettings( | 390 HostContentSettingsMap* content_settings = GetContentSettings( |
| 407 originating_contents); | 391 originating_contents); |
| 408 ContentSetting setting = CONTENT_SETTING_ASK; | 392 ContentSetting setting = CONTENT_SETTING_ASK; |
| 409 if (content_settings) | 393 if (content_settings) |
| 410 setting = content_settings->GetContentSetting( | 394 setting = content_settings->GetContentSetting( |
| 411 originating_contents->GetURL(), | 395 originating_contents->GetURL(), |
| 412 originating_contents->GetURL(), | 396 originating_contents->GetURL(), |
| 413 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, | 397 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, |
| 414 std::string()); | 398 std::string()); |
| 415 switch (setting) { | 399 switch (setting) { |
| 416 case CONTENT_SETTING_ALLOW: { | 400 case CONTENT_SETTING_ALLOW: { |
| 417 TabSpecificContentSettings* settings = | 401 TabSpecificContentSettings* settings = |
| 418 TabSpecificContentSettings::FromWebContents( | 402 TabSpecificContentSettings::FromWebContents( |
| 419 originating_contents); | 403 originating_contents); |
| 420 if (settings) | 404 if (settings) |
| 421 settings->SetDownloadsBlocked(false); | 405 settings->SetDownloadsBlocked(false); |
| 422 ScheduleNotification(callback, true); | 406 callback.Run(true); |
| 423 state->increment_download_count(); | 407 state->increment_download_count(); |
| 424 return; | 408 return; |
| 425 } | 409 } |
| 426 case CONTENT_SETTING_BLOCK: { | 410 case CONTENT_SETTING_BLOCK: { |
| 427 TabSpecificContentSettings* settings = | 411 TabSpecificContentSettings* settings = |
| 428 TabSpecificContentSettings::FromWebContents( | 412 TabSpecificContentSettings::FromWebContents( |
| 429 originating_contents); | 413 originating_contents); |
| 430 if (settings) | 414 if (settings) |
| 431 settings->SetDownloadsBlocked(true); | 415 settings->SetDownloadsBlocked(true); |
| 432 ScheduleNotification(callback, false); | 416 callback.Run(false); |
| 433 return; | 417 return; |
| 434 } | 418 } |
| 435 case CONTENT_SETTING_DEFAULT: | 419 case CONTENT_SETTING_DEFAULT: |
| 436 case CONTENT_SETTING_ASK: | 420 case CONTENT_SETTING_ASK: |
| 437 case CONTENT_SETTING_SESSION_ONLY: | 421 case CONTENT_SETTING_SESSION_ONLY: |
| 438 state->PromptUserForDownload(callback); | 422 state->PromptUserForDownload(callback); |
| 439 state->increment_download_count(); | 423 state->increment_download_count(); |
| 440 break; | 424 break; |
| 441 case CONTENT_SETTING_NUM_SETTINGS: | 425 case CONTENT_SETTING_NUM_SETTINGS: |
| 442 default: | 426 default: |
| 443 NOTREACHED(); | 427 NOTREACHED(); |
| 444 return; | 428 return; |
| 445 } | 429 } |
| 446 break; | 430 break; |
| 447 } | 431 } |
| 448 | 432 |
| 449 default: | 433 default: |
| 450 NOTREACHED(); | 434 NOTREACHED(); |
| 451 } | 435 } |
| 452 } | 436 } |
| 453 | 437 |
| 454 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback, | 438 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback, |
|
asanka
2015/07/15 20:23:00
Remove. The notification is now documented to be i
qinmin
2015/07/17 00:42:35
TabDownloadState still calls this method.
But sinc
| |
| 455 bool allow) { | 439 bool allow) { |
| 456 BrowserThread::PostTask( | 440 BrowserThread::PostTask( |
| 457 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); | 441 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); |
| 458 } | 442 } |
| 459 | 443 |
| 460 void DownloadRequestLimiter::Remove(TabDownloadState* state, | 444 void DownloadRequestLimiter::Remove(TabDownloadState* state, |
| 461 content::WebContents* contents) { | 445 content::WebContents* contents) { |
| 462 DCHECK(ContainsKey(state_map_, contents)); | 446 DCHECK(ContainsKey(state_map_, contents)); |
| 463 state_map_.erase(contents); | 447 state_map_.erase(contents); |
| 464 delete state; | 448 delete state; |
| 465 } | 449 } |
| OLD | NEW |