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

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

Issue 62131: Ask for user confirmation when closing a browser with in-progress downloads (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 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
« no previous file with comments | « chrome/browser/browser.h ('k') | chrome/browser/browser_window.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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/browser.h" 5 #include "chrome/browser/browser.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/idle_timer.h" 8 #include "base/idle_timer.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "base/thread.h" 11 #include "base/thread.h"
12 #include "chrome/app/chrome_dll_resource.h" 12 #include "chrome/app/chrome_dll_resource.h"
13 #include "chrome/browser/bookmarks/bookmark_model.h" 13 #include "chrome/browser/bookmarks/bookmark_model.h"
14 #include "chrome/browser/browser_list.h" 14 #include "chrome/browser/browser_list.h"
15 #include "chrome/browser/browser_shutdown.h" 15 #include "chrome/browser/browser_shutdown.h"
16 #include "chrome/browser/browser_window.h" 16 #include "chrome/browser/browser_window.h"
17 #include "chrome/browser/character_encoding.h" 17 #include "chrome/browser/character_encoding.h"
18 #include "chrome/browser/debugger/devtools_manager.h" 18 #include "chrome/browser/debugger/devtools_manager.h"
19 #include "chrome/browser/download/download_manager.h"
19 #include "chrome/browser/find_bar.h" 20 #include "chrome/browser/find_bar.h"
20 #include "chrome/browser/find_bar_controller.h" 21 #include "chrome/browser/find_bar_controller.h"
21 #include "chrome/browser/location_bar.h" 22 #include "chrome/browser/location_bar.h"
22 #include "chrome/browser/metrics/user_metrics.h" 23 #include "chrome/browser/metrics/user_metrics.h"
23 #include "chrome/browser/net/url_fixer_upper.h" 24 #include "chrome/browser/net/url_fixer_upper.h"
24 #include "chrome/browser/profile.h" 25 #include "chrome/browser/profile.h"
25 #include "chrome/browser/sessions/session_service.h" 26 #include "chrome/browser/sessions/session_service.h"
26 #include "chrome/browser/sessions/session_types.h" 27 #include "chrome/browser/sessions/session_types.h"
27 #include "chrome/browser/sessions/tab_restore_service.h" 28 #include "chrome/browser/sessions/tab_restore_service.h"
28 #include "chrome/browser/status_bubble.h" 29 #include "chrome/browser/status_bubble.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 170
170 Browser::Browser(Type type, Profile* profile) 171 Browser::Browser(Type type, Profile* profile)
171 : type_(type), 172 : type_(type),
172 profile_(profile), 173 profile_(profile),
173 window_(NULL), 174 window_(NULL),
174 tabstrip_model_(this, profile), 175 tabstrip_model_(this, profile),
175 command_updater_(this), 176 command_updater_(this),
176 toolbar_model_(this), 177 toolbar_model_(this),
177 chrome_updater_factory_(this), 178 chrome_updater_factory_(this),
178 is_attempting_to_close_browser_(false), 179 is_attempting_to_close_browser_(false),
180 cancel_download_confirmation_state_(NOT_PROMPTED),
179 maximized_state_(MAXIMIZED_STATE_DEFAULT), 181 maximized_state_(MAXIMIZED_STATE_DEFAULT),
180 method_factory_(this), 182 method_factory_(this),
181 idle_task_(new BrowserIdleTimer) { 183 idle_task_(new BrowserIdleTimer) {
182 tabstrip_model_.AddObserver(this); 184 tabstrip_model_.AddObserver(this);
183 185
184 NotificationService::current()->AddObserver( 186 NotificationService::current()->AddObserver(
185 this, 187 this,
186 NotificationType::SSL_VISIBLE_STATE_CHANGED, 188 NotificationType::SSL_VISIBLE_STATE_CHANGED,
187 NotificationService::AllSources()); 189 NotificationService::AllSources());
188 190
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 title->replace(match_index, 1, L""); 427 title->replace(match_index, 1, L"");
426 current_index = match_index; 428 current_index = match_index;
427 } 429 }
428 } 430 }
429 431
430 432
431 /////////////////////////////////////////////////////////////////////////////// 433 ///////////////////////////////////////////////////////////////////////////////
432 // Browser, OnBeforeUnload handling: 434 // Browser, OnBeforeUnload handling:
433 435
434 bool Browser::ShouldCloseWindow() { 436 bool Browser::ShouldCloseWindow() {
435 if (HasCompletedUnloadProcessing()) { 437 if (!CanCloseWithInProgressDownloads())
438 return false;
439
440 if (HasCompletedUnloadProcessing())
436 return true; 441 return true;
437 } 442
438 is_attempting_to_close_browser_ = true; 443 is_attempting_to_close_browser_ = true;
439 444
440 for (int i = 0; i < tab_count(); ++i) { 445 for (int i = 0; i < tab_count(); ++i) {
441 TabContents* contents = GetTabContentsAt(i); 446 TabContents* contents = GetTabContentsAt(i);
442 if (TabHasUnloadListener(contents)) 447 if (TabHasUnloadListener(contents))
443 tabs_needing_before_unload_fired_.insert(contents); 448 tabs_needing_before_unload_fired_.insert(contents);
444 } 449 }
445 450
446 if (tabs_needing_before_unload_fired_.empty()) 451 if (tabs_needing_before_unload_fired_.empty())
447 return true; 452 return true;
(...skipping 19 matching lines...) Expand all
467 if (session_service) 472 if (session_service)
468 session_service->WindowClosing(session_id()); 473 session_service->WindowClosing(session_id());
469 474
470 TabRestoreService* tab_restore_service = profile()->GetTabRestoreService(); 475 TabRestoreService* tab_restore_service = profile()->GetTabRestoreService();
471 if (tab_restore_service) 476 if (tab_restore_service)
472 tab_restore_service->BrowserClosing(this); 477 tab_restore_service->BrowserClosing(this);
473 478
474 CloseAllTabs(); 479 CloseAllTabs();
475 } 480 }
476 481
477 /////////////////////////////////////////////////////////////////////////////// 482 ////////////////////////////////////////////////////////////////////////////////
483 // In-progress download termination handling:
484
485 void Browser::InProgressDownloadResponse(bool cancel_downloads) {
486 if (cancel_downloads) {
487 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
488 CloseWindow();
489 return;
490 }
491
492 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
493 // close again we'll show the warning again.
494 cancel_download_confirmation_state_ = NOT_PROMPTED;
495
496 // Show the download page so the user can figure-out what downloads are still
497 // in-progress.
498 ShowDownloadsTab();
499 }
500
501
502 ////////////////////////////////////////////////////////////////////////////////
478 // Browser, Tab adding/showing functions: 503 // Browser, Tab adding/showing functions:
479 504
480 TabContents* Browser::AddTabWithURL( 505 TabContents* Browser::AddTabWithURL(
481 const GURL& url, const GURL& referrer, PageTransition::Type transition, 506 const GURL& url, const GURL& referrer, PageTransition::Type transition,
482 bool foreground, SiteInstance* instance) { 507 bool foreground, SiteInstance* instance) {
483 if ((type_ & TYPE_APP) != 0 && tabstrip_model_.count() == 1) { 508 if ((type_ & TYPE_APP) != 0 && tabstrip_model_.count() == 1) {
484 NOTREACHED() << "Cannot add a tab in a mono tab application."; 509 NOTREACHED() << "Cannot add a tab in a mono tab application.";
485 return NULL; 510 return NULL;
486 } 511 }
487 512
(...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 2481
2457 void Browser::ClearUnloadState(TabContents* tab) { 2482 void Browser::ClearUnloadState(TabContents* tab) {
2458 DCHECK(is_attempting_to_close_browser_); 2483 DCHECK(is_attempting_to_close_browser_);
2459 RemoveFromSet(&tabs_needing_before_unload_fired_, tab); 2484 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
2460 RemoveFromSet(&tabs_needing_unload_fired_, tab); 2485 RemoveFromSet(&tabs_needing_unload_fired_, tab);
2461 ProcessPendingTabs(); 2486 ProcessPendingTabs();
2462 } 2487 }
2463 2488
2464 2489
2465 /////////////////////////////////////////////////////////////////////////////// 2490 ///////////////////////////////////////////////////////////////////////////////
2491 // Browser, In-progress download termination handling (private):
2492
2493 bool Browser::CanCloseWithInProgressDownloads() {
2494 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
2495 // This should probably not happen.
2496 DCHECK(cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE);
2497 return true;
2498 }
2499
2500 // If there are no download in-progress, our job is done.
2501 DownloadManager* download_manager = profile_->GetDownloadManager();
2502 if (!download_manager || download_manager->in_progress_count() == 0)
2503 return true;
2504
2505 // Let's figure out if we are the last window for our profile.
2506 // Note that we cannot just use BrowserList::GetBrowserCount as browser
2507 // windows closing is delayed and the returned count might include windows
2508 // that are being closed.
2509 int count = 0;
2510 for (BrowserList::const_iterator iter = BrowserList::begin();
2511 iter != BrowserList::end(); ++iter) {
2512 // Don't count this browser window or any other in the process of closing.
2513 if (*iter == this || (*iter)->is_attempting_to_close_browser_)
2514 continue;
2515
2516 // We test the original profile, because an incognito browser window keeps
2517 // the original profile alive (and its DownloadManager).
2518 // We also need to test explicitly the profile directly so that 2 incognito
2519 // profiles count as a match.
2520 if ((*iter)->profile() == profile() ||
2521 (*iter)->profile()->GetOriginalProfile() == profile())
2522 count++;
2523 }
2524 if (count > 0)
2525 return true;
2526
2527 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
2528 window_->ConfirmBrowserCloseWithPendingDownloads();
2529
2530 // Return false so the browser does not close. We'll close if the user
2531 // confirms in the dialog.
2532 return false;
2533 }
2534
2535 ///////////////////////////////////////////////////////////////////////////////
2466 // Browser, Assorted utility functions (private): 2536 // Browser, Assorted utility functions (private):
2467 2537
2468 Browser* Browser::GetOrCreateTabbedBrowser() { 2538 Browser* Browser::GetOrCreateTabbedBrowser() {
2469 Browser* browser = BrowserList::FindBrowserWithType( 2539 Browser* browser = BrowserList::FindBrowserWithType(
2470 profile_, TYPE_NORMAL); 2540 profile_, TYPE_NORMAL);
2471 if (!browser) 2541 if (!browser)
2472 browser = Browser::Create(profile_); 2542 browser = Browser::Create(profile_);
2473 return browser; 2543 return browser;
2474 } 2544 }
2475 2545
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2538 2608
2539 // We need to register the window position pref. 2609 // We need to register the window position pref.
2540 std::wstring window_pref(prefs::kBrowserWindowPlacement); 2610 std::wstring window_pref(prefs::kBrowserWindowPlacement);
2541 window_pref.append(L"_"); 2611 window_pref.append(L"_");
2542 window_pref.append(app_name); 2612 window_pref.append(app_name);
2543 PrefService* prefs = g_browser_process->local_state(); 2613 PrefService* prefs = g_browser_process->local_state();
2544 DCHECK(prefs); 2614 DCHECK(prefs);
2545 2615
2546 prefs->RegisterDictionaryPref(window_pref.c_str()); 2616 prefs->RegisterDictionaryPref(window_pref.c_str());
2547 } 2617 }
OLDNEW
« no previous file with comments | « chrome/browser/browser.h ('k') | chrome/browser/browser_window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698