| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |