Chromium Code Reviews| 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/background/background_mode_manager.h" | 5 #include "chrome/browser/background/background_mode_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 22 #include "base/thread_task_runner_handle.h" | 22 #include "base/thread_task_runner_handle.h" |
| 23 #include "chrome/app/chrome_command_ids.h" | 23 #include "chrome/app/chrome_command_ids.h" |
| 24 #include "chrome/browser/background/background_application_list_model.h" | 24 #include "chrome/browser/background/background_application_list_model.h" |
| 25 #include "chrome/browser/background/background_trigger.h" | 25 #include "chrome/browser/background/background_trigger.h" |
| 26 #include "chrome/browser/browser_process.h" | 26 #include "chrome/browser/browser_process.h" |
| 27 #include "chrome/browser/browser_shutdown.h" | 27 #include "chrome/browser/browser_shutdown.h" |
| 28 #include "chrome/browser/chrome_notification_types.h" | 28 #include "chrome/browser/chrome_notification_types.h" |
| 29 #include "chrome/browser/extensions/extension_service.h" | 29 #include "chrome/browser/extensions/extension_service.h" |
| 30 #include "chrome/browser/lifetime/application_lifetime.h" | 30 #include "chrome/browser/lifetime/application_lifetime.h" |
| 31 #include "chrome/browser/lifetime/browser_keep_alive.h" | |
| 31 #include "chrome/browser/profiles/profile.h" | 32 #include "chrome/browser/profiles/profile.h" |
| 32 #include "chrome/browser/profiles/profile_info_cache.h" | 33 #include "chrome/browser/profiles/profile_info_cache.h" |
| 33 #include "chrome/browser/profiles/profile_manager.h" | 34 #include "chrome/browser/profiles/profile_manager.h" |
| 34 #include "chrome/browser/status_icons/status_icon.h" | 35 #include "chrome/browser/status_icons/status_icon.h" |
| 35 #include "chrome/browser/status_icons/status_tray.h" | 36 #include "chrome/browser/status_icons/status_tray.h" |
| 36 #include "chrome/browser/ui/browser.h" | 37 #include "chrome/browser/ui/browser.h" |
| 37 #include "chrome/browser/ui/browser_commands.h" | 38 #include "chrome/browser/ui/browser_commands.h" |
| 38 #include "chrome/browser/ui/browser_dialogs.h" | 39 #include "chrome/browser/ui/browser_dialogs.h" |
| 39 #include "chrome/browser/ui/browser_finder.h" | 40 #include "chrome/browser/ui/browser_finder.h" |
| 40 #include "chrome/browser/ui/browser_list.h" | 41 #include "chrome/browser/ui/browser_list.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 MENU_ITEM_BACKGROUND_CLIENT = 2, | 115 MENU_ITEM_BACKGROUND_CLIENT = 2, |
| 115 MENU_ITEM_KEEP_RUNNING = 3, | 116 MENU_ITEM_KEEP_RUNNING = 3, |
| 116 MENU_ITEM_EXIT = 4, | 117 MENU_ITEM_EXIT = 4, |
| 117 MENU_ITEM_NUM_STATES | 118 MENU_ITEM_NUM_STATES |
| 118 }; | 119 }; |
| 119 | 120 |
| 120 void RecordMenuItemClick(MenuItem item) { | 121 void RecordMenuItemClick(MenuItem item) { |
| 121 UMA_HISTOGRAM_ENUMERATION("BackgroundMode.MenuItemClick", item, | 122 UMA_HISTOGRAM_ENUMERATION("BackgroundMode.MenuItemClick", item, |
| 122 MENU_ITEM_NUM_STATES); | 123 MENU_ITEM_NUM_STATES); |
| 123 } | 124 } |
| 125 | |
| 126 // Helper function for DecrementKeepAliveCountForStartup() to actually decrement | |
| 127 // the keep alive. | |
| 128 void DoDecrementKeepAliveCountForStartup( | |
| 129 scoped_ptr<browser_lifetime::ScopedKeepAlive> keep_alive) { | |
| 130 keep_alive.reset(); // Explicitly reset(). | |
|
sky
2015/10/07 17:27:24
You don't actually need this.
| |
| 131 } | |
| 132 | |
| 124 } // namespace | 133 } // namespace |
| 125 | 134 |
| 126 BackgroundModeManager::BackgroundModeData::BackgroundModeData( | 135 BackgroundModeManager::BackgroundModeData::BackgroundModeData( |
| 127 Profile* profile, | 136 Profile* profile, |
| 128 CommandIdHandlerVector* command_id_handler_vector) | 137 CommandIdHandlerVector* command_id_handler_vector) |
| 129 : applications_(new BackgroundApplicationListModel(profile)), | 138 : applications_(new BackgroundApplicationListModel(profile)), |
| 130 profile_(profile), | 139 profile_(profile), |
| 131 command_id_handler_vector_(command_id_handler_vector) { | 140 command_id_handler_vector_(command_id_handler_vector) { |
| 132 } | 141 } |
| 133 | 142 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 /////////////////////////////////////////////////////////////////////////////// | 312 /////////////////////////////////////////////////////////////////////////////// |
| 304 // BackgroundModeManager, public | 313 // BackgroundModeManager, public |
| 305 BackgroundModeManager::BackgroundModeManager( | 314 BackgroundModeManager::BackgroundModeManager( |
| 306 const base::CommandLine& command_line, | 315 const base::CommandLine& command_line, |
| 307 ProfileInfoCache* profile_cache) | 316 ProfileInfoCache* profile_cache) |
| 308 : profile_cache_(profile_cache), | 317 : profile_cache_(profile_cache), |
| 309 status_tray_(NULL), | 318 status_tray_(NULL), |
| 310 status_icon_(NULL), | 319 status_icon_(NULL), |
| 311 context_menu_(NULL), | 320 context_menu_(NULL), |
| 312 in_background_mode_(false), | 321 in_background_mode_(false), |
| 313 keep_alive_for_startup_(false), | |
| 314 keep_alive_for_test_(false), | 322 keep_alive_for_test_(false), |
| 315 background_mode_suspended_(false), | 323 background_mode_suspended_(false), |
| 316 keeping_alive_(false), | |
| 317 weak_factory_(this) { | 324 weak_factory_(this) { |
| 318 // We should never start up if there is no browser process or if we are | 325 // We should never start up if there is no browser process or if we are |
| 319 // currently quitting. | 326 // currently quitting. |
| 320 CHECK(g_browser_process != NULL); | 327 CHECK(g_browser_process != NULL); |
| 321 CHECK(!browser_shutdown::IsTryingToQuit()); | 328 CHECK(!browser_shutdown::IsTryingToQuit()); |
| 322 | 329 |
| 323 // Add self as an observer for the profile info cache so we know when profiles | 330 // Add self as an observer for the profile info cache so we know when profiles |
| 324 // are deleted and their names change. | 331 // are deleted and their names change. |
| 325 profile_cache_->AddObserver(this); | 332 profile_cache_->AddObserver(this); |
| 326 | 333 |
| 327 RecordAutoLaunchState(command_line); | 334 RecordAutoLaunchState(command_line); |
| 328 UMA_HISTOGRAM_BOOLEAN("BackgroundMode.OnStartup.IsBackgroundModePrefEnabled", | 335 UMA_HISTOGRAM_BOOLEAN("BackgroundMode.OnStartup.IsBackgroundModePrefEnabled", |
| 329 IsBackgroundModePrefEnabled()); | 336 IsBackgroundModePrefEnabled()); |
| 330 | 337 |
| 331 // Listen for the background mode preference changing. | 338 // Listen for the background mode preference changing. |
| 332 if (g_browser_process->local_state()) { // Skip for unit tests | 339 if (g_browser_process->local_state()) { // Skip for unit tests |
| 333 pref_registrar_.Init(g_browser_process->local_state()); | 340 pref_registrar_.Init(g_browser_process->local_state()); |
| 334 pref_registrar_.Add( | 341 pref_registrar_.Add( |
| 335 prefs::kBackgroundModeEnabled, | 342 prefs::kBackgroundModeEnabled, |
| 336 base::Bind(&BackgroundModeManager::OnBackgroundModeEnabledPrefChanged, | 343 base::Bind(&BackgroundModeManager::OnBackgroundModeEnabledPrefChanged, |
| 337 base::Unretained(this))); | 344 base::Unretained(this))); |
| 338 } | 345 } |
| 339 | 346 |
| 340 // Keep the browser alive until extensions are done loading - this is needed | 347 // Keep the browser alive until extensions are done loading - this is needed |
| 341 // by the --no-startup-window flag. We want to stay alive until we load | 348 // by the --no-startup-window flag. We want to stay alive until we load |
| 342 // extensions, at which point we should either run in background mode (if | 349 // extensions, at which point we should either run in background mode (if |
| 343 // there are background apps) or exit if there are none. | 350 // there are background apps) or exit if there are none. |
| 344 if (command_line.HasSwitch(switches::kNoStartupWindow)) { | 351 if (command_line.HasSwitch(switches::kNoStartupWindow)) { |
| 345 keep_alive_for_startup_ = true; | 352 keep_alive_for_startup_.reset(new browser_lifetime::ScopedKeepAlive); |
| 346 chrome::IncrementKeepAliveCount(); | |
| 347 } else { | 353 } else { |
| 348 // Otherwise, start with background mode suspended in case we're launching | 354 // Otherwise, start with background mode suspended in case we're launching |
| 349 // in a mode that doesn't open a browser window. It will be resumed when the | 355 // in a mode that doesn't open a browser window. It will be resumed when the |
| 350 // first browser window is opened. | 356 // first browser window is opened. |
| 351 SuspendBackgroundMode(); | 357 SuspendBackgroundMode(); |
| 352 } | 358 } |
| 353 | 359 |
| 354 // If the -keep-alive-for-test flag is passed, then always keep chrome running | 360 // If the -keep-alive-for-test flag is passed, then always keep chrome running |
| 355 // in the background until the user explicitly terminates it. | 361 // in the background until the user explicitly terminates it. |
| 356 if (command_line.HasSwitch(switches::kKeepAliveForTest)) | 362 if (command_line.HasSwitch(switches::kKeepAliveForTest)) |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 browser_watcher::ExitFunnel::RecordSingleEvent( | 679 browser_watcher::ExitFunnel::RecordSingleEvent( |
| 674 chrome::kBrowserExitCodesRegistryPath, L"TraybarExit"); | 680 chrome::kBrowserExitCodesRegistryPath, L"TraybarExit"); |
| 675 #endif | 681 #endif |
| 676 content::RecordAction(UserMetricsAction("Exit")); | 682 content::RecordAction(UserMetricsAction("Exit")); |
| 677 chrome::CloseAllBrowsers(); | 683 chrome::CloseAllBrowsers(); |
| 678 break; | 684 break; |
| 679 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { | 685 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { |
| 680 // Background mode must already be enabled (as otherwise this menu would | 686 // Background mode must already be enabled (as otherwise this menu would |
| 681 // not be visible). | 687 // not be visible). |
| 682 DCHECK(IsBackgroundModePrefEnabled()); | 688 DCHECK(IsBackgroundModePrefEnabled()); |
| 683 DCHECK(chrome::WillKeepAlive()); | 689 DCHECK(browser_lifetime::WillKeepAlive()); |
| 684 | 690 |
| 685 RecordMenuItemClick(MENU_ITEM_KEEP_RUNNING); | 691 RecordMenuItemClick(MENU_ITEM_KEEP_RUNNING); |
| 686 | 692 |
| 687 // Set the background mode pref to "disabled" - the resulting notification | 693 // Set the background mode pref to "disabled" - the resulting notification |
| 688 // will result in a call to DisableBackgroundMode(). | 694 // will result in a call to DisableBackgroundMode(). |
| 689 PrefService* service = g_browser_process->local_state(); | 695 PrefService* service = g_browser_process->local_state(); |
| 690 DCHECK(service); | 696 DCHECK(service); |
| 691 service->SetBoolean(prefs::kBackgroundModeEnabled, false); | 697 service->SetBoolean(prefs::kBackgroundModeEnabled, false); |
| 692 break; | 698 break; |
| 693 } | 699 } |
| 694 default: | 700 default: |
| 695 if (bmd) { | 701 if (bmd) { |
| 696 bmd->ExecuteCommand(command_id, event_flags); | 702 bmd->ExecuteCommand(command_id, event_flags); |
| 697 } else { | 703 } else { |
| 698 UserManager::Show(base::FilePath(), | 704 UserManager::Show(base::FilePath(), |
| 699 profiles::USER_MANAGER_NO_TUTORIAL, | 705 profiles::USER_MANAGER_NO_TUTORIAL, |
| 700 profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); | 706 profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); |
| 701 } | 707 } |
| 702 break; | 708 break; |
| 703 } | 709 } |
| 704 } | 710 } |
| 705 | 711 |
| 706 | 712 |
| 707 /////////////////////////////////////////////////////////////////////////////// | 713 /////////////////////////////////////////////////////////////////////////////// |
| 708 // BackgroundModeManager, private | 714 // BackgroundModeManager, private |
| 709 void BackgroundModeManager::DecrementKeepAliveCountForStartup() { | 715 void BackgroundModeManager::DecrementKeepAliveCountForStartup() { |
| 710 if (keep_alive_for_startup_) { | 716 if (keep_alive_for_startup_) { |
| 711 keep_alive_for_startup_ = false; | |
| 712 // We call this via the message queue to make sure we don't try to end | 717 // We call this via the message queue to make sure we don't try to end |
| 713 // keep-alive (which can shutdown Chrome) before the message loop has | 718 // keep-alive (which can shutdown Chrome) before the message loop has |
| 714 // started. | 719 // started. |
| 715 base::ThreadTaskRunnerHandle::Get()->PostTask( | 720 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 716 FROM_HERE, base::Bind(&chrome::DecrementKeepAliveCount)); | 721 FROM_HERE, |
| 722 base::Bind(&DoDecrementKeepAliveCountForStartup, | |
| 723 base::Passed(&keep_alive_for_startup_))); | |
| 717 } | 724 } |
| 718 } | 725 } |
| 719 | 726 |
| 720 void BackgroundModeManager::StartBackgroundMode() { | 727 void BackgroundModeManager::StartBackgroundMode() { |
| 721 DCHECK(ShouldBeInBackgroundMode()); | 728 DCHECK(ShouldBeInBackgroundMode()); |
| 722 // Don't bother putting ourselves in background mode if we're already there | 729 // Don't bother putting ourselves in background mode if we're already there |
| 723 // or if background mode is disabled. | 730 // or if background mode is disabled. |
| 724 if (in_background_mode_) | 731 if (in_background_mode_) |
| 725 return; | 732 return; |
| 726 | 733 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 UpdateKeepAliveAndTrayIcon(); | 792 UpdateKeepAliveAndTrayIcon(); |
| 786 } | 793 } |
| 787 | 794 |
| 788 void BackgroundModeManager::ResumeBackgroundMode() { | 795 void BackgroundModeManager::ResumeBackgroundMode() { |
| 789 background_mode_suspended_ = false; | 796 background_mode_suspended_ = false; |
| 790 UpdateKeepAliveAndTrayIcon(); | 797 UpdateKeepAliveAndTrayIcon(); |
| 791 } | 798 } |
| 792 | 799 |
| 793 void BackgroundModeManager::UpdateKeepAliveAndTrayIcon() { | 800 void BackgroundModeManager::UpdateKeepAliveAndTrayIcon() { |
| 794 if (in_background_mode_ && !background_mode_suspended_) { | 801 if (in_background_mode_ && !background_mode_suspended_) { |
| 795 if (!keeping_alive_) { | 802 if (!keep_alive_for_background_mode_) { |
| 796 keeping_alive_ = true; | 803 keep_alive_for_background_mode_.reset( |
| 797 chrome::IncrementKeepAliveCount(); | 804 new browser_lifetime::ScopedKeepAlive); |
| 798 | 805 |
| 799 #if defined(OS_WIN) | 806 #if defined(OS_WIN) |
| 800 browser_watcher::ExitFunnel::RecordSingleEvent( | 807 browser_watcher::ExitFunnel::RecordSingleEvent( |
| 801 chrome::kBrowserExitCodesRegistryPath, L"BackgroundOn"); | 808 chrome::kBrowserExitCodesRegistryPath, L"BackgroundOn"); |
| 802 #endif | 809 #endif |
| 803 } | 810 } |
| 804 CreateStatusTrayIcon(); | 811 CreateStatusTrayIcon(); |
| 805 return; | 812 return; |
| 806 } | 813 } |
| 807 | 814 |
| 808 RemoveStatusTrayIcon(); | 815 RemoveStatusTrayIcon(); |
| 809 if (keeping_alive_) { | 816 if (keep_alive_for_background_mode_) { |
| 810 keeping_alive_ = false; | 817 keep_alive_for_background_mode_.reset(); |
| 811 chrome::DecrementKeepAliveCount(); | |
| 812 | 818 |
| 813 #if defined(OS_WIN) | 819 #if defined(OS_WIN) |
| 814 browser_watcher::ExitFunnel::RecordSingleEvent( | 820 browser_watcher::ExitFunnel::RecordSingleEvent( |
| 815 chrome::kBrowserExitCodesRegistryPath, L"BackgroundOff"); | 821 chrome::kBrowserExitCodesRegistryPath, L"BackgroundOff"); |
| 816 #endif | 822 #endif |
| 817 } | 823 } |
| 818 } | 824 } |
| 819 | 825 |
| 820 void BackgroundModeManager::OnBrowserAdded(Browser* browser) { | 826 void BackgroundModeManager::OnBrowserAdded(Browser* browser) { |
| 821 ResumeBackgroundMode(); | 827 ResumeBackgroundMode(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 OnBackgroundClientInstalled(name); | 866 OnBackgroundClientInstalled(name); |
| 861 } | 867 } |
| 862 } | 868 } |
| 863 | 869 |
| 864 int BackgroundModeManager::GetBackgroundClientCount() const { | 870 int BackgroundModeManager::GetBackgroundClientCount() const { |
| 865 int count = 0; | 871 int count = 0; |
| 866 // Walk the BackgroundModeData for all profiles and count the number of | 872 // Walk the BackgroundModeData for all profiles and count the number of |
| 867 // clients. | 873 // clients. |
| 868 for (const auto& it : background_mode_data_) | 874 for (const auto& it : background_mode_data_) |
| 869 count += it.second->GetBackgroundClientCount(); | 875 count += it.second->GetBackgroundClientCount(); |
| 870 DCHECK(count >= 0); | 876 DCHECK_GE(count, 0); |
| 871 return count; | 877 return count; |
| 872 } | 878 } |
| 873 | 879 |
| 874 int BackgroundModeManager::GetBackgroundClientCountForProfile( | 880 int BackgroundModeManager::GetBackgroundClientCountForProfile( |
| 875 Profile* const profile) const { | 881 Profile* const profile) const { |
| 876 BackgroundModeManager::BackgroundModeData* bmd = | 882 BackgroundModeManager::BackgroundModeData* bmd = |
| 877 GetBackgroundModeData(profile); | 883 GetBackgroundModeData(profile); |
| 878 if (!bmd) | 884 if (!bmd) |
| 879 return 0; | 885 return 0; |
| 880 return bmd->GetBackgroundClientCount(); | 886 return bmd->GetBackgroundClientCount(); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1043 } | 1049 } |
| 1044 } | 1050 } |
| 1045 return profile_it; | 1051 return profile_it; |
| 1046 } | 1052 } |
| 1047 | 1053 |
| 1048 bool BackgroundModeManager::IsBackgroundModePrefEnabled() const { | 1054 bool BackgroundModeManager::IsBackgroundModePrefEnabled() const { |
| 1049 PrefService* service = g_browser_process->local_state(); | 1055 PrefService* service = g_browser_process->local_state(); |
| 1050 DCHECK(service); | 1056 DCHECK(service); |
| 1051 return service->GetBoolean(prefs::kBackgroundModeEnabled); | 1057 return service->GetBoolean(prefs::kBackgroundModeEnabled); |
| 1052 } | 1058 } |
| OLD | NEW |