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 |
276 CanDownloadImpl( | 278 if (!originating_contents->GetDelegate()) { |
277 originating_contents, | 279 ScheduleNotification(callback, false); |
| 280 return; |
| 281 } |
| 282 |
| 283 // Note that because |originating_contents| might go away before |
| 284 // OnCanDownloadDecided is invoked, we look it up by |render_process_host_id| |
| 285 // and |render_view_id|. |
| 286 base::Callback<void(bool)> can_download_callback = base::Bind( |
| 287 &DownloadRequestLimiter::OnCanDownloadDecided, |
| 288 factory_.GetWeakPtr(), |
| 289 render_process_host_id, |
| 290 render_view_id, |
278 request_id, | 291 request_id, |
279 request_method, | 292 request_method, |
280 callback); | 293 callback); |
| 294 |
| 295 originating_contents->GetDelegate()->CanDownload( |
| 296 originating_contents->GetRenderViewHost(), |
| 297 request_id, |
| 298 request_method, |
| 299 can_download_callback); |
| 300 } |
| 301 |
| 302 void DownloadRequestLimiter::OnCanDownloadDecided( |
| 303 int render_process_host_id, |
| 304 int render_view_id, |
| 305 int request_id, |
| 306 const std::string& request_method, |
| 307 const Callback& orig_callback, bool allow) { |
| 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 309 WebContents* originating_contents = |
| 310 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); |
| 311 if (!originating_contents || !allow) { |
| 312 ScheduleNotification(orig_callback, false); |
| 313 return; |
| 314 } |
| 315 |
| 316 CanDownloadImpl(originating_contents, |
| 317 request_id, |
| 318 request_method, |
| 319 orig_callback); |
281 } | 320 } |
282 | 321 |
283 void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents, | 322 void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents, |
284 int request_id, | 323 int request_id, |
285 const std::string& request_method, | 324 const std::string& request_method, |
286 const Callback& callback) { | 325 const Callback& callback) { |
287 DCHECK(originating_contents); | 326 DCHECK(originating_contents); |
288 | 327 |
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 | 328 // 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. | 329 // shown, treat the request as if it came from the parent. |
303 WebContents* effective_contents = originating_contents; | 330 WebContents* effective_contents = originating_contents; |
304 BlockedContentTabHelper* blocked_content_tab_helper = | 331 BlockedContentTabHelper* blocked_content_tab_helper = |
305 BlockedContentTabHelper::FromWebContents(originating_contents); | 332 BlockedContentTabHelper::FromWebContents(originating_contents); |
306 if (blocked_content_tab_helper && | 333 if (blocked_content_tab_helper && |
307 blocked_content_tab_helper->delegate()) { | 334 blocked_content_tab_helper->delegate()) { |
308 effective_contents = blocked_content_tab_helper->delegate()-> | 335 effective_contents = blocked_content_tab_helper->delegate()-> |
309 GetConstrainingWebContents(originating_contents); | 336 GetConstrainingWebContents(originating_contents); |
310 } | 337 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 bool allow) { | 370 bool allow) { |
344 BrowserThread::PostTask( | 371 BrowserThread::PostTask( |
345 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); | 372 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); |
346 } | 373 } |
347 | 374 |
348 void DownloadRequestLimiter::Remove(TabDownloadState* state) { | 375 void DownloadRequestLimiter::Remove(TabDownloadState* state) { |
349 DCHECK(ContainsKey(state_map_, state->web_contents())); | 376 DCHECK(ContainsKey(state_map_, state->web_contents())); |
350 state_map_.erase(state->web_contents()); | 377 state_map_.erase(state->web_contents()); |
351 delete state; | 378 delete state; |
352 } | 379 } |
OLD | NEW |