| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/lifetime/application_lifetime.h" | 5 #include "chrome/browser/lifetime/application_lifetime.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/process/process.h" | 11 #include "base/process/process.h" |
| 12 #include "base/process/process_handle.h" | 12 #include "base/process/process_handle.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
| 15 #include "chrome/browser/browser_process_platform_part.h" | 15 #include "chrome/browser/browser_process_platform_part.h" |
| 16 #include "chrome/browser/browser_shutdown.h" | 16 #include "chrome/browser/browser_shutdown.h" |
| 17 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/download/download_service.h" | 18 #include "chrome/browser/download/download_service.h" |
| 19 #include "chrome/browser/lifetime/browser_close_manager.h" | 19 #include "chrome/browser/lifetime/browser_close_manager.h" |
| 20 #include "chrome/browser/lifetime/keep_alive_registry.h" |
| 20 #include "chrome/browser/metrics/thread_watcher.h" | 21 #include "chrome/browser/metrics/thread_watcher.h" |
| 21 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 22 #include "chrome/browser/profiles/profile_manager.h" | 23 #include "chrome/browser/profiles/profile_manager.h" |
| 23 #include "chrome/browser/ui/browser.h" | 24 #include "chrome/browser/ui/browser.h" |
| 24 #include "chrome/browser/ui/browser_finder.h" | 25 #include "chrome/browser/ui/browser_finder.h" |
| 25 #include "chrome/browser/ui/browser_list.h" | 26 #include "chrome/browser/ui/browser_list.h" |
| 26 #include "chrome/browser/ui/browser_tabstrip.h" | 27 #include "chrome/browser/ui/browser_tabstrip.h" |
| 27 #include "chrome/browser/ui/browser_window.h" | 28 #include "chrome/browser/ui/browser_window.h" |
| 28 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 29 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 29 #include "chrome/browser/ui/user_manager.h" | 30 #include "chrome/browser/ui/user_manager.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 return false; | 64 return false; |
| 64 | 65 |
| 65 // Check TabsNeedBeforeUnloadFired(). | 66 // Check TabsNeedBeforeUnloadFired(). |
| 66 for (auto* browser : *BrowserList::GetInstance()) { | 67 for (auto* browser : *BrowserList::GetInstance()) { |
| 67 if (browser->TabsNeedBeforeUnloadFired()) | 68 if (browser->TabsNeedBeforeUnloadFired()) |
| 68 return false; | 69 return false; |
| 69 } | 70 } |
| 70 return true; | 71 return true; |
| 71 } | 72 } |
| 72 | 73 |
| 73 int g_keep_alive_count = 0; | |
| 74 bool g_disable_shutdown_for_testing = false; | 74 bool g_disable_shutdown_for_testing = false; |
| 75 #endif // !defined(OS_ANDROID) | 75 #endif // !defined(OS_ANDROID) |
| 76 | 76 |
| 77 #if defined(OS_CHROMEOS) | 77 #if defined(OS_CHROMEOS) |
| 78 // Whether chrome should send stop request to a session manager. | 78 // Whether chrome should send stop request to a session manager. |
| 79 bool g_send_stop_request_to_session_manager = false; | 79 bool g_send_stop_request_to_session_manager = false; |
| 80 #endif | 80 #endif |
| 81 | 81 |
| 82 } // namespace | 82 } // namespace |
| 83 | 83 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 106 void CloseAllBrowsersAndQuit() { | 106 void CloseAllBrowsersAndQuit() { |
| 107 browser_shutdown::SetTryingToQuit(true); | 107 browser_shutdown::SetTryingToQuit(true); |
| 108 CloseAllBrowsers(); | 108 CloseAllBrowsers(); |
| 109 } | 109 } |
| 110 | 110 |
| 111 void CloseAllBrowsers() { | 111 void CloseAllBrowsers() { |
| 112 // If there are no browsers and closing the last browser would quit the | 112 // If there are no browsers and closing the last browser would quit the |
| 113 // application, send the APP_TERMINATING action here. Otherwise, it will be | 113 // application, send the APP_TERMINATING action here. Otherwise, it will be |
| 114 // sent by RemoveBrowser() when the last browser has closed. | 114 // sent by RemoveBrowser() when the last browser has closed. |
| 115 if (chrome::GetTotalBrowserCount() == 0 && | 115 if (chrome::GetTotalBrowserCount() == 0 && |
| 116 (browser_shutdown::IsTryingToQuit() || !chrome::WillKeepAlive())) { | 116 (browser_shutdown::IsTryingToQuit() || |
| 117 !KeepAliveRegistry::GetInstance()->IsKeepingAlive())) { |
| 117 // Tell everyone that we are shutting down. | 118 // Tell everyone that we are shutting down. |
| 118 browser_shutdown::SetTryingToQuit(true); | 119 browser_shutdown::SetTryingToQuit(true); |
| 119 | 120 |
| 120 #if defined(ENABLE_SESSION_SERVICE) | 121 #if defined(ENABLE_SESSION_SERVICE) |
| 121 // If ShuttingDownWithoutClosingBrowsers() returns true, the session | 122 // If ShuttingDownWithoutClosingBrowsers() returns true, the session |
| 122 // services may not get a chance to shut down normally, so explicitly shut | 123 // services may not get a chance to shut down normally, so explicitly shut |
| 123 // them down here to ensure they have a chance to persist their data. | 124 // them down here to ensure they have a chance to persist their data. |
| 124 ProfileManager::ShutdownSessionServices(); | 125 ProfileManager::ShutdownSessionServices(); |
| 125 #endif | 126 #endif |
| 126 | 127 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 #if defined(OS_WIN) | 269 #if defined(OS_WIN) |
| 269 base::win::SetShouldCrashOnProcessDetach(false); | 270 base::win::SetShouldCrashOnProcessDetach(false); |
| 270 #endif | 271 #endif |
| 271 // On Windows 7 and later, the system will consider the process ripe for | 272 // On Windows 7 and later, the system will consider the process ripe for |
| 272 // termination as soon as it hides or destroys its windows. Since any | 273 // termination as soon as it hides or destroys its windows. Since any |
| 273 // execution past that point will be non-deterministically cut short, we | 274 // execution past that point will be non-deterministically cut short, we |
| 274 // might as well put ourselves out of that misery deterministically. | 275 // might as well put ourselves out of that misery deterministically. |
| 275 base::Process::Current().Terminate(0, false); | 276 base::Process::Current().Terminate(0, false); |
| 276 } | 277 } |
| 277 | 278 |
| 278 void IncrementKeepAliveCount() { | |
| 279 // Increment the browser process refcount as long as we're keeping the | |
| 280 // application alive. | |
| 281 if (!WillKeepAlive()) | |
| 282 g_browser_process->AddRefModule(); | |
| 283 ++g_keep_alive_count; | |
| 284 } | |
| 285 | |
| 286 void CloseAllBrowsersIfNeeded() { | 279 void CloseAllBrowsersIfNeeded() { |
| 287 // If there are no browsers open and we aren't already shutting down, | |
| 288 // initiate a shutdown. Also skips shutdown if this is a unit test. | |
| 289 // (MessageLoop::current() == null or explicitly disabled). | |
| 290 if (chrome::GetTotalBrowserCount() == 0 && | 280 if (chrome::GetTotalBrowserCount() == 0 && |
| 291 !browser_shutdown::IsTryingToQuit() && base::MessageLoop::current() && | 281 !browser_shutdown::IsTryingToQuit() && base::MessageLoop::current() && |
| 292 !g_disable_shutdown_for_testing) { | 282 !g_disable_shutdown_for_testing) { |
| 293 CloseAllBrowsers(); | 283 CloseAllBrowsers(); |
| 294 } | 284 } |
| 295 } | 285 } |
| 296 | 286 |
| 297 void DecrementKeepAliveCount() { | |
| 298 DCHECK_GT(g_keep_alive_count, 0); | |
| 299 --g_keep_alive_count; | |
| 300 // Although we should have a browser process, if there is none, | |
| 301 // there is nothing to do. | |
| 302 if (!g_browser_process) return; | |
| 303 | |
| 304 // Allow the app to shutdown again. | |
| 305 if (!WillKeepAlive()) { | |
| 306 g_browser_process->ReleaseModule(); | |
| 307 CloseAllBrowsersIfNeeded(); | |
| 308 } | |
| 309 } | |
| 310 | |
| 311 int GetKeepAliveCountForTesting() { | |
| 312 return g_keep_alive_count; | |
| 313 } | |
| 314 | |
| 315 bool WillKeepAlive() { | |
| 316 return g_keep_alive_count > 0; | |
| 317 } | |
| 318 #endif // !defined(OS_ANDROID) | 287 #endif // !defined(OS_ANDROID) |
| 319 | 288 |
| 320 void NotifyAppTerminating() { | 289 void NotifyAppTerminating() { |
| 321 static bool notified = false; | 290 static bool notified = false; |
| 322 if (notified) | 291 if (notified) |
| 323 return; | 292 return; |
| 324 notified = true; | 293 notified = true; |
| 325 content::NotificationService::current()->Notify( | 294 content::NotificationService::current()->Notify( |
| 326 chrome::NOTIFICATION_APP_TERMINATING, | 295 chrome::NOTIFICATION_APP_TERMINATING, |
| 327 content::NotificationService::AllSources(), | 296 content::NotificationService::AllSources(), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 void OnAppExiting() { | 339 void OnAppExiting() { |
| 371 static bool notified = false; | 340 static bool notified = false; |
| 372 if (notified) | 341 if (notified) |
| 373 return; | 342 return; |
| 374 notified = true; | 343 notified = true; |
| 375 HandleAppExitingForPlatform(); | 344 HandleAppExitingForPlatform(); |
| 376 } | 345 } |
| 377 | 346 |
| 378 void DisableShutdownForTesting(bool disable_shutdown_for_testing) { | 347 void DisableShutdownForTesting(bool disable_shutdown_for_testing) { |
| 379 g_disable_shutdown_for_testing = disable_shutdown_for_testing; | 348 g_disable_shutdown_for_testing = disable_shutdown_for_testing; |
| 380 if (!g_disable_shutdown_for_testing && !WillKeepAlive()) | 349 if (!g_disable_shutdown_for_testing && |
| 350 !KeepAliveRegistry::GetInstance()->IsKeepingAlive()) |
| 381 CloseAllBrowsersIfNeeded(); | 351 CloseAllBrowsersIfNeeded(); |
| 382 } | 352 } |
| 383 #endif // !defined(OS_ANDROID) | 353 #endif // !defined(OS_ANDROID) |
| 384 | 354 |
| 385 } // namespace chrome | 355 } // namespace chrome |
| OLD | NEW |