| Index: chrome/browser/lifetime/application_lifetime.cc
|
| diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
|
| index 1986d1b3a5c44e9159c4943b7a1919cb8b1c3d0a..2626bf541fcdd32246b966e4d254adeb8bb7f9e8 100644
|
| --- a/chrome/browser/lifetime/application_lifetime.cc
|
| +++ b/chrome/browser/lifetime/application_lifetime.cc
|
| @@ -8,94 +8,31 @@
|
| #include "base/command_line.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/prefs/pref_service.h"
|
| #include "base/process/process.h"
|
| #include "base/process/process_handle.h"
|
| #include "base/trace_event/trace_event.h"
|
| -#include "build/build_config.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/browser_process_platform_part.h"
|
| #include "chrome/browser/browser_shutdown.h"
|
| #include "chrome/browser/chrome_notification_types.h"
|
| -#include "chrome/browser/download/download_service.h"
|
| -#include "chrome/browser/lifetime/browser_close_manager.h"
|
| +#include "chrome/browser/lifetime/application_lifetime_internal.h"
|
| #include "chrome/browser/metrics/thread_watcher.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/profiles/profile_manager.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/browser_finder.h"
|
| -#include "chrome/browser/ui/browser_iterator.h"
|
| -#include "chrome/browser/ui/browser_tabstrip.h"
|
| -#include "chrome/browser/ui/browser_window.h"
|
| -#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| -#include "chrome/browser/ui/user_manager.h"
|
| #include "chrome/common/chrome_constants.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/pref_names.h"
|
| #include "components/tracing/tracing_switches.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/navigation_details.h"
|
| #include "content/public/browser/notification_service.h"
|
|
|
| -#if defined(OS_CHROMEOS)
|
| -#include "base/sys_info.h"
|
| -#include "chrome/browser/chromeos/boot_times_recorder.h"
|
| -#include "chromeos/dbus/dbus_thread_manager.h"
|
| -#include "chromeos/dbus/session_manager_client.h"
|
| -#include "chromeos/dbus/update_engine_client.h"
|
| -#endif
|
| -
|
| #if defined(OS_WIN)
|
| #include "base/win/win_util.h"
|
| #include "components/browser_watcher/exit_funnel_win.h"
|
| #endif
|
|
|
| -#if defined(USE_ASH)
|
| -#include "ash/shell.h"
|
| +#if !defined(OS_ANDROID) && !defined(OS_IOS)
|
| +#include "chrome/browser/lifetime/application_lifetime_desktop.h"
|
| #endif
|
|
|
| namespace chrome {
|
| -namespace {
|
| -
|
| -#if !defined(OS_ANDROID)
|
| -// Returns true if all browsers can be closed without user interaction.
|
| -// This currently checks if there is pending download, or if it needs to
|
| -// handle unload handler.
|
| -bool AreAllBrowsersCloseable() {
|
| - chrome::BrowserIterator browser_it;
|
| - if (browser_it.done())
|
| - return true;
|
|
|
| - // If there are any downloads active, all browsers are not closeable.
|
| - // However, this does not block for malicious downloads.
|
| - if (DownloadService::NonMaliciousDownloadCountAllProfiles() > 0)
|
| - return false;
|
| -
|
| - // Check TabsNeedBeforeUnloadFired().
|
| - for (; !browser_it.done(); browser_it.Next()) {
|
| - if (browser_it->TabsNeedBeforeUnloadFired())
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -#endif // !defined(OS_ANDROID)
|
| -
|
| -int g_keep_alive_count = 0;
|
| -bool g_disable_shutdown_for_testing = false;
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| -// Whether chrome should send stop request to a session manager.
|
| -bool g_send_stop_request_to_session_manager = false;
|
| -#endif
|
| -
|
| -} // namespace
|
| -
|
| -void MarkAsCleanShutdown() {
|
| - // TODO(beng): Can this use ProfileManager::GetLoadedProfiles() instead?
|
| - for (chrome::BrowserIterator it; !it.done(); it.Next())
|
| - it->profile()->SetExitType(Profile::EXIT_NORMAL);
|
| -}
|
| +namespace internal {
|
|
|
| void AttemptExitInternal(bool try_to_quit_application) {
|
| // On Mac, the platform-specific part handles setting this.
|
| @@ -112,74 +49,7 @@ void AttemptExitInternal(bool try_to_quit_application) {
|
| g_browser_process->platform_part()->AttemptExit();
|
| }
|
|
|
| -void CloseAllBrowsersAndQuit() {
|
| - browser_shutdown::SetTryingToQuit(true);
|
| - CloseAllBrowsers();
|
| -}
|
| -
|
| -void CloseAllBrowsers() {
|
| - // If there are no browsers and closing the last browser would quit the
|
| - // application, send the APP_TERMINATING action here. Otherwise, it will be
|
| - // sent by RemoveBrowser() when the last browser has closed.
|
| - if (chrome::GetTotalBrowserCount() == 0 &&
|
| - (browser_shutdown::IsTryingToQuit() || !chrome::WillKeepAlive())) {
|
| - // Tell everyone that we are shutting down.
|
| - browser_shutdown::SetTryingToQuit(true);
|
| -
|
| -#if defined(ENABLE_SESSION_SERVICE)
|
| - // If ShuttingDownWithoutClosingBrowsers() returns true, the session
|
| - // services may not get a chance to shut down normally, so explicitly shut
|
| - // them down here to ensure they have a chance to persist their data.
|
| - ProfileManager::ShutdownSessionServices();
|
| -#endif
|
| -
|
| - chrome::NotifyAndTerminate(true);
|
| - chrome::OnAppExiting();
|
| - return;
|
| - }
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| - chromeos::BootTimesRecorder::Get()->AddLogoutTimeMarker(
|
| - "StartedClosingWindows", false);
|
| -#endif
|
| - scoped_refptr<BrowserCloseManager> browser_close_manager =
|
| - new BrowserCloseManager;
|
| - browser_close_manager->StartClosingBrowsers();
|
| -}
|
| -
|
| -void AttemptUserExit() {
|
| -#if defined(OS_CHROMEOS)
|
| - StartShutdownTracing();
|
| - chromeos::BootTimesRecorder::Get()->AddLogoutTimeMarker("LogoutStarted",
|
| - false);
|
| -
|
| - PrefService* state = g_browser_process->local_state();
|
| - if (state) {
|
| - chromeos::BootTimesRecorder::Get()->OnLogoutStarted(state);
|
| -
|
| - // Login screen should show up in owner's locale.
|
| - std::string owner_locale = state->GetString(prefs::kOwnerLocale);
|
| - if (!owner_locale.empty() &&
|
| - state->GetString(prefs::kApplicationLocale) != owner_locale &&
|
| - !state->IsManagedPreference(prefs::kApplicationLocale)) {
|
| - state->SetString(prefs::kApplicationLocale, owner_locale);
|
| - TRACE_EVENT0("shutdown", "CommitPendingWrite");
|
| - state->CommitPendingWrite();
|
| - }
|
| - }
|
| - g_send_stop_request_to_session_manager = true;
|
| - // On ChromeOS, always terminate the browser, regardless of the result of
|
| - // AreAllBrowsersCloseable(). See crbug.com/123107.
|
| - chrome::NotifyAndTerminate(true);
|
| -#else
|
| - // Reset the restart bit that might have been set in cancelled restart
|
| - // request.
|
| - UserManager::Hide();
|
| - PrefService* pref_service = g_browser_process->local_state();
|
| - pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, false);
|
| - AttemptExitInternal(false);
|
| -#endif
|
| -}
|
| +} // namespace internal
|
|
|
| void StartShutdownTracing() {
|
| const base::CommandLine& command_line =
|
| @@ -194,33 +64,6 @@ void StartShutdownTracing() {
|
| TRACE_EVENT0("shutdown", "StartShutdownTracing");
|
| }
|
|
|
| -// The Android implementation is in application_lifetime_android.cc
|
| -#if !defined(OS_ANDROID)
|
| -void AttemptRestart() {
|
| - // TODO(beng): Can this use ProfileManager::GetLoadedProfiles instead?
|
| - for (chrome::BrowserIterator it; !it.done(); it.Next())
|
| - content::BrowserContext::SaveSessionState(it->profile());
|
| -
|
| - PrefService* pref_service = g_browser_process->local_state();
|
| - pref_service->SetBoolean(prefs::kWasRestarted, true);
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| - chromeos::BootTimesRecorder::Get()->set_restart_requested();
|
| -
|
| - DCHECK(!g_send_stop_request_to_session_manager);
|
| - // Make sure we don't send stop request to the session manager.
|
| - g_send_stop_request_to_session_manager = false;
|
| - // Run exit process in clean stack.
|
| - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&ExitCleanly));
|
| -#else
|
| - // Set the flag to restore state after the restart.
|
| - pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true);
|
| - AttemptExit();
|
| -#endif
|
| -}
|
| -#endif
|
| -
|
| void AttemptExit() {
|
| #if defined(OS_CHROMEOS)
|
| // On ChromeOS, user exit and system exits are the same.
|
| @@ -232,30 +75,12 @@ void AttemptExit() {
|
| // so crashes during shutdown are still reported in UMA.
|
| #if !defined(OS_ANDROID)
|
| // Android doesn't use Browser.
|
| - if (AreAllBrowsersCloseable())
|
| - MarkAsCleanShutdown();
|
| + internal::AttemptExitInternalDesktop();
|
| #endif
|
| - AttemptExitInternal(true);
|
| + internal::AttemptExitInternal(true);
|
| #endif
|
| }
|
|
|
| -#if defined(OS_CHROMEOS)
|
| -// A function called when SIGTERM is received.
|
| -void ExitCleanly() {
|
| - // We always mark exit cleanly.
|
| - MarkAsCleanShutdown();
|
| -
|
| - // Don't block when SIGTERM is received. AreaAllBrowsersCloseable()
|
| - // can be false in following cases. a) power-off b) signout from
|
| - // screen locker.
|
| - if (!AreAllBrowsersCloseable())
|
| - browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION);
|
| - else
|
| - browser_shutdown::OnShutdownStarting(browser_shutdown::BROWSER_EXIT);
|
| - AttemptExitInternal(true);
|
| -}
|
| -#endif
|
| -
|
| void SessionEnding() {
|
| #if defined(OS_WIN)
|
| browser_watcher::ExitFunnel funnel;
|
| @@ -296,9 +121,7 @@ void SessionEnding() {
|
|
|
| #if defined(OS_WIN)
|
| base::win::SetShouldCrashOnProcessDetach(false);
|
| -#endif
|
|
|
| -#if defined(OS_WIN)
|
| // KillProcess ought to terminate the process without further ado, so if
|
| // execution gets to this point, presumably this is normal exit.
|
| funnel.RecordEvent(L"KillProcess");
|
| @@ -311,43 +134,6 @@ void SessionEnding() {
|
| base::Process::Current().Terminate(0, false);
|
| }
|
|
|
| -void IncrementKeepAliveCount() {
|
| - // Increment the browser process refcount as long as we're keeping the
|
| - // application alive.
|
| - if (!WillKeepAlive())
|
| - g_browser_process->AddRefModule();
|
| - ++g_keep_alive_count;
|
| -}
|
| -
|
| -void CloseAllBrowsersIfNeeded() {
|
| - // If there are no browsers open and we aren't already shutting down,
|
| - // initiate a shutdown. Also skips shutdown if this is a unit test.
|
| - // (MessageLoop::current() == null or explicitly disabled).
|
| - if (chrome::GetTotalBrowserCount() == 0 &&
|
| - !browser_shutdown::IsTryingToQuit() && base::MessageLoop::current() &&
|
| - !g_disable_shutdown_for_testing) {
|
| - CloseAllBrowsers();
|
| - }
|
| -}
|
| -
|
| -void DecrementKeepAliveCount() {
|
| - DCHECK_GT(g_keep_alive_count, 0);
|
| - --g_keep_alive_count;
|
| - // Although we should have a browser process, if there is none,
|
| - // there is nothing to do.
|
| - if (!g_browser_process) return;
|
| -
|
| - // Allow the app to shutdown again.
|
| - if (!WillKeepAlive()) {
|
| - g_browser_process->ReleaseModule();
|
| - CloseAllBrowsersIfNeeded();
|
| - }
|
| -}
|
| -
|
| -bool WillKeepAlive() {
|
| - return g_keep_alive_count > 0;
|
| -}
|
| -
|
| void NotifyAppTerminating() {
|
| static bool notified = false;
|
| if (notified)
|
| @@ -372,62 +158,8 @@ void NotifyAndTerminate(bool fast_path) {
|
| NotifyAppTerminating();
|
|
|
| #if defined(OS_CHROMEOS)
|
| - if (base::SysInfo::IsRunningOnChromeOS()) {
|
| - // If we're on a ChromeOS device, reboot if an update has been applied,
|
| - // or else signal the session manager to log out.
|
| - chromeos::UpdateEngineClient* update_engine_client
|
| - = chromeos::DBusThreadManager::Get()->GetUpdateEngineClient();
|
| - if (update_engine_client->GetLastStatus().status ==
|
| - chromeos::UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
|
| - update_engine_client->RebootAfterUpdate();
|
| - } else if (g_send_stop_request_to_session_manager) {
|
| - // Don't ask SessionManager to stop session if the shutdown request comes
|
| - // from session manager.
|
| - chromeos::DBusThreadManager::Get()->GetSessionManagerClient()
|
| - ->StopSession();
|
| - }
|
| - } else {
|
| - if (g_send_stop_request_to_session_manager) {
|
| - // If running the Chrome OS build, but we're not on the device, act
|
| - // as if we received signal from SessionManager.
|
| - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&ExitCleanly));
|
| - }
|
| - }
|
| + internal::NotifyAndTerminateInternalCrOS();
|
| #endif
|
| }
|
|
|
| -void OnAppExiting() {
|
| - static bool notified = false;
|
| - if (notified)
|
| - return;
|
| - notified = true;
|
| - HandleAppExitingForPlatform();
|
| -}
|
| -
|
| -bool ShouldStartShutdown(Browser* browser) {
|
| - if (BrowserList::GetInstance(browser->host_desktop_type())->size() > 1)
|
| - return false;
|
| -#if defined(OS_WIN)
|
| - // On Windows 8 the desktop and ASH environments could be active
|
| - // at the same time.
|
| - // We should not start the shutdown process in the following cases:-
|
| - // 1. If the desktop type of the browser going away is ASH and there
|
| - // are browser windows open in the desktop.
|
| - // 2. If the desktop type of the browser going away is desktop and the ASH
|
| - // environment is still active.
|
| - if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE)
|
| - return !ash::Shell::HasInstance();
|
| - else if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH)
|
| - return BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->empty();
|
| -#endif
|
| - return true;
|
| -}
|
| -
|
| -void DisableShutdownForTesting(bool disable_shutdown_for_testing) {
|
| - g_disable_shutdown_for_testing = disable_shutdown_for_testing;
|
| - if (!g_disable_shutdown_for_testing && !WillKeepAlive())
|
| - CloseAllBrowsersIfNeeded();
|
| -}
|
| -
|
| } // namespace chrome
|
|
|