OLD | NEW |
---|---|
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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 | 248 |
249 // Send out notifications after add has occurred. Do some basic checking to | 249 // Send out notifications after add has occurred. Do some basic checking to |
250 // try to catch evil observers that change the list from under us. | 250 // try to catch evil observers that change the list from under us. |
251 size_t original_count = observers_.size(); | 251 size_t original_count = observers_.size(); |
252 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserAdded(browser)); | 252 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserAdded(browser)); |
253 DCHECK_EQ(original_count, observers_.size()) | 253 DCHECK_EQ(original_count, observers_.size()) |
254 << "observer list modified during notification"; | 254 << "observer list modified during notification"; |
255 } | 255 } |
256 | 256 |
257 // static | 257 // static |
258 void BrowserList::MarkAsCleanShutdown() { | 258 void BrowserList::MarkAsCleanShutdownInUserProfiles() { |
259 for (const_iterator i = begin(); i != end(); ++i) { | 259 for (const_iterator i = begin(); i != end(); ++i) { |
260 (*i)->profile()->MarkAsCleanShutdown(); | 260 (*i)->profile()->MarkAsCleanShutdown(); |
261 } | 261 } |
262 } | 262 } |
263 | 263 |
264 void BrowserList::AttemptExitInternal() { | 264 void BrowserList::AttemptExitInternal() { |
265 NotificationService::current()->Notify( | 265 NotificationService::current()->Notify( |
266 NotificationType::APP_EXITING, | 266 NotificationType::APP_EXITING, |
267 NotificationService::AllSources(), | 267 NotificationService::AllSources(), |
268 NotificationService::NoDetails()); | 268 NotificationService::NoDetails()); |
269 | 269 |
270 #if !defined(OS_MACOSX) | 270 #if !defined(OS_MACOSX) |
271 // On most platforms, closing all windows causes the application to exit. | 271 // On most platforms, closing all windows causes the application to exit. |
272 CloseAllBrowsers(); | 272 CloseAllBrowsers(); |
273 #else | 273 #else |
274 // On the Mac, the application continues to run once all windows are closed. | 274 // On the Mac, the application continues to run once all windows are closed. |
275 // Terminate will result in a CloseAllBrowsers() call, and once (and if) | 275 // Terminate will result in a CloseAllBrowsers() call, and once (and if) |
276 // that is done, will cause the application to exit cleanly. | 276 // that is done, will cause the application to exit cleanly. |
277 chrome_browser_application_mac::Terminate(); | 277 chrome_browser_application_mac::Terminate(); |
278 #endif | 278 #endif |
279 } | 279 } |
280 | 280 |
281 // static | 281 // static |
282 void BrowserList::NotifyAndTerminate(bool fast_path) { | 282 void BrowserList::NotifyAndTerminate(bool fast_path) { |
283 #if defined(OS_CHROMEOS) | 283 #if defined(OS_CHROMEOS) |
284 if (!signout) return; | 284 if (!signout) |
285 NotifyWindowManagerAboutSignout(); | 285 return; |
286 #endif | 286 #endif |
287 | 287 |
288 if (fast_path) { | 288 if (fast_path) { |
289 NotificationService::current()->Notify(NotificationType::APP_TERMINATING, | 289 NotificationService::current()->Notify(NotificationType::APP_TERMINATING, |
290 NotificationService::AllSources(), | 290 NotificationService::AllSources(), |
291 NotificationService::NoDetails()); | 291 NotificationService::NoDetails()); |
292 } | 292 } |
293 | 293 |
294 #if defined(OS_CHROMEOS) | 294 #if defined(OS_CHROMEOS) |
295 NotifyWindowManagerAboutSignout(); | |
295 chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); | 296 chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); |
296 if (cros_library->EnsureLoaded()) { | 297 if (cros_library->EnsureLoaded()) { |
297 // If update has been installed, reboot, otherwise, sign out. | 298 // If update has been installed, reboot, otherwise, sign out. |
298 if (cros_library->GetUpdateLibrary()->status().status == | 299 if (cros_library->GetUpdateLibrary()->status().status == |
299 chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT) { | 300 chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT) { |
300 cros_library->GetUpdateLibrary()->RebootAfterUpdate(); | 301 cros_library->GetUpdateLibrary()->RebootAfterUpdate(); |
301 } else { | 302 } else { |
302 cros_library->GetLoginLibrary()->StopSession(""); | 303 cros_library->GetLoginLibrary()->StopSession(""); |
303 } | 304 } |
304 return; | 305 return; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 } | 363 } |
363 | 364 |
364 // static | 365 // static |
365 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { | 366 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { |
366 observers_.RemoveObserver(observer); | 367 observers_.RemoveObserver(observer); |
367 } | 368 } |
368 | 369 |
369 // static | 370 // static |
370 void BrowserList::CloseAllBrowsers() { | 371 void BrowserList::CloseAllBrowsers() { |
371 bool session_ending = | 372 bool session_ending = |
372 browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION; | 373 browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION; |
achuithb
2011/06/29 20:46:57
session_ending is true when this function is calle
| |
373 bool force_exit = false; | 374 bool force_exit = false; |
374 #if defined(USE_X11) | 375 #if defined(USE_X11) |
375 if (session_ending) | 376 if (session_ending) |
376 force_exit = true; | 377 force_exit = true; |
achuithb
2011/06/29 20:46:57
force_exit is true
| |
377 #endif | 378 #endif |
378 // Tell everyone that we are shutting down. | 379 // Tell everyone that we are shutting down. |
379 browser_shutdown::SetTryingToQuit(true); | 380 browser_shutdown::SetTryingToQuit(true); |
380 | 381 |
381 // Before we close the browsers shutdown all session services. That way an | 382 // Before we close the browsers shutdown all session services. That way an |
382 // exit can restore all browsers open before exiting. | 383 // exit can restore all browsers open before exiting. |
383 ProfileManager::ShutdownSessionServices(); | 384 ProfileManager::ShutdownSessionServices(); |
384 | 385 |
385 // If there are no browsers, send the APP_TERMINATING action here. Otherwise, | 386 // If there are no browsers, send the APP_TERMINATING action here. Otherwise, |
386 // it will be sent by RemoveBrowser() when the last browser has closed. | 387 // it will be sent by RemoveBrowser() when the last browser has closed. |
387 if (force_exit || browsers_.empty()) { | 388 if (force_exit || browsers_.empty()) { |
388 NotifyAndTerminate(true); | 389 NotifyAndTerminate(true); |
389 return; | 390 return; |
achuithb
2011/06/29 20:46:57
We return here because force_exit is true. None of
| |
390 } | 391 } |
391 #if defined(OS_CHROMEOS) | 392 #if defined(OS_CHROMEOS) |
392 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker( | 393 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker( |
393 "StartedClosingWindows", false); | 394 "StartedClosingWindows", false); |
394 #endif | 395 #endif |
395 for (BrowserList::const_iterator i = BrowserList::begin(); | 396 for (BrowserList::const_iterator i = BrowserList::begin(); |
396 i != BrowserList::end();) { | 397 i != BrowserList::end();) { |
397 Browser* browser = *i; | 398 Browser* browser = *i; |
398 browser->window()->Close(); | 399 browser->window()->Close(); |
399 if (!session_ending) { | 400 if (!session_ending) { |
(...skipping 29 matching lines...) Expand all Loading... | |
429 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted); | 430 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted); |
430 | 431 |
431 // Login screen should show up in owner's locale. | 432 // Login screen should show up in owner's locale. |
432 PrefService* state = g_browser_process->local_state(); | 433 PrefService* state = g_browser_process->local_state(); |
433 if (state) { | 434 if (state) { |
434 std::string owner_locale = state->GetString(prefs::kOwnerLocale); | 435 std::string owner_locale = state->GetString(prefs::kOwnerLocale); |
435 if (!owner_locale.empty() && | 436 if (!owner_locale.empty() && |
436 state->GetString(prefs::kApplicationLocale) != owner_locale && | 437 state->GetString(prefs::kApplicationLocale) != owner_locale && |
437 !state->IsManagedPreference(prefs::kApplicationLocale)) { | 438 !state->IsManagedPreference(prefs::kApplicationLocale)) { |
438 state->SetString(prefs::kApplicationLocale, owner_locale); | 439 state->SetString(prefs::kApplicationLocale, owner_locale); |
439 state->ScheduleSavePersistentPrefs(); | 440 state->SavePersistentPrefs(); |
440 } | 441 } |
441 } | 442 } |
442 if (FastShutdown()) { | 443 if (FastShutdown()) |
443 return; | 444 return; |
444 } | |
445 #else | 445 #else |
446 // Reset the restart bit that might have been set in cancelled restart | 446 // Reset the restart bit that might have been set in cancelled restart |
447 // request. | 447 // request. |
448 PrefService* pref_service = g_browser_process->local_state(); | 448 PrefService* pref_service = g_browser_process->local_state(); |
449 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, false); | 449 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, false); |
450 #endif | 450 #endif |
451 AttemptExitInternal(); | 451 AttemptExitInternal(); |
452 } | 452 } |
453 | 453 |
454 // static | 454 // static |
455 void BrowserList::AttemptRestart() { | 455 void BrowserList::AttemptRestart() { |
456 #if defined(OS_CHROMEOS) | 456 #if defined(OS_CHROMEOS) |
457 // For CrOS instead of browser restart (which is not supported) perform a full | 457 // For CrOS instead of browser restart (which is not supported) perform a full |
458 // sign out. Session will be only restored if user has that setting set. | 458 // sign out. Session will be only restored if user has that setting set. |
459 // Same session restore behavior happens in case of full restart after update. | 459 // Same session restore behavior happens in case of full restart after update. |
460 AttemptUserExit(); | 460 AttemptUserExit(); |
461 #else | 461 #else |
462 // Set the flag to restore state after the restart. | 462 // Set the flag to restore state after the restart. |
463 PrefService* pref_service = g_browser_process->local_state(); | 463 PrefService* pref_service = g_browser_process->local_state(); |
464 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); | 464 pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); |
465 AttemptExit(); | 465 AttemptExit(); |
466 #endif | 466 #endif |
467 } | 467 } |
468 | 468 |
469 // static | 469 // static |
470 void BrowserList::AttemptExit() { | 470 void BrowserList::AttemptExit() { |
471 // If we know that all browsers can be closed without blocking, | 471 // If we know that all browsers can be closed without blocking, |
472 // don't notify users of crashes beyond this point. | 472 // don't notify users of crashes beyond this point. Note that |
473 // Note that MarkAsCleanShutdown does not set UMA's exit cleanly bit | 473 // MarkAsCleanShutdownInUserProfiles does not set UMA's exit cleanly |
474 // so crashes during shutdown are still reported in UMA. | 474 // bit so crashes during shutdown are still reported in UMA. |
475 if (AreAllBrowsersCloseable()) | 475 if (AreAllBrowsersCloseable()) |
476 MarkAsCleanShutdown(); | 476 MarkAsCleanShutdownInUserProfiles(); |
477 AttemptExitInternal(); | 477 AttemptExitInternal(); |
478 } | 478 } |
479 | 479 |
480 #if defined(OS_CHROMEOS) | |
481 // static | |
482 void BrowserList::ExitCleanly() { | |
483 // We always mark exit cleanly. | |
484 MarkAsCleanShutdown(); | |
485 AttemptExitInternal(); | |
486 } | |
487 #endif | |
488 | |
489 // static | 480 // static |
490 void BrowserList::SessionEnding() { | 481 void BrowserList::SessionEnding() { |
491 // EndSession is invoked once per frame. Only do something the first time. | 482 // EndSession is invoked once per frame. Only do something the first time. |
492 static bool already_ended = false; | 483 static bool already_ended = false; |
493 // We may get called in the middle of shutdown, e.g. http://crbug.com/70852 | 484 // We may get called in the middle of shutdown, e.g. http://crbug.com/70852 |
494 // In this case, do nothing. | 485 // In this case, do nothing. |
495 if (already_ended || !NotificationService::current()) | 486 if (already_ended || !NotificationService::current()) |
496 return; | 487 return; |
497 already_ended = true; | 488 already_ended = true; |
498 | 489 |
499 browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION); | 490 browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION); |
achuithb
2011/06/29 20:46:57
We set shutdown_type to END_SESSION here.
| |
500 | 491 |
501 NotificationService::current()->Notify( | 492 NotificationService::current()->Notify( |
502 NotificationType::APP_EXITING, | 493 NotificationType::APP_EXITING, |
503 NotificationService::AllSources(), | 494 NotificationService::AllSources(), |
504 NotificationService::NoDetails()); | 495 NotificationService::NoDetails()); |
505 | 496 |
506 // Write important data first. | 497 // Write important data first. |
507 g_browser_process->EndSession(); | 498 g_browser_process->EndSession(); |
508 | 499 |
509 BrowserList::CloseAllBrowsers(); | 500 BrowserList::CloseAllBrowsers(); |
achuithb
2011/06/29 20:46:57
This doesn't actually close any browser windows, a
| |
510 | 501 |
511 // Send out notification. This is used during testing so that the test harness | 502 // Send out notification. This is used during testing so that the test harness |
512 // can properly shutdown before we exit. | 503 // can properly shutdown before we exit. |
513 NotificationService::current()->Notify( | 504 NotificationService::current()->Notify( |
514 NotificationType::SESSION_END, | 505 NotificationType::SESSION_END, |
515 NotificationService::AllSources(), | 506 NotificationService::AllSources(), |
516 NotificationService::NoDetails()); | 507 NotificationService::NoDetails()); |
517 | 508 |
518 // And shutdown. | 509 // And shutdown. |
519 browser_shutdown::Shutdown(); | 510 browser_shutdown::Shutdown(); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
726 // If no more TabContents from Browsers, check the BackgroundPrintingManager. | 717 // If no more TabContents from Browsers, check the BackgroundPrintingManager. |
727 while (bg_printing_iterator_ != GetBackgroundPrintingManager()->end()) { | 718 while (bg_printing_iterator_ != GetBackgroundPrintingManager()->end()) { |
728 cur_ = *bg_printing_iterator_; | 719 cur_ = *bg_printing_iterator_; |
729 CHECK(cur_); | 720 CHECK(cur_); |
730 ++bg_printing_iterator_; | 721 ++bg_printing_iterator_; |
731 return; | 722 return; |
732 } | 723 } |
733 // Reached the end - no more TabContents. | 724 // Reached the end - no more TabContents. |
734 cur_ = NULL; | 725 cur_ = NULL; |
735 } | 726 } |
OLD | NEW |