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

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

Issue 8271003: Shutdown (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 2 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/ui/browser_list.h ('k') | no next file » | 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/ui/browser_list.h" 5 #include "chrome/browser/ui/browser_list.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 22 matching lines...) Expand all
33 #include "chrome/browser/chromeos/cros/cros_library.h" 33 #include "chrome/browser/chromeos/cros/cros_library.h"
34 #include "chrome/browser/chromeos/cros/login_library.h" 34 #include "chrome/browser/chromeos/cros/login_library.h"
35 #include "chrome/browser/chromeos/cros/update_library.h" 35 #include "chrome/browser/chromeos/cros/update_library.h"
36 #if defined(TOOLKIT_USES_GTK) 36 #if defined(TOOLKIT_USES_GTK)
37 #include "chrome/browser/chromeos/wm_ipc.h" 37 #include "chrome/browser/chromeos/wm_ipc.h"
38 #endif 38 #endif
39 #endif 39 #endif
40 40
41 namespace { 41 namespace {
42 42
43 // ********************* IMPORTANT ****************
44 // Please read and update if you need to change the quit/shutdown
45 // process.
46 //
47 // This is an attempt to descritbe different kinds of quit/shutdown
48 // process that chrome may process. This overs only Windows and Linux
49 // because I (oshima) don't know about mac. Mac contribution to this
50 // comment would be greatly appreciated.
51 //
52 // Common behavior.
53 // APP_EXITING notification is always sent when chrome starts shutdown
54 // process (with one exception. see ChromeOS guest mode below).
55 // Note that shutdown process can be canceled, so APP_EXITING may
56 // be sent MORE THAN ONCE.
57 //
58 // Normal shutdown on Linux & Windows
59 // A user requested to quit the browser (win: by wrench menu or
60 // ctrl-alt-q, or linux:wrench menu, ctrl-alt-q or SIGTERM).
61 // It notifies APP_EXITING, then tries to close all browsers.
62 // When the last browser gets deleted, it sends out APP_TERMINATING
63 // notification as a signal that browser is really quitting.
64 // Shutdown may be blocked and canceled by beforeunload handler or
65 // downloads in progress. (in which case, APP_TERMINATING won't be sent)
66 //
67 // Restart on Linux & Windows
68 // A user requested to restart the browser. This can happen when
69 // certain preference has changed (flags page, language option), or
70 // update is availabe. Chrome sets kRestartLastSessionOnShutdown
71 // preference to true, follows normal shutdown process and re-launches
72 // itself at the end of the process (see browser_shutdown::Shutdown()).
73 //
74 // Logoff/power off on Windows
75 // This happens when chrome recieves WM_ENDSESSION message. It
76 // notifies APP_EXITING, then close all tabs forcibly. This
77 // process does send APP_TERMINATING notification. This shutdown
78 // process cannot be blocked nor canceled.
79 //
80 // X IO Error on Linux and ChromeOS:
81 // When X server reports IO error, it's most likely X has gone away and
82 // chrome needs has to shutdown without make another call to X.
83 // This is similar to Window's logoff/power off process, except that
84 // chrome doesn't try to close browsers nor tabs. APP_TERMINATING is sent
85 // after APP_EXITING.
86 //
87 // ChromeOS specific:
88 // Fast shutdown
89 // When a user requested to quit browser either by wrench menu or
90 // ctrl-alt-q, and we know that shutdown will not be canceled (that is,
91 // all contents have no beforeunload handlers and there is no
92 // downloads in progress), chrome quits using fast shutdown process.
93 // It notifies APP_EXITING, followed by APP_TERMINATING, then
94 // tells SessionManager to start shutdown process. SessionManager sends
95 // SIGTERM back to chrome, which closes all browsers.
96 //
97 // Slow shutdown
98 // If there is a tab with beforeunload handlers, or a download is
99 // in progress, it will follow normal shutdown process. That is,
100 // it notifies APP_EXITING, tries to closes all browsers. APP_TERMINATING
101 // will be sent when the last browser is closd. Shutdown may be cancelled
102 // either by beforeunload handler or download dialog.
103 //
104 // Restart
105 // ChromeOS does not support restarting. It follows regular shutdown process ,
106 //
107 // Power off
108 // A user pressed power button, or closed a lid on login screen. This is
109 // similar to Windows log-off/power-off scenario. Chrome receives SIGTERM
110 // and start shutdown process. It will close all tabs forcibly and shutdown
111 // cannot be canceled.
112 //
113 // Signout from Screen locker.
114 // A user clicked signout button on screen locker. This is basically same
115 // as Power off. Chrome asks session manager to stop session and session
116 // manager sends SIGTERM to chrome.
117 //
118 // Switching to Guest mode
119 // When a user selected guest mode, Chrome first writes exit_cleanly bit
120 // off to the disk (see g_browser_process->EndSession() in
121 // chromeos/login_utils.cc), then tells SessionManager to switch to guest
122 // mode. Session manager kills and restarts Chrome with guest mode flag.
123 // This process never use method in BrowserList, nor sends APP_EXITING
124 // or APP_TERMINATING (to restart fast).
125 //
126 // Note that different shutdown path
127 //
128 // Mac:
129 // T.B.D.
130 //
131
43 // This object is instantiated when the first Browser object is added to the 132 // This object is instantiated when the first Browser object is added to the
44 // list and delete when the last one is removed. It watches for loads and 133 // list and delete when the last one is removed. It watches for loads and
45 // creates histograms of some global object counts. 134 // creates histograms of some global object counts.
46 class BrowserActivityObserver : public NotificationObserver { 135 class BrowserActivityObserver : public NotificationObserver {
47 public: 136 public:
48 BrowserActivityObserver() { 137 BrowserActivityObserver() {
49 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 138 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
50 NotificationService::AllSources()); 139 NotificationService::AllSources());
51 } 140 }
52 ~BrowserActivityObserver() {} 141 ~BrowserActivityObserver() {}
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 (*i)->CheckDownloadsInProgress(&normal_downloads_are_present, 283 (*i)->CheckDownloadsInProgress(&normal_downloads_are_present,
195 &incognito_downloads_are_present); 284 &incognito_downloads_are_present);
196 if (normal_downloads_are_present || 285 if (normal_downloads_are_present ||
197 incognito_downloads_are_present || 286 incognito_downloads_are_present ||
198 (*i)->TabsNeedBeforeUnloadFired()) 287 (*i)->TabsNeedBeforeUnloadFired())
199 return false; 288 return false;
200 } 289 }
201 return true; 290 return true;
202 } 291 }
203 292
293 // Sends out NOTIFICATION_APP_TERMINATING notification.
294 // Returns true if the notification is set, or false if the notification
295 // has already sent out before.
296 bool NotifyAppTerminating() {
297 static bool notified = false;
298 if (notified)
299 return false;
300 notified = true;
301 NotificationService::current()->Notify(
302 content::NOTIFICATION_APP_TERMINATING,
303 NotificationService::AllSources(),
304 NotificationService::NoDetails());
305 return true;
306 }
307
204 #if defined(OS_CHROMEOS) 308 #if defined(OS_CHROMEOS)
205 309
206 bool signout = false; 310 bool explicit_signout = false;
207 311
208 // Fast shutdown for ChromeOS. It tells session manager to start 312 // Fast shutdown for ChromeOS. It tells session manager to start
209 // shutdown process when closing browser windows won't be canceled. 313 // shutdown process when closing browser windows won't be canceled.
210 // Returns true if fast shutdown is successfully started. 314 // Returns true if fast shutdown is successfully started.
211 bool FastShutdown() { 315 bool FastShutdown() {
212 signout = true;
213 if (chromeos::CrosLibrary::Get()->EnsureLoaded() 316 if (chromeos::CrosLibrary::Get()->EnsureLoaded()
214 && AreAllBrowsersCloseable()) { 317 && AreAllBrowsersCloseable()) {
215 BrowserList::NotifyAndTerminate(true); 318 BrowserList::NotifyAndTerminate(true);
216 return true; 319 return true;
217 } 320 }
218 return false; 321 return false;
219 } 322 }
220 323
221 void NotifyWindowManagerAboutSignout() { 324 void NotifyWindowManagerAboutSignout() {
222 #if defined(TOOLKIT_USES_GTK) 325 #if defined(TOOLKIT_USES_GTK)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 // On the Mac, the application continues to run once all windows are closed. 383 // On the Mac, the application continues to run once all windows are closed.
281 // Terminate will result in a CloseAllBrowsers() call, and once (and if) 384 // Terminate will result in a CloseAllBrowsers() call, and once (and if)
282 // that is done, will cause the application to exit cleanly. 385 // that is done, will cause the application to exit cleanly.
283 chrome_browser_application_mac::Terminate(); 386 chrome_browser_application_mac::Terminate();
284 #endif 387 #endif
285 } 388 }
286 389
287 // static 390 // static
288 void BrowserList::NotifyAndTerminate(bool fast_path) { 391 void BrowserList::NotifyAndTerminate(bool fast_path) {
289 #if defined(OS_CHROMEOS) 392 #if defined(OS_CHROMEOS)
290 if (!signout) 393 if (browser_shutdown::ShutdownType() != browser_shutdown::BROWSER_EXIT);
291 return; 394 return;
292 #endif 395 #endif
293 396
294 if (fast_path) { 397 if (fast_path) {
295 NotificationService::current()->Notify( 398 NotifyAppTerminating();
296 content::NOTIFICATION_APP_TERMINATING,
297 NotificationService::AllSources(),
298 NotificationService::NoDetails());
299 } 399 }
300 400
301 #if defined(OS_CHROMEOS) 401 #if defined(OS_CHROMEOS)
302 NotifyWindowManagerAboutSignout(); 402 NotifyWindowManagerAboutSignout();
303 chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); 403 chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get();
304 if (cros_library->EnsureLoaded()) { 404 if (cros_library->EnsureLoaded()) {
305 // If update has been installed, reboot, otherwise, sign out. 405 // If update has been installed, reboot, otherwise, sign out.
306 if (cros_library->GetUpdateLibrary()->status().status == 406 if (cros_library->GetUpdateLibrary()->status().status ==
307 chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT) { 407 chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
308 cros_library->GetUpdateLibrary()->RebootAfterUpdate(); 408 cros_library->GetUpdateLibrary()->RebootAfterUpdate();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 // If we're exiting, send out the APP_TERMINATING notification to allow other 450 // If we're exiting, send out the APP_TERMINATING notification to allow other
351 // modules to shut themselves down. 451 // modules to shut themselves down.
352 if (browsers_.empty() && 452 if (browsers_.empty() &&
353 (browser_shutdown::IsTryingToQuit() || 453 (browser_shutdown::IsTryingToQuit() ||
354 g_browser_process->IsShuttingDown())) { 454 g_browser_process->IsShuttingDown())) {
355 // Last browser has just closed, and this is a user-initiated quit or there 455 // Last browser has just closed, and this is a user-initiated quit or there
356 // is no module keeping the app alive, so send out our notification. No need 456 // is no module keeping the app alive, so send out our notification. No need
357 // to call ProfileManager::ShutdownSessionServices() as part of the 457 // to call ProfileManager::ShutdownSessionServices() as part of the
358 // shutdown, because Browser::WindowClosing() already makes sure that the 458 // shutdown, because Browser::WindowClosing() already makes sure that the
359 // SessionService is created and notified. 459 // SessionService is created and notified.
360 NotificationService::current()->Notify( 460 // On ChromeOS, APP_TERMINATING might have already been sent when
361 content::NOTIFICATION_APP_TERMINATING, 461 // shutdown is first requested. The call will be ignored in that case.
362 NotificationService::AllSources(), 462 NotifyAppTerminating();
363 NotificationService::NoDetails());
364 AllBrowsersClosedAndAppExiting(); 463 AllBrowsersClosedAndAppExiting();
365 } 464 }
366 } 465 }
367 466
368 // static 467 // static
369 void BrowserList::AddObserver(BrowserList::Observer* observer) { 468 void BrowserList::AddObserver(BrowserList::Observer* observer) {
370 observers_.AddObserver(observer); 469 observers_.AddObserver(observer);
371 } 470 }
372 471
373 // static 472 // static
374 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { 473 void BrowserList::RemoveObserver(BrowserList::Observer* observer) {
375 observers_.RemoveObserver(observer); 474 observers_.RemoveObserver(observer);
376 } 475 }
377 476
378 // static 477 // static
379 void BrowserList::CloseAllBrowsers() { 478 void BrowserList::CloseAllBrowsers() {
479 browser_shutdown::ShutdownType shutdown_type =
480 browser_shutdown::GetShutdownType()
481 /*
380 bool session_ending = 482 bool session_ending =
381 browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION; 483 browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION;
382 bool force_exit = false; 484 bool force_exit = false;
383 #if defined(USE_X11) 485 #if defined(USE_X11)
384 if (session_ending) 486 if (session_ending)
385 force_exit = true; 487 force_exit = true;
386 #endif 488 #endif
489 */
387 // Tell everyone that we are shutting down. 490 // Tell everyone that we are shutting down.
388 browser_shutdown::SetTryingToQuit(true); 491 browser_shutdown::SetTryingToQuit(true);
389 492
390 // Before we close the browsers shutdown all session services. That way an 493 // Before we close the browsers shutdown all session services. That way an
391 // exit can restore all browsers open before exiting. 494 // exit can restore all browsers open before exiting.
392 ProfileManager::ShutdownSessionServices(); 495 ProfileManager::ShutdownSessionServices();
393 496
497 // If we're not closing browser, send APP_TERMINATING
498 if (shutdown_type == browser_shutdown::SHUTDOWN_WITHOUT_CLOSE) {
499 NotifyAppTerminating();
500 return;
501 }
502
394 // If there are no browsers, send the APP_TERMINATING action here. Otherwise, 503 // If there are no browsers, send the APP_TERMINATING action here. Otherwise,
395 // it will be sent by RemoveBrowser() when the last browser has closed. 504 // it will be sent by RemoveBrowser() when the last browser has closed.
396 if (force_exit || browsers_.empty()) { 505 if (force_exit || browsers_.empty()) {
397 NotifyAndTerminate(true); 506 NotifyAndTerminate(true);
398 return; 507 return;
399 } 508 }
509
400 #if defined(OS_CHROMEOS) 510 #if defined(OS_CHROMEOS)
401 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker( 511 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker(
402 "StartedClosingWindows", false); 512 "StartedClosingWindows", false);
403 #endif 513 #endif
514
404 for (BrowserList::const_iterator i = BrowserList::begin(); 515 for (BrowserList::const_iterator i = BrowserList::begin();
405 i != BrowserList::end();) { 516 i != BrowserList::end();) {
406 Browser* browser = *i; 517 Browser* browser = *i;
achuithb 2011/10/28 22:22:26 Do you think you could also clean this loop up if
407 browser->window()->Close(); 518 browser->window()->Close();
408 if (!session_ending) { 519 if (shutdown_type != browser_shutdown::POWER_OFF) {
409 ++i; 520 ++i;
410 } else { 521 } else {
411 // This path is hit during logoff/power-down. In this case we won't get 522 // This path is hit during logoff/power-down. In this case we won't get
412 // a final message and so we force the browser to be deleted. 523 // a final message and so we force the browser to be deleted.
413 // Close doesn't immediately destroy the browser 524 // Close doesn't immediately destroy the browser
414 // (Browser::TabStripEmpty() uses invoke later) but when we're ending the 525 // (Browser::TabStripEmpty() uses invoke later) but when we're ending the
415 // session we need to make sure the browser is destroyed now. So, invoke 526 // session we need to make sure the browser is destroyed now. So, invoke
416 // DestroyBrowser to make sure the browser is deleted and cleanup can 527 // DestroyBrowser to make sure the browser is deleted and cleanup can
417 // happen. 528 // happen.
418 while (browser->tab_count()) 529 while (browser->tab_count())
(...skipping 21 matching lines...) Expand all
440 } 551 }
441 552
442 for (BrowserVector::const_iterator i = browsers_to_close.begin(); 553 for (BrowserVector::const_iterator i = browsers_to_close.begin();
443 i != browsers_to_close.end(); ++i) { 554 i != browsers_to_close.end(); ++i) {
444 (*i)->window()->Close(); 555 (*i)->window()->Close();
445 } 556 }
446 } 557 }
447 558
448 // static 559 // static
449 void BrowserList::AttemptUserExit() { 560 void BrowserList::AttemptUserExit() {
561 browser_shutdown::OnShutdownStarting(browser_shutdown::BROWSER_EXIT);
450 #if defined(OS_CHROMEOS) 562 #if defined(OS_CHROMEOS)
451 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false); 563 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false);
452 // Write /tmp/uptime-logout-started as well. 564 // Write /tmp/uptime-logout-started as well.
453 const char kLogoutStarted[] = "logout-started"; 565 const char kLogoutStarted[] = "logout-started";
454 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted); 566 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted);
455 567
456 // Login screen should show up in owner's locale. 568 // Login screen should show up in owner's locale.
457 PrefService* state = g_browser_process->local_state(); 569 PrefService* state = g_browser_process->local_state();
458 if (state) { 570 if (state) {
459 std::string owner_locale = state->GetString(prefs::kOwnerLocale); 571 std::string owner_locale = state->GetString(prefs::kOwnerLocale);
460 if (!owner_locale.empty() && 572 if (!owner_locale.empty() &&
461 state->GetString(prefs::kApplicationLocale) != owner_locale && 573 state->GetString(prefs::kApplicationLocale) != owner_locale &&
462 !state->IsManagedPreference(prefs::kApplicationLocale)) { 574 !state->IsManagedPreference(prefs::kApplicationLocale)) {
463 state->SetString(prefs::kApplicationLocale, owner_locale); 575 state->SetString(prefs::kApplicationLocale, owner_locale);
464 state->SavePersistentPrefs(); 576 state->SavePersistentPrefs();
465 } 577 }
466 } 578 }
579
467 if (FastShutdown()) 580 if (FastShutdown())
468 return; 581 return;
469 #else 582 #else
470 // Reset the restart bit that might have been set in cancelled restart 583 // Reset the restart bit that might have been set in cancelled restart
471 // request. 584 // request.
472 PrefService* pref_service = g_browser_process->local_state(); 585 PrefService* pref_service = g_browser_process->local_state();
473 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, false); 586 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, false);
474 #endif 587 #endif
475 AttemptExitInternal(); 588 AttemptExitInternal();
476 } 589 }
477 590
478 // static 591 // static
479 void BrowserList::AttemptRestart() { 592 void BrowserList::AttemptRestart() {
480 #if defined(OS_CHROMEOS) 593 #if defined(OS_CHROMEOS)
481 // For CrOS instead of browser restart (which is not supported) perform a full 594 // For CrOS instead of browser restart (which is not supported) perform a full
482 // sign out. Session will be only restored if user has that setting set. 595 // sign out. Session will be only restored if user has that setting set.
483 // Same session restore behavior happens in case of full restart after update. 596 // Same session restore behavior happens in case of full restart after update.
597 // TODO(oshima): Should we use LoginLibrary::RestartJob()?
484 AttemptUserExit(); 598 AttemptUserExit();
485 #else 599 #else
486 // Set the flag to restore state after the restart. 600 // Set the flag to restore state after the restart.
487 PrefService* pref_service = g_browser_process->local_state(); 601 PrefService* pref_service = g_browser_process->local_state();
488 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); 602 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true);
489 AttemptExit(); 603 AttemptExit();
490 #endif 604 #endif
491 } 605 }
492 606
493 // static 607 // static
494 void BrowserList::AttemptExit() { 608 void BrowserList::AttemptExit() {
495 // If we know that all browsers can be closed without blocking, 609 // If we know that all browsers can be closed without blocking,
496 // don't notify users of crashes beyond this point. 610 // don't notify users of crashes beyond this point.
497 // Note that MarkAsCleanShutdown does not set UMA's exit cleanly bit 611 // Note that MarkAsCleanShutdown does not set UMA's exit cleanly bit
498 // so crashes during shutdown are still reported in UMA. 612 // so crashes during shutdown are still reported in UMA.
499 if (AreAllBrowsersCloseable()) 613 if (AreAllBrowsersCloseable())
500 MarkAsCleanShutdown(); 614 MarkAsCleanShutdown();
501 AttemptExitInternal(); 615 AttemptExitInternal();
502 } 616 }
503 617
504 #if defined(OS_CHROMEOS) 618 #if defined(OS_CHROMEOS)
505 // static 619 // static
506 void BrowserList::ExitCleanly() { 620 void BrowserList::ExitCleanly() {
507 // We always mark exit cleanly. 621 // We always mark exit cleanly.
508 g_browser_process->EndSession(); 622 g_browser_process->EndSession();
623 if (AreAllBrowsersCloseable())
624
509 AttemptExitInternal(); 625 AttemptExitInternal();
510 } 626 }
511 #endif 627 #endif
512 628
513 static void TimeLimitedSessionEnding() { 629 static void TimeLimitedForceShutdown(browser_shutdown::ShutdownType type) {
514 // Start watching for hang during shutdown, and crash it if takes too long. 630 // Start watching for hang during shutdown, and crash it if takes too long.
515 // We disarm when |shutdown_watcher| object is destroyed, which is when we 631 // We disarm when |shutdown_watcher| object is destroyed, which is when we
516 // exit this function. 632 // exit this function.
517 ShutdownWatcherHelper shutdown_watcher; 633 ShutdownWatcherHelper shutdown_watcher;
518 shutdown_watcher.Arm(base::TimeDelta::FromSeconds(90)); 634 shutdown_watcher.Arm(base::TimeDelta::FromSeconds(90));
519 635
520 // EndSession is invoked once per frame. Only do something the first time. 636 // EndSession is invoked once per frame. Only do something the first time.
521 static bool already_ended = false; 637 static bool already_ended = false;
522 // We may get called in the middle of shutdown, e.g. http://crbug.com/70852 638 // We may get called in the middle of shutdown, e.g. http://crbug.com/70852
523 // In this case, do nothing. 639 // In this case, do nothing.
524 if (already_ended || !NotificationService::current()) 640 if (already_ended || !NotificationService::current())
525 return; 641 return;
526 already_ended = true; 642 already_ended = true;
527 643
528 browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION); 644 browser_shutdown::OnShutdownStarting(type);
529 645
530 NotificationService::current()->Notify( 646 NotificationService::current()->Notify(
531 content::NOTIFICATION_APP_EXITING, 647 content::NOTIFICATION_APP_EXITING,
532 NotificationService::AllSources(), 648 NotificationService::AllSources(),
533 NotificationService::NoDetails()); 649 NotificationService::NoDetails());
534 650
535 // Write important data first. 651 // Write important data first.
536 g_browser_process->EndSession(); 652 g_browser_process->EndSession();
537 653
538 BrowserList::CloseAllBrowsers(); 654 BrowserList::CloseAllBrowsers();
539 655
540 // Send out notification. This is used during testing so that the test harness 656 // Send out notification. This is used during testing so that the test harness
541 // can properly shutdown before we exit. 657 // can properly shutdown before we exit.
542 NotificationService::current()->Notify( 658 NotificationService::current()->Notify(
543 chrome::NOTIFICATION_SESSION_END, 659 chrome::NOTIFICATION_SESSION_END,
544 NotificationService::AllSources(), 660 NotificationService::AllSources(),
545 NotificationService::NoDetails()); 661 NotificationService::NoDetails());
546 662
547 // And shutdown. 663 // And shutdown.
548 browser_shutdown::Shutdown(); 664 browser_shutdown::Shutdown();
549 } 665 }
550 666
551 // static 667 // static
552 void BrowserList::SessionEnding() { 668 void BrowserList::ForceShutdown(SessionEndingReason raeson) {
553 TimeLimitedSessionEnding(); 669 TimeLimitedForceShutdown(reason);
554 670
555 #if defined(OS_WIN) 671 #if defined(OS_WIN)
556 // At this point the message loop is still running yet we've shut everything 672 // At this point the message loop is still running yet we've shut everything
557 // down. If any messages are processed we'll likely crash. Exit now. 673 // down. If any messages are processed we'll likely crash. Exit now.
558 ExitProcess(content::RESULT_CODE_NORMAL_EXIT); 674 ExitProcess(content::RESULT_CODE_NORMAL_EXIT);
559 #elif defined(OS_POSIX) && !defined(OS_MACOSX) 675 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
560 _exit(content::RESULT_CODE_NORMAL_EXIT); 676 _exit(content::RESULT_CODE_NORMAL_EXIT);
561 #else 677 #else
562 NOTIMPLEMENTED(); 678 NOTIMPLEMENTED();
563 #endif 679 #endif
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 // If no more TabContents from Browsers, check the BackgroundPrintingManager. 903 // If no more TabContents from Browsers, check the BackgroundPrintingManager.
788 while (bg_printing_iterator_ != GetBackgroundPrintingManager()->end()) { 904 while (bg_printing_iterator_ != GetBackgroundPrintingManager()->end()) {
789 cur_ = *bg_printing_iterator_; 905 cur_ = *bg_printing_iterator_;
790 CHECK(cur_); 906 CHECK(cur_);
791 ++bg_printing_iterator_; 907 ++bg_printing_iterator_;
792 return; 908 return;
793 } 909 }
794 // Reached the end - no more TabContents. 910 // Reached the end - no more TabContents.
795 cur_ = NULL; 911 cur_ = NULL;
796 } 912 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/browser_list.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698