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_service.h" | 10 #include "chrome/browser/infobars/infobar_service.h" |
11 #include "chrome/browser/tab_contents/tab_util.h" | 11 #include "chrome/browser/tab_contents/tab_util.h" |
12 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" | 12 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" |
13 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.
h" | 13 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.
h" |
14 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/navigation_controller.h" | 15 #include "content/public/browser/navigation_controller.h" |
16 #include "content/public/browser/navigation_entry.h" | 16 #include "content/public/browser/navigation_entry.h" |
17 #include "content/public/browser/notification_source.h" | 17 #include "content/public/browser/notification_source.h" |
18 #include "content/public/browser/notification_types.h" | 18 #include "content/public/browser/notification_types.h" |
| 19 #include "content/public/browser/render_process_host.h" |
19 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
20 #include "content/public/browser/web_contents_delegate.h" | 21 #include "content/public/browser/web_contents_delegate.h" |
21 | 22 |
22 using content::BrowserThread; | 23 using content::BrowserThread; |
23 using content::NavigationController; | 24 using content::NavigationController; |
24 using content::NavigationEntry; | 25 using content::NavigationEntry; |
25 using content::WebContents; | 26 using content::WebContents; |
26 | 27 |
27 // TabDownloadState ------------------------------------------------------------ | 28 // TabDownloadState ------------------------------------------------------------ |
28 | 29 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 | 202 |
202 for (size_t i = 0; i < callbacks.size(); ++i) | 203 for (size_t i = 0; i < callbacks.size(); ++i) |
203 host_->ScheduleNotification(callbacks[i], allow); | 204 host_->ScheduleNotification(callbacks[i], allow); |
204 | 205 |
205 if (change_status) | 206 if (change_status) |
206 set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD); | 207 set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD); |
207 } | 208 } |
208 | 209 |
209 // DownloadRequestLimiter ------------------------------------------------------ | 210 // DownloadRequestLimiter ------------------------------------------------------ |
210 | 211 |
211 DownloadRequestLimiter::DownloadRequestLimiter() { | 212 DownloadRequestLimiter::DownloadRequestLimiter() |
| 213 : factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
212 } | 214 } |
213 | 215 |
214 DownloadRequestLimiter::~DownloadRequestLimiter() { | 216 DownloadRequestLimiter::~DownloadRequestLimiter() { |
215 // All the tabs should have closed before us, which sends notification and | 217 // All the tabs should have closed before us, which sends notification and |
216 // removes from state_map_. As such, there should be no pending callbacks. | 218 // removes from state_map_. As such, there should be no pending callbacks. |
217 DCHECK(state_map_.empty()); | 219 DCHECK(state_map_.empty()); |
218 } | 220 } |
219 | 221 |
220 DownloadRequestLimiter::DownloadStatus | 222 DownloadRequestLimiter::DownloadStatus |
221 DownloadRequestLimiter::GetDownloadStatus(WebContents* web_contents) { | 223 DownloadRequestLimiter::GetDownloadStatus(WebContents* web_contents) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
267 | 269 |
268 WebContents* originating_contents = | 270 WebContents* originating_contents = |
269 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); | 271 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); |
270 if (!originating_contents) { | 272 if (!originating_contents) { |
271 // The WebContents was closed, don't allow the download. | 273 // The WebContents was closed, don't allow the download. |
272 ScheduleNotification(callback, false); | 274 ScheduleNotification(callback, false); |
273 return; | 275 return; |
274 } | 276 } |
275 | 277 |
| 278 if (!originating_contents->GetDelegate()) { |
| 279 ScheduleNotification(callback, false); |
| 280 return; |
| 281 } |
| 282 |
| 283 if (originating_contents->GetRenderProcessHost()->IsGuest()) { |
| 284 // Decide asynchronously for BrowserPluginGuest. |
| 285 base::Callback<void(bool)> wrapped_callback = base::Bind( |
| 286 &DownloadRequestLimiter::OnCanDownloadDecidedAsync, |
| 287 factory_.GetWeakPtr(), |
| 288 originating_contents, request_id, request_method, callback); |
| 289 originating_contents->GetDelegate()->CanDownloadAsync( |
| 290 originating_contents->GetRenderViewHost(), |
| 291 request_id, |
| 292 request_method, |
| 293 wrapped_callback); |
| 294 return; |
| 295 } else { |
| 296 // FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order |
| 297 // to cancel the download operation in chrome and let the host browser |
| 298 // take care of it. |
| 299 if (!originating_contents->GetDelegate()->CanDownload( |
| 300 originating_contents->GetRenderViewHost(), |
| 301 request_id, |
| 302 request_method)) { |
| 303 ScheduleNotification(callback, false); |
| 304 return; |
| 305 } |
| 306 } |
| 307 |
276 CanDownloadImpl( | 308 CanDownloadImpl( |
277 originating_contents, | 309 originating_contents, |
278 request_id, | 310 request_id, |
279 request_method, | 311 request_method, |
280 callback); | 312 callback); |
281 } | 313 } |
282 | 314 |
| 315 void DownloadRequestLimiter::OnCanDownloadDecidedAsync( |
| 316 WebContents* originating_contents, |
| 317 int request_id, |
| 318 const std::string& request_method, |
| 319 const Callback& orig_callback, bool allow) { |
| 320 if (!allow) { |
| 321 ScheduleNotification(orig_callback, false); |
| 322 return; |
| 323 } |
| 324 |
| 325 CanDownloadImpl(originating_contents, |
| 326 request_id, |
| 327 request_method, |
| 328 orig_callback); |
| 329 } |
| 330 |
283 void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents, | 331 void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents, |
284 int request_id, | 332 int request_id, |
285 const std::string& request_method, | 333 const std::string& request_method, |
286 const Callback& callback) { | 334 const Callback& callback) { |
287 DCHECK(originating_contents); | 335 DCHECK(originating_contents); |
288 | 336 |
289 // FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order | |
290 // to cancel the download operation in chrome and let the host browser | |
291 // take care of it. | |
292 if (originating_contents->GetDelegate() && | |
293 !originating_contents->GetDelegate()->CanDownload( | |
294 originating_contents->GetRenderViewHost(), | |
295 request_id, | |
296 request_method)) { | |
297 ScheduleNotification(callback, false); | |
298 return; | |
299 } | |
300 | |
301 // If the tab requesting the download is a constrained popup that is not | 337 // If the tab requesting the download is a constrained popup that is not |
302 // shown, treat the request as if it came from the parent. | 338 // shown, treat the request as if it came from the parent. |
303 WebContents* effective_contents = originating_contents; | 339 WebContents* effective_contents = originating_contents; |
304 BlockedContentTabHelper* blocked_content_tab_helper = | 340 BlockedContentTabHelper* blocked_content_tab_helper = |
305 BlockedContentTabHelper::FromWebContents(originating_contents); | 341 BlockedContentTabHelper::FromWebContents(originating_contents); |
306 if (blocked_content_tab_helper && | 342 if (blocked_content_tab_helper && |
307 blocked_content_tab_helper->delegate()) { | 343 blocked_content_tab_helper->delegate()) { |
308 effective_contents = blocked_content_tab_helper->delegate()-> | 344 effective_contents = blocked_content_tab_helper->delegate()-> |
309 GetConstrainingWebContents(originating_contents); | 345 GetConstrainingWebContents(originating_contents); |
310 } | 346 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 bool allow) { | 379 bool allow) { |
344 BrowserThread::PostTask( | 380 BrowserThread::PostTask( |
345 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); | 381 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); |
346 } | 382 } |
347 | 383 |
348 void DownloadRequestLimiter::Remove(TabDownloadState* state) { | 384 void DownloadRequestLimiter::Remove(TabDownloadState* state) { |
349 DCHECK(ContainsKey(state_map_, state->web_contents())); | 385 DCHECK(ContainsKey(state_map_, state->web_contents())); |
350 state_map_.erase(state->web_contents()); | 386 state_map_.erase(state->web_contents()); |
351 delete state; | 387 delete state; |
352 } | 388 } |
OLD | NEW |