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

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

Issue 1229933010: move file access permission logic to DownloadResourceThrottle (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits Created 5 years, 5 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
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/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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 callbacks.swap(callbacks_); 240 callbacks.swap(callbacks_);
241 } else { 241 } else {
242 std::vector<DownloadRequestLimiter::Callback>::iterator start, end; 242 std::vector<DownloadRequestLimiter::Callback>::iterator start, end;
243 start = callbacks_.begin(); 243 start = callbacks_.begin();
244 end = callbacks_.begin() + kMaxDownloadsAtOnce; 244 end = callbacks_.begin() + kMaxDownloadsAtOnce;
245 callbacks.assign(start, end); 245 callbacks.assign(start, end);
246 callbacks_.erase(start, end); 246 callbacks_.erase(start, end);
247 change_status = true; 247 change_status = true;
248 } 248 }
249 249
250 for (size_t i = 0; i < callbacks.size(); ++i) 250 for (const auto& callback : callbacks) {
251 host_->ScheduleNotification(callbacks[i], allow); 251 // When callback runs, it can cause the WebContents to be destroyed.
252 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
253 base::Bind(callback, allow));
254 }
252 255
253 if (change_status) 256 if (change_status)
254 set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD); 257 set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD);
255 } 258 }
256 259
257 // DownloadRequestLimiter ------------------------------------------------------ 260 // DownloadRequestLimiter ------------------------------------------------------
258 261
259 HostContentSettingsMap* DownloadRequestLimiter::content_settings_ = NULL; 262 HostContentSettingsMap* DownloadRequestLimiter::content_settings_ = NULL;
260 263
261 void DownloadRequestLimiter::SetContentSettingsForTesting( 264 void DownloadRequestLimiter::SetContentSettingsForTesting(
(...skipping 10 matching lines...) Expand all
272 // removes from state_map_. As such, there should be no pending callbacks. 275 // removes from state_map_. As such, there should be no pending callbacks.
273 DCHECK(state_map_.empty()); 276 DCHECK(state_map_.empty());
274 } 277 }
275 278
276 DownloadRequestLimiter::DownloadStatus 279 DownloadRequestLimiter::DownloadStatus
277 DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) { 280 DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) {
278 TabDownloadState* state = GetDownloadState(web_contents, NULL, false); 281 TabDownloadState* state = GetDownloadState(web_contents, NULL, false);
279 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD; 282 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD;
280 } 283 }
281 284
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* 285 DownloadRequestLimiter::TabDownloadState*
299 DownloadRequestLimiter::GetDownloadState( 286 DownloadRequestLimiter::GetDownloadState(
300 content::WebContents* web_contents, 287 content::WebContents* web_contents,
301 content::WebContents* originating_web_contents, 288 content::WebContents* originating_web_contents,
302 bool create) { 289 bool create) {
303 DCHECK(web_contents); 290 DCHECK(web_contents);
304 StateMap::iterator i = state_map_.find(web_contents); 291 StateMap::iterator i = state_map_.find(web_contents);
305 if (i != state_map_.end()) 292 if (i != state_map_.end())
306 return i->second; 293 return i->second;
307 294
(...skipping 10 matching lines...) Expand all
318 int render_view_id, 305 int render_view_id,
319 const GURL& url, 306 const GURL& url,
320 const std::string& request_method, 307 const std::string& request_method,
321 const Callback& callback) { 308 const Callback& callback) {
322 DCHECK_CURRENTLY_ON(BrowserThread::UI); 309 DCHECK_CURRENTLY_ON(BrowserThread::UI);
323 310
324 content::WebContents* originating_contents = 311 content::WebContents* originating_contents =
325 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); 312 tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
326 if (!originating_contents) { 313 if (!originating_contents) {
327 // The WebContents was closed, don't allow the download. 314 // The WebContents was closed, don't allow the download.
328 ScheduleNotification(callback, false); 315 callback.Run(false);
329 return; 316 return;
330 } 317 }
331 318
332 if (!originating_contents->GetDelegate()) { 319 if (!originating_contents->GetDelegate()) {
333 ScheduleNotification(callback, false); 320 callback.Run(false);
334 return; 321 return;
335 } 322 }
336 323
337 // Note that because |originating_contents| might go away before 324 // Note that because |originating_contents| might go away before
338 // OnCanDownloadDecided is invoked, we look it up by |render_process_host_id| 325 // OnCanDownloadDecided is invoked, we look it up by |render_process_host_id|
339 // and |render_view_id|. 326 // and |render_view_id|.
340 base::Callback<void(bool)> can_download_callback = base::Bind( 327 base::Callback<void(bool)> can_download_callback = base::Bind(
341 &DownloadRequestLimiter::OnCanDownloadDecided, 328 &DownloadRequestLimiter::OnCanDownloadDecided,
342 factory_.GetWeakPtr(), 329 factory_.GetWeakPtr(),
343 render_process_host_id, 330 render_process_host_id,
344 render_view_id, 331 render_view_id,
345 request_method, 332 request_method,
346 callback); 333 callback);
347 334
348 originating_contents->GetDelegate()->CanDownload( 335 originating_contents->GetDelegate()->CanDownload(
349 url, 336 url,
350 request_method, 337 request_method,
351 can_download_callback); 338 can_download_callback);
352 } 339 }
353 340
354 void DownloadRequestLimiter::OnCanDownloadDecided( 341 void DownloadRequestLimiter::OnCanDownloadDecided(
355 int render_process_host_id, 342 int render_process_host_id,
356 int render_view_id, 343 int render_view_id,
357 const std::string& request_method, 344 const std::string& request_method,
358 const Callback& orig_callback, bool allow) { 345 const Callback& orig_callback, bool allow) {
359 DCHECK_CURRENTLY_ON(BrowserThread::UI); 346 DCHECK_CURRENTLY_ON(BrowserThread::UI);
360 content::WebContents* originating_contents = 347 content::WebContents* originating_contents =
361 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); 348 tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
362 if (!originating_contents || !allow) { 349 if (!originating_contents || !allow) {
363 ScheduleNotification(orig_callback, false); 350 orig_callback.Run(false);
364 return; 351 return;
365 } 352 }
366 353
367 CanDownloadImpl(originating_contents, 354 CanDownloadImpl(originating_contents,
368 request_method, 355 request_method,
369 orig_callback); 356 orig_callback);
370 } 357 }
371 358
372 HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings( 359 HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings(
373 content::WebContents* contents) { 360 content::WebContents* contents) {
374 return content_settings_ ? content_settings_ : Profile::FromBrowserContext( 361 return content_settings_ ? content_settings_ : Profile::FromBrowserContext(
375 contents->GetBrowserContext())->GetHostContentSettingsMap(); 362 contents->GetBrowserContext())->GetHostContentSettingsMap();
376 } 363 }
377 364
378 void DownloadRequestLimiter::CanDownloadImpl( 365 void DownloadRequestLimiter::CanDownloadImpl(
379 content::WebContents* originating_contents, 366 content::WebContents* originating_contents,
380 const std::string& request_method, 367 const std::string& request_method,
381 const Callback& callback) { 368 const Callback& callback) {
382 DCHECK(originating_contents); 369 DCHECK(originating_contents);
383 370
384 TabDownloadState* state = GetDownloadState( 371 TabDownloadState* state = GetDownloadState(
385 originating_contents, originating_contents, true); 372 originating_contents, originating_contents, true);
386 switch (state->download_status()) { 373 switch (state->download_status()) {
387 case ALLOW_ALL_DOWNLOADS: 374 case ALLOW_ALL_DOWNLOADS:
388 if (state->download_count() && !(state->download_count() % 375 if (state->download_count() && !(state->download_count() %
389 DownloadRequestLimiter::kMaxDownloadsAtOnce)) 376 DownloadRequestLimiter::kMaxDownloadsAtOnce))
390 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); 377 state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
391 ScheduleNotification(callback, true); 378 callback.Run(true);
392 state->increment_download_count(); 379 state->increment_download_count();
393 break; 380 break;
394 381
395 case ALLOW_ONE_DOWNLOAD: 382 case ALLOW_ONE_DOWNLOAD:
396 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); 383 state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
397 ScheduleNotification(callback, true); 384 callback.Run(true);
398 state->increment_download_count(); 385 state->increment_download_count();
399 break; 386 break;
400 387
401 case DOWNLOADS_NOT_ALLOWED: 388 case DOWNLOADS_NOT_ALLOWED:
402 ScheduleNotification(callback, false); 389 callback.Run(false);
403 break; 390 break;
404 391
405 case PROMPT_BEFORE_DOWNLOAD: { 392 case PROMPT_BEFORE_DOWNLOAD: {
406 HostContentSettingsMap* content_settings = GetContentSettings( 393 HostContentSettingsMap* content_settings = GetContentSettings(
407 originating_contents); 394 originating_contents);
408 ContentSetting setting = CONTENT_SETTING_ASK; 395 ContentSetting setting = CONTENT_SETTING_ASK;
409 if (content_settings) 396 if (content_settings)
410 setting = content_settings->GetContentSetting( 397 setting = content_settings->GetContentSetting(
411 originating_contents->GetURL(), 398 originating_contents->GetURL(),
412 originating_contents->GetURL(), 399 originating_contents->GetURL(),
413 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, 400 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
414 std::string()); 401 std::string());
415 switch (setting) { 402 switch (setting) {
416 case CONTENT_SETTING_ALLOW: { 403 case CONTENT_SETTING_ALLOW: {
417 TabSpecificContentSettings* settings = 404 TabSpecificContentSettings* settings =
418 TabSpecificContentSettings::FromWebContents( 405 TabSpecificContentSettings::FromWebContents(
419 originating_contents); 406 originating_contents);
420 if (settings) 407 if (settings)
421 settings->SetDownloadsBlocked(false); 408 settings->SetDownloadsBlocked(false);
422 ScheduleNotification(callback, true); 409 callback.Run(true);
423 state->increment_download_count(); 410 state->increment_download_count();
424 return; 411 return;
425 } 412 }
426 case CONTENT_SETTING_BLOCK: { 413 case CONTENT_SETTING_BLOCK: {
427 TabSpecificContentSettings* settings = 414 TabSpecificContentSettings* settings =
428 TabSpecificContentSettings::FromWebContents( 415 TabSpecificContentSettings::FromWebContents(
429 originating_contents); 416 originating_contents);
430 if (settings) 417 if (settings)
431 settings->SetDownloadsBlocked(true); 418 settings->SetDownloadsBlocked(true);
432 ScheduleNotification(callback, false); 419 callback.Run(false);
433 return; 420 return;
434 } 421 }
435 case CONTENT_SETTING_DEFAULT: 422 case CONTENT_SETTING_DEFAULT:
436 case CONTENT_SETTING_ASK: 423 case CONTENT_SETTING_ASK:
437 case CONTENT_SETTING_SESSION_ONLY: 424 case CONTENT_SETTING_SESSION_ONLY:
438 state->PromptUserForDownload(callback); 425 state->PromptUserForDownload(callback);
439 state->increment_download_count(); 426 state->increment_download_count();
440 break; 427 break;
441 case CONTENT_SETTING_NUM_SETTINGS: 428 case CONTENT_SETTING_NUM_SETTINGS:
442 default: 429 default:
443 NOTREACHED(); 430 NOTREACHED();
444 return; 431 return;
445 } 432 }
446 break; 433 break;
447 } 434 }
448 435
449 default: 436 default:
450 NOTREACHED(); 437 NOTREACHED();
451 } 438 }
452 } 439 }
453 440
454 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback,
455 bool allow) {
456 BrowserThread::PostTask(
457 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow));
458 }
459
460 void DownloadRequestLimiter::Remove(TabDownloadState* state, 441 void DownloadRequestLimiter::Remove(TabDownloadState* state,
461 content::WebContents* contents) { 442 content::WebContents* contents) {
462 DCHECK(ContainsKey(state_map_, contents)); 443 DCHECK(ContainsKey(state_map_, contents));
463 state_map_.erase(contents); 444 state_map_.erase(contents);
464 delete state; 445 delete state;
465 } 446 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_request_limiter.h ('k') | chrome/browser/download/download_resource_throttle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698