| 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/download/download_request_infobar_delegate.h" | 9 #include "chrome/browser/download/download_request_infobar_delegate.h" |
| 10 #include "chrome/browser/infobars/infobar_tab_helper.h" | 10 #include "chrome/browser/infobars/infobar_tab_helper.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 } | 204 } |
| 205 | 205 |
| 206 DownloadRequestLimiter::~DownloadRequestLimiter() { | 206 DownloadRequestLimiter::~DownloadRequestLimiter() { |
| 207 // All the tabs should have closed before us, which sends notification and | 207 // All the tabs should have closed before us, which sends notification and |
| 208 // removes from state_map_. As such, there should be no pending callbacks. | 208 // removes from state_map_. As such, there should be no pending callbacks. |
| 209 DCHECK(state_map_.empty()); | 209 DCHECK(state_map_.empty()); |
| 210 } | 210 } |
| 211 | 211 |
| 212 DownloadRequestLimiter::DownloadStatus | 212 DownloadRequestLimiter::DownloadStatus |
| 213 DownloadRequestLimiter::GetDownloadStatus(WebContents* tab) { | 213 DownloadRequestLimiter::GetDownloadStatus(WebContents* tab) { |
| 214 TabDownloadState* state = GetDownloadState(&tab->GetController(), NULL, false)
; | 214 TabDownloadState* state = |
| 215 GetDownloadState(&tab->GetController(), NULL, false); |
| 215 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD; | 216 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD; |
| 216 } | 217 } |
| 217 | 218 |
| 218 void DownloadRequestLimiter::CanDownloadOnIOThread( | 219 void DownloadRequestLimiter::CanDownloadOnIOThread( |
| 219 int render_process_host_id, | 220 int render_process_host_id, |
| 220 int render_view_id, | 221 int render_view_id, |
| 221 int request_id, | 222 int request_id, |
| 222 const std::string& request_method, | 223 const std::string& request_method, |
| 223 const Callback& callback) { | 224 const Callback& callback) { |
| 224 // This is invoked on the IO thread. Schedule the task to run on the UI | 225 // This is invoked on the IO thread. Schedule the task to run on the UI |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 return state; | 264 return state; |
| 264 } | 265 } |
| 265 | 266 |
| 266 void DownloadRequestLimiter::CanDownload(int render_process_host_id, | 267 void DownloadRequestLimiter::CanDownload(int render_process_host_id, |
| 267 int render_view_id, | 268 int render_view_id, |
| 268 int request_id, | 269 int request_id, |
| 269 const std::string& request_method, | 270 const std::string& request_method, |
| 270 const Callback& callback) { | 271 const Callback& callback) { |
| 271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 272 | 273 |
| 273 WebContents* originating_tab = | 274 WebContents* originating_contents = |
| 274 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); | 275 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); |
| 275 if (!originating_tab) { | 276 if (!originating_contents) { |
| 276 // The tab was closed, don't allow the download. | 277 // The tab was closed, don't allow the download. |
| 277 ScheduleNotification(callback, false); | 278 ScheduleNotification(callback, false); |
| 278 return; | 279 return; |
| 279 } | 280 } |
| 280 | 281 |
| 281 CanDownloadImpl( | 282 CanDownloadImpl( |
| 282 TabContentsWrapper::GetCurrentWrapperForContents(originating_tab), | 283 originating_contents, |
| 283 request_id, | 284 request_id, |
| 284 request_method, | 285 request_method, |
| 285 callback); | 286 callback); |
| 286 } | 287 } |
| 287 | 288 |
| 288 void DownloadRequestLimiter::CanDownloadImpl( | 289 void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents, |
| 289 TabContentsWrapper* originating_tab, | 290 int request_id, |
| 290 int request_id, | 291 const std::string& request_method, |
| 291 const std::string& request_method, | 292 const Callback& callback) { |
| 292 const Callback& callback) { | 293 DCHECK(originating_contents); |
| 293 DCHECK(originating_tab); | |
| 294 | 294 |
| 295 // FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order | 295 // FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order |
| 296 // to cancel the download operation in chrome and let the host browser | 296 // to cancel the download operation in chrome and let the host browser |
| 297 // take care of it. | 297 // take care of it. |
| 298 WebContents* tab = originating_tab->web_contents(); | 298 if (originating_contents->GetDelegate() && |
| 299 if (tab->GetDelegate() && !tab->GetDelegate()->CanDownload( | 299 !originating_contents->GetDelegate()->CanDownload( |
| 300 tab->GetRenderViewHost(), request_id, request_method)) { | 300 originating_contents->GetRenderViewHost(), |
| 301 request_id, |
| 302 request_method)) { |
| 301 ScheduleNotification(callback, false); | 303 ScheduleNotification(callback, false); |
| 302 return; | 304 return; |
| 303 } | 305 } |
| 304 | 306 |
| 305 // If the tab requesting the download is a constrained popup that is not | 307 // If the tab requesting the download is a constrained popup that is not |
| 306 // shown, treat the request as if it came from the parent. | 308 // shown, treat the request as if it came from the parent. |
| 307 TabContentsWrapper* effective_wrapper = originating_tab; | 309 WebContents* effective_contents = originating_contents; |
| 308 if (effective_wrapper->blocked_content_tab_helper()->delegate()) { | 310 TabContentsWrapper* originating_wrapper = |
| 309 effective_wrapper = effective_wrapper->blocked_content_tab_helper()-> | 311 TabContentsWrapper::GetCurrentWrapperForContents(originating_contents); |
| 310 delegate()->GetConstrainingContentsWrapper(effective_wrapper); | 312 if (originating_wrapper && |
| 313 originating_wrapper->blocked_content_tab_helper()->delegate()) { |
| 314 effective_contents = originating_wrapper->blocked_content_tab_helper()-> |
| 315 delegate()->GetConstrainingContentsWrapper(originating_wrapper)-> |
| 316 web_contents(); |
| 311 } | 317 } |
| 312 | 318 |
| 313 TabDownloadState* state = GetDownloadState( | 319 TabDownloadState* state = GetDownloadState( |
| 314 &effective_wrapper->web_contents()->GetController(), | 320 &effective_contents->GetController(), |
| 315 &tab->GetController(), true); | 321 &originating_contents->GetController(), |
| 322 true); |
| 316 switch (state->download_status()) { | 323 switch (state->download_status()) { |
| 317 case ALLOW_ALL_DOWNLOADS: | 324 case ALLOW_ALL_DOWNLOADS: |
| 318 if (state->download_count() && !(state->download_count() % | 325 if (state->download_count() && !(state->download_count() % |
| 319 DownloadRequestLimiter::kMaxDownloadsAtOnce)) | 326 DownloadRequestLimiter::kMaxDownloadsAtOnce)) |
| 320 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); | 327 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); |
| 321 ScheduleNotification(callback, true); | 328 ScheduleNotification(callback, true); |
| 322 state->increment_download_count(); | 329 state->increment_download_count(); |
| 323 break; | 330 break; |
| 324 | 331 |
| 325 case ALLOW_ONE_DOWNLOAD: | 332 case ALLOW_ONE_DOWNLOAD: |
| 326 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); | 333 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); |
| 327 ScheduleNotification(callback, true); | 334 ScheduleNotification(callback, true); |
| 328 break; | 335 break; |
| 329 | 336 |
| 330 case DOWNLOADS_NOT_ALLOWED: | 337 case DOWNLOADS_NOT_ALLOWED: |
| 331 ScheduleNotification(callback, false); | 338 ScheduleNotification(callback, false); |
| 332 break; | 339 break; |
| 333 | 340 |
| 334 case PROMPT_BEFORE_DOWNLOAD: | 341 case PROMPT_BEFORE_DOWNLOAD: |
| 335 state->PromptUserForDownload(effective_wrapper->web_contents(), callback); | 342 state->PromptUserForDownload(effective_contents, callback); |
| 336 state->increment_download_count(); | 343 state->increment_download_count(); |
| 337 break; | 344 break; |
| 338 | 345 |
| 339 default: | 346 default: |
| 340 NOTREACHED(); | 347 NOTREACHED(); |
| 341 } | 348 } |
| 342 } | 349 } |
| 343 | 350 |
| 344 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback, | 351 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback, |
| 345 bool allow) { | 352 bool allow) { |
| 346 BrowserThread::PostTask( | 353 BrowserThread::PostTask( |
| 347 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); | 354 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); |
| 348 } | 355 } |
| 349 | 356 |
| 350 void DownloadRequestLimiter::Remove(TabDownloadState* state) { | 357 void DownloadRequestLimiter::Remove(TabDownloadState* state) { |
| 351 DCHECK(ContainsKey(state_map_, state->controller())); | 358 DCHECK(ContainsKey(state_map_, state->controller())); |
| 352 state_map_.erase(state->controller()); | 359 state_map_.erase(state->controller()); |
| 353 delete state; | 360 delete state; |
| 354 } | 361 } |
| 355 | 362 |
| 356 // static | 363 // static |
| 357 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = | 364 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = |
| 358 NULL; | 365 NULL; |
| OLD | NEW |