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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/browser_list.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/browser_list.cc
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc
index be11579dd2359840435112537ac8179c225e8e87..f05ee705ac7f0425d7b34a07cf0bc51fecd144e2 100644
--- a/chrome/browser/ui/browser_list.cc
+++ b/chrome/browser/ui/browser_list.cc
@@ -40,6 +40,95 @@
namespace {
+// ********************* IMPORTANT ****************
+// Please read and update if you need to change the quit/shutdown
+// process.
+//
+// This is an attempt to descritbe different kinds of quit/shutdown
+// process that chrome may process. This overs only Windows and Linux
+// because I (oshima) don't know about mac. Mac contribution to this
+// comment would be greatly appreciated.
+//
+// Common behavior.
+// APP_EXITING notification is always sent when chrome starts shutdown
+// process (with one exception. see ChromeOS guest mode below).
+// Note that shutdown process can be canceled, so APP_EXITING may
+// be sent MORE THAN ONCE.
+//
+// Normal shutdown on Linux & Windows
+// A user requested to quit the browser (win: by wrench menu or
+// ctrl-alt-q, or linux:wrench menu, ctrl-alt-q or SIGTERM).
+// It notifies APP_EXITING, then tries to close all browsers.
+// When the last browser gets deleted, it sends out APP_TERMINATING
+// notification as a signal that browser is really quitting.
+// Shutdown may be blocked and canceled by beforeunload handler or
+// downloads in progress. (in which case, APP_TERMINATING won't be sent)
+//
+// Restart on Linux & Windows
+// A user requested to restart the browser. This can happen when
+// certain preference has changed (flags page, language option), or
+// update is availabe. Chrome sets kRestartLastSessionOnShutdown
+// preference to true, follows normal shutdown process and re-launches
+// itself at the end of the process (see browser_shutdown::Shutdown()).
+//
+// Logoff/power off on Windows
+// This happens when chrome recieves WM_ENDSESSION message. It
+// notifies APP_EXITING, then close all tabs forcibly. This
+// process does send APP_TERMINATING notification. This shutdown
+// process cannot be blocked nor canceled.
+//
+// X IO Error on Linux and ChromeOS:
+// When X server reports IO error, it's most likely X has gone away and
+// chrome needs has to shutdown without make another call to X.
+// This is similar to Window's logoff/power off process, except that
+// chrome doesn't try to close browsers nor tabs. APP_TERMINATING is sent
+// after APP_EXITING.
+//
+// ChromeOS specific:
+// Fast shutdown
+// When a user requested to quit browser either by wrench menu or
+// ctrl-alt-q, and we know that shutdown will not be canceled (that is,
+// all contents have no beforeunload handlers and there is no
+// downloads in progress), chrome quits using fast shutdown process.
+// It notifies APP_EXITING, followed by APP_TERMINATING, then
+// tells SessionManager to start shutdown process. SessionManager sends
+// SIGTERM back to chrome, which closes all browsers.
+//
+// Slow shutdown
+// If there is a tab with beforeunload handlers, or a download is
+// in progress, it will follow normal shutdown process. That is,
+// it notifies APP_EXITING, tries to closes all browsers. APP_TERMINATING
+// will be sent when the last browser is closd. Shutdown may be cancelled
+// either by beforeunload handler or download dialog.
+//
+// Restart
+// ChromeOS does not support restarting. It follows regular shutdown process,
+//
+// Power off
+// A user pressed power button, or closed a lid on login screen. This is
+// similar to Windows log-off/power-off scenario. Chrome receives SIGTERM
+// and start shutdown process. It will close all tabs forcibly and shutdown
+// cannot be canceled.
+//
+// Signout from Screen locker.
+// A user clicked signout button on screen locker. This is basically same
+// as Power off. Chrome asks session manager to stop session and session
+// manager sends SIGTERM to chrome.
+//
+// Switching to Guest mode
+// When a user selected guest mode, Chrome first writes exit_cleanly bit
+// off to the disk (see g_browser_process->EndSession() in
+// chromeos/login_utils.cc), then tells SessionManager to switch to guest
+// mode. Session manager kills and restarts Chrome with guest mode flag.
+// This process never use method in BrowserList, nor sends APP_EXITING
+// or APP_TERMINATING (to restart fast).
+//
+// Note that different shutdown path
+//
+// Mac:
+// T.B.D.
+//
+
// This object is instantiated when the first Browser object is added to the
// list and delete when the last one is removed. It watches for loads and
// creates histograms of some global object counts.
@@ -201,15 +290,29 @@ bool AreAllBrowsersCloseable() {
return true;
}
+// Sends out NOTIFICATION_APP_TERMINATING notification.
+// Returns true if the notification is set, or false if the notification
+// has already sent out before.
+bool NotifyAppTerminating() {
+ static bool notified = false;
+ if (notified)
+ return false;
+ notified = true;
+ NotificationService::current()->Notify(
+ content::NOTIFICATION_APP_TERMINATING,
+ NotificationService::AllSources(),
+ NotificationService::NoDetails());
+ return true;
+}
+
#if defined(OS_CHROMEOS)
-bool signout = false;
+bool explicit_signout = false;
// Fast shutdown for ChromeOS. It tells session manager to start
// shutdown process when closing browser windows won't be canceled.
// Returns true if fast shutdown is successfully started.
bool FastShutdown() {
- signout = true;
if (chromeos::CrosLibrary::Get()->EnsureLoaded()
&& AreAllBrowsersCloseable()) {
BrowserList::NotifyAndTerminate(true);
@@ -287,15 +390,12 @@ void BrowserList::AttemptExitInternal() {
// static
void BrowserList::NotifyAndTerminate(bool fast_path) {
#if defined(OS_CHROMEOS)
- if (!signout)
+ if (browser_shutdown::ShutdownType() != browser_shutdown::BROWSER_EXIT);
return;
#endif
if (fast_path) {
- NotificationService::current()->Notify(
- content::NOTIFICATION_APP_TERMINATING,
- NotificationService::AllSources(),
- NotificationService::NoDetails());
+ NotifyAppTerminating();
}
#if defined(OS_CHROMEOS)
@@ -357,10 +457,9 @@ void BrowserList::RemoveBrowser(Browser* browser) {
// to call ProfileManager::ShutdownSessionServices() as part of the
// shutdown, because Browser::WindowClosing() already makes sure that the
// SessionService is created and notified.
- NotificationService::current()->Notify(
- content::NOTIFICATION_APP_TERMINATING,
- NotificationService::AllSources(),
- NotificationService::NoDetails());
+ // On ChromeOS, APP_TERMINATING might have already been sent when
+ // shutdown is first requested. The call will be ignored in that case.
+ NotifyAppTerminating();
AllBrowsersClosedAndAppExiting();
}
}
@@ -377,6 +476,9 @@ void BrowserList::RemoveObserver(BrowserList::Observer* observer) {
// static
void BrowserList::CloseAllBrowsers() {
+ browser_shutdown::ShutdownType shutdown_type =
+ browser_shutdown::GetShutdownType()
+ /*
bool session_ending =
browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION;
bool force_exit = false;
@@ -384,6 +486,7 @@ void BrowserList::CloseAllBrowsers() {
if (session_ending)
force_exit = true;
#endif
+ */
// Tell everyone that we are shutting down.
browser_shutdown::SetTryingToQuit(true);
@@ -391,21 +494,29 @@ void BrowserList::CloseAllBrowsers() {
// exit can restore all browsers open before exiting.
ProfileManager::ShutdownSessionServices();
+ // If we're not closing browser, send APP_TERMINATING
+ if (shutdown_type == browser_shutdown::SHUTDOWN_WITHOUT_CLOSE) {
+ NotifyAppTerminating();
+ return;
+ }
+
// If there are no browsers, send the APP_TERMINATING action here. Otherwise,
// it will be sent by RemoveBrowser() when the last browser has closed.
if (force_exit || browsers_.empty()) {
NotifyAndTerminate(true);
return;
}
+
#if defined(OS_CHROMEOS)
chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker(
"StartedClosingWindows", false);
#endif
+
for (BrowserList::const_iterator i = BrowserList::begin();
i != BrowserList::end();) {
Browser* browser = *i;
achuithb 2011/10/28 22:22:26 Do you think you could also clean this loop up if
browser->window()->Close();
- if (!session_ending) {
+ if (shutdown_type != browser_shutdown::POWER_OFF) {
++i;
} else {
// This path is hit during logoff/power-down. In this case we won't get
@@ -447,6 +558,7 @@ void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
// static
void BrowserList::AttemptUserExit() {
+ browser_shutdown::OnShutdownStarting(browser_shutdown::BROWSER_EXIT);
#if defined(OS_CHROMEOS)
chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false);
// Write /tmp/uptime-logout-started as well.
@@ -464,6 +576,7 @@ void BrowserList::AttemptUserExit() {
state->SavePersistentPrefs();
}
}
+
if (FastShutdown())
return;
#else
@@ -481,6 +594,7 @@ void BrowserList::AttemptRestart() {
// For CrOS instead of browser restart (which is not supported) perform a full
// sign out. Session will be only restored if user has that setting set.
// Same session restore behavior happens in case of full restart after update.
+ // TODO(oshima): Should we use LoginLibrary::RestartJob()?
AttemptUserExit();
#else
// Set the flag to restore state after the restart.
@@ -506,11 +620,13 @@ void BrowserList::AttemptExit() {
void BrowserList::ExitCleanly() {
// We always mark exit cleanly.
g_browser_process->EndSession();
+ if (AreAllBrowsersCloseable())
+
AttemptExitInternal();
}
#endif
-static void TimeLimitedSessionEnding() {
+static void TimeLimitedForceShutdown(browser_shutdown::ShutdownType type) {
// Start watching for hang during shutdown, and crash it if takes too long.
// We disarm when |shutdown_watcher| object is destroyed, which is when we
// exit this function.
@@ -524,8 +640,8 @@ static void TimeLimitedSessionEnding() {
if (already_ended || !NotificationService::current())
return;
already_ended = true;
-
- browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION);
+
+ browser_shutdown::OnShutdownStarting(type);
NotificationService::current()->Notify(
content::NOTIFICATION_APP_EXITING,
@@ -549,8 +665,8 @@ static void TimeLimitedSessionEnding() {
}
// static
-void BrowserList::SessionEnding() {
- TimeLimitedSessionEnding();
+void BrowserList::ForceShutdown(SessionEndingReason raeson) {
+ TimeLimitedForceShutdown(reason);
#if defined(OS_WIN)
// At this point the message loop is still running yet we've shut everything
« 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