Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: chrome/browser/download/download_request_limiter.cc

Issue 10409031: Fix crash when download from popup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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;
OLDNEW
« no previous file with comments | « chrome/browser/download/download_request_limiter.h ('k') | chrome/browser/download/download_request_limiter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698