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 10 matching lines...) Expand all Loading... | |
40 #include "chromeos/dbus/dbus_thread_manager.h" | 41 #include "chromeos/dbus/dbus_thread_manager.h" |
41 #include "chromeos/dbus/session_manager_client.h" | 42 #include "chromeos/dbus/session_manager_client.h" |
42 #include "chromeos/dbus/update_engine_client.h" | 43 #include "chromeos/dbus/update_engine_client.h" |
43 #endif | 44 #endif |
44 | 45 |
45 #if defined(OS_WIN) | 46 #if defined(OS_WIN) |
46 #include "base/win/win_util.h" | 47 #include "base/win/win_util.h" |
47 #endif | 48 #endif |
48 | 49 |
49 namespace chrome { | 50 namespace chrome { |
51 | |
50 namespace { | 52 namespace { |
51 | 53 |
52 #if !defined(OS_ANDROID) | 54 #if !defined(OS_ANDROID) |
53 // Returns true if all browsers can be closed without user interaction. | 55 // Returns true if all browsers can be closed without user interaction. |
54 // This currently checks if there is pending download, or if it needs to | 56 // This currently checks if there is pending download, or if it needs to |
55 // handle unload handler. | 57 // handle unload handler. |
56 bool AreAllBrowsersCloseable() { | 58 bool AreAllBrowsersCloseable() { |
57 if (BrowserList::GetInstance()->empty()) | 59 if (BrowserList::GetInstance()->empty()) |
58 return true; | 60 return true; |
59 | 61 |
60 // If there are any downloads active, all browsers are not closeable. | 62 // If there are any downloads active, all browsers are not closeable. |
61 // However, this does not block for malicious downloads. | 63 // However, this does not block for malicious downloads. |
62 if (DownloadService::NonMaliciousDownloadCountAllProfiles() > 0) | 64 if (DownloadService::NonMaliciousDownloadCountAllProfiles() > 0) |
63 return false; | 65 return false; |
64 | 66 |
65 // Check TabsNeedBeforeUnloadFired(). | 67 // Check TabsNeedBeforeUnloadFired(). |
66 for (auto* browser : *BrowserList::GetInstance()) { | 68 for (auto* browser : *BrowserList::GetInstance()) { |
67 if (browser->TabsNeedBeforeUnloadFired()) | 69 if (browser->TabsNeedBeforeUnloadFired()) |
68 return false; | 70 return false; |
69 } | 71 } |
70 return true; | 72 return true; |
71 } | 73 } |
72 | 74 |
73 int g_keep_alive_count = 0; | |
74 bool g_disable_shutdown_for_testing = false; | 75 bool g_disable_shutdown_for_testing = false; |
75 #endif // !defined(OS_ANDROID) | 76 #endif // !defined(OS_ANDROID) |
76 | 77 |
77 #if defined(OS_CHROMEOS) | 78 #if defined(OS_CHROMEOS) |
78 // Whether chrome should send stop request to a session manager. | 79 // Whether chrome should send stop request to a session manager. |
79 bool g_send_stop_request_to_session_manager = false; | 80 bool g_send_stop_request_to_session_manager = false; |
80 #endif | 81 #endif |
81 | 82 |
82 } // namespace | 83 } // namespace |
83 | 84 |
(...skipping 22 matching lines...) Expand all Loading... | |
106 void CloseAllBrowsersAndQuit() { | 107 void CloseAllBrowsersAndQuit() { |
107 browser_shutdown::SetTryingToQuit(true); | 108 browser_shutdown::SetTryingToQuit(true); |
108 CloseAllBrowsers(); | 109 CloseAllBrowsers(); |
109 } | 110 } |
110 | 111 |
111 void CloseAllBrowsers() { | 112 void CloseAllBrowsers() { |
112 // If there are no browsers and closing the last browser would quit the | 113 // 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 | 114 // application, send the APP_TERMINATING action here. Otherwise, it will be |
114 // sent by RemoveBrowser() when the last browser has closed. | 115 // sent by RemoveBrowser() when the last browser has closed. |
115 if (chrome::GetTotalBrowserCount() == 0 && | 116 if (chrome::GetTotalBrowserCount() == 0 && |
116 (browser_shutdown::IsTryingToQuit() || !chrome::WillKeepAlive())) { | 117 (browser_shutdown::IsTryingToQuit() || |
118 !KeepAliveRegistry::GetInstance()->IsKeepingAlive())) { | |
117 // Tell everyone that we are shutting down. | 119 // Tell everyone that we are shutting down. |
118 browser_shutdown::SetTryingToQuit(true); | 120 browser_shutdown::SetTryingToQuit(true); |
119 | 121 |
120 #if defined(ENABLE_SESSION_SERVICE) | 122 #if defined(ENABLE_SESSION_SERVICE) |
121 // If ShuttingDownWithoutClosingBrowsers() returns true, the session | 123 // If ShuttingDownWithoutClosingBrowsers() returns true, the session |
122 // services may not get a chance to shut down normally, so explicitly shut | 124 // 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. | 125 // them down here to ensure they have a chance to persist their data. |
124 ProfileManager::ShutdownSessionServices(); | 126 ProfileManager::ShutdownSessionServices(); |
125 #endif | 127 #endif |
126 | 128 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 #if defined(OS_WIN) | 270 #if defined(OS_WIN) |
269 base::win::SetShouldCrashOnProcessDetach(false); | 271 base::win::SetShouldCrashOnProcessDetach(false); |
270 #endif | 272 #endif |
271 // On Windows 7 and later, the system will consider the process ripe for | 273 // 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 | 274 // termination as soon as it hides or destroys its windows. Since any |
273 // execution past that point will be non-deterministically cut short, we | 275 // execution past that point will be non-deterministically cut short, we |
274 // might as well put ourselves out of that misery deterministically. | 276 // might as well put ourselves out of that misery deterministically. |
275 base::Process::Current().Terminate(0, false); | 277 base::Process::Current().Terminate(0, false); |
276 } | 278 } |
277 | 279 |
278 void IncrementKeepAliveCount() { | |
279 // Increment the browser process refcount as long as we're keeping the | |
dgn
2016/03/09 23:49:23
moved to KeepAliveRegistry::OnKeepingAliveChanged
| |
280 // application alive. | |
281 if (!WillKeepAlive()) | |
282 g_browser_process->AddRefModule(); | |
283 ++g_keep_alive_count; | |
284 } | |
285 | |
286 void CloseAllBrowsersIfNeeded() { | 280 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 && | 281 if (chrome::GetTotalBrowserCount() == 0 && |
291 !browser_shutdown::IsTryingToQuit() && base::MessageLoop::current() && | 282 !browser_shutdown::IsTryingToQuit() && base::MessageLoop::current() && |
292 !g_disable_shutdown_for_testing) { | 283 !g_disable_shutdown_for_testing) { |
293 CloseAllBrowsers(); | 284 CloseAllBrowsers(); |
294 } | 285 } |
295 } | 286 } |
296 | 287 |
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, | |
dgn
2016/03/09 23:49:23
moved to KeepAliveRegistry::OnKeepingAliveChanged
| |
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) | 288 #endif // !defined(OS_ANDROID) |
319 | 289 |
320 void NotifyAppTerminating() { | 290 void NotifyAppTerminating() { |
321 static bool notified = false; | 291 static bool notified = false; |
322 if (notified) | 292 if (notified) |
323 return; | 293 return; |
324 notified = true; | 294 notified = true; |
325 content::NotificationService::current()->Notify( | 295 content::NotificationService::current()->Notify( |
326 chrome::NOTIFICATION_APP_TERMINATING, | 296 chrome::NOTIFICATION_APP_TERMINATING, |
327 content::NotificationService::AllSources(), | 297 content::NotificationService::AllSources(), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 void OnAppExiting() { | 340 void OnAppExiting() { |
371 static bool notified = false; | 341 static bool notified = false; |
372 if (notified) | 342 if (notified) |
373 return; | 343 return; |
374 notified = true; | 344 notified = true; |
375 HandleAppExitingForPlatform(); | 345 HandleAppExitingForPlatform(); |
376 } | 346 } |
377 | 347 |
378 void DisableShutdownForTesting(bool disable_shutdown_for_testing) { | 348 void DisableShutdownForTesting(bool disable_shutdown_for_testing) { |
379 g_disable_shutdown_for_testing = disable_shutdown_for_testing; | 349 g_disable_shutdown_for_testing = disable_shutdown_for_testing; |
380 if (!g_disable_shutdown_for_testing && !WillKeepAlive()) | 350 if (!g_disable_shutdown_for_testing && |
351 !KeepAliveRegistry::GetInstance()->IsKeepingAlive()) | |
381 CloseAllBrowsersIfNeeded(); | 352 CloseAllBrowsersIfNeeded(); |
382 } | 353 } |
383 #endif // !defined(OS_ANDROID) | 354 #endif // !defined(OS_ANDROID) |
384 | 355 |
385 } // namespace chrome | 356 } // namespace chrome |
OLD | NEW |