Index: chrome/browser/background_mode_manager.cc |
=================================================================== |
--- chrome/browser/background_mode_manager.cc (revision 86725) |
+++ chrome/browser/background_mode_manager.cc (working copy) |
@@ -29,114 +29,26 @@ |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
- |
-BackgroundModeManager::BackgroundModeData::BackgroundModeData( |
- Profile* profile, |
- BackgroundModeManager* background_mode_manager) |
- : applications_(new BackgroundApplicationListModel(profile)), |
- status_icon_(NULL), |
- context_menu_(NULL), |
- context_menu_application_offset_(0), |
- profile_(profile), |
- background_mode_manager_(background_mode_manager) { |
-} |
- |
-BackgroundModeManager::BackgroundModeData::~BackgroundModeData() { |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////// |
-// BackgroundModeManager::BackgroundModeData, ui::SimpleMenuModel overrides |
-bool BackgroundModeManager::BackgroundModeData::IsCommandIdChecked( |
- int command_id) const { |
- DCHECK(command_id == IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); |
- return true; |
-} |
- |
-bool BackgroundModeManager::BackgroundModeData::IsCommandIdEnabled( |
- int command_id) const { |
- // For now, we do not support disabled items. |
- return true; |
-} |
- |
-bool BackgroundModeManager::BackgroundModeData::GetAcceleratorForCommandId( |
- int command_id, ui::Accelerator* accelerator) { |
- // No accelerators for status icon context menus. |
- return false; |
-} |
- |
-void BackgroundModeManager::BackgroundModeData::ExecuteCommand(int item) { |
- switch (item) { |
- case IDC_ABOUT: |
- GetBrowserWindow()->OpenAboutChromeDialog(); |
- break; |
- case IDC_EXIT: |
- UserMetrics::RecordAction(UserMetricsAction("Exit")); |
- BrowserList::CloseAllBrowsersAndExit(); |
- break; |
- case IDC_OPTIONS: |
- GetBrowserWindow()->OpenOptionsDialog(); |
- break; |
- case IDC_TASK_MANAGER: |
- GetBrowserWindow()->OpenTaskManager(true); |
- break; |
- case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { |
- // Background mode must already be enabled (as otherwise this menu would |
- // not be visible). |
- DCHECK(background_mode_manager_->IsBackgroundModePrefEnabled()); |
- DCHECK(BrowserList::WillKeepAlive()); |
- |
- // Set the background mode pref to "disabled" - the resulting notification |
- // will result in a call to DisableBackgroundMode(). |
- PrefService* service = g_browser_process->local_state(); |
- DCHECK(service); |
- service->SetBoolean(prefs::kBackgroundModeEnabled, false); |
- break; |
- } |
- default: |
- ExecuteApplication(item); |
- break; |
- } |
-} |
- |
-void BackgroundModeManager::BackgroundModeData::ExecuteApplication( |
- int item) { |
- Browser* browser = GetBrowserWindow(); |
- const Extension* extension = applications_->GetExtension(item); |
- browser->OpenApplicationTab(profile_, extension, NEW_FOREGROUND_TAB); |
-} |
- |
-Browser* BackgroundModeManager::BackgroundModeData::GetBrowserWindow() { |
- Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); |
- if (!browser) { |
- Browser::OpenEmptyWindow(profile_); |
- browser = BrowserList::GetLastActiveWithProfile(profile_); |
- } |
- return browser; |
-} |
- |
-void BackgroundModeManager::BackgroundModeData::UpdateContextMenuEntryIcon( |
+void BackgroundModeManager::OnApplicationDataChanged( |
const Extension* extension) { |
- if (!context_menu_) |
- return; |
- context_menu_->SetIcon( |
- context_menu_application_offset_ + |
- applications_->GetPosition(extension), |
- *(applications_->GetIcon(extension))); |
- |
- status_icon_->SetContextMenu(context_menu_); // for Update effect |
+ UpdateContextMenuEntryIcon(extension); |
} |
-bool BackgroundModeManager::BackgroundModeData::HasBackgroundApp() { |
- return (applications_->size() > 0); |
+void BackgroundModeManager::OnApplicationListChanged() { |
+ UpdateStatusTrayIconContextMenu(); |
} |
-/////////////////////////////////////////////////////////////////////////////// |
-// BackgroundModeManager, public |
-BackgroundModeManager::BackgroundModeManager(CommandLine* command_line) |
- : status_tray_(NULL), |
+BackgroundModeManager::BackgroundModeManager(Profile* profile, |
+ CommandLine* command_line) |
+ : profile_(profile), |
+ applications_(profile), |
background_app_count_(0), |
+ context_menu_(NULL), |
+ context_menu_application_offset_(0), |
in_background_mode_(false), |
- keep_alive_for_startup_(false) { |
+ keep_alive_for_startup_(false), |
+ status_tray_(NULL), |
+ status_icon_(NULL) { |
// If background mode is currently disabled, just exit - don't listen for any |
// notifications. |
if (IsBackgroundModePermanentlyDisabled(command_line)) |
@@ -160,43 +72,9 @@ |
// If the -keep-alive-for-test flag is passed, then always keep chrome running |
// in the background until the user explicitly terminates it, by acting as if |
// we loaded a background app. |
- if (command_line->HasSwitch(switches::kKeepAliveForTest)) |
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKeepAliveForTest)) |
OnBackgroundAppLoaded(); |
- // Listen for the application shutting down so we can decrement our KeepAlive |
- // count. |
- registrar_.Add(this, NotificationType::APP_TERMINATING, |
- NotificationService::AllSources()); |
-} |
- |
-BackgroundModeManager::~BackgroundModeManager() { |
- for (std::map<Profile*, BackgroundModeInfo>::iterator it = |
- background_mode_data_.begin(); |
- it != background_mode_data_.end(); |
- ++it) { |
- it->second->applications_->RemoveObserver(this); |
- } |
- |
- // We're going away, so exit background mode (does nothing if we aren't in |
- // background mode currently). This is primarily needed for unit tests, |
- // because in an actual running system we'd get an APP_TERMINATING |
- // notification before being destroyed. |
- EndBackgroundMode(); |
-} |
- |
-// static |
-void BackgroundModeManager::RegisterPrefs(PrefService* prefs) { |
- prefs->RegisterBooleanPref(prefs::kUserCreatedLoginItem, false); |
- prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true); |
-} |
- |
- |
-void BackgroundModeManager::RegisterProfile(Profile* profile) { |
- // We don't want to register multiple times for one profile. |
- DCHECK(background_mode_data_.find(profile) == background_mode_data_.end()); |
- BackgroundModeInfo bmd(new BackgroundModeData(profile, this)); |
- background_mode_data_[profile] = bmd; |
- |
// Listen for when extensions are loaded/unloaded so we can track the |
// number of background apps and modify our keep-alive and launch-on-startup |
// state appropriately. |
@@ -211,11 +89,24 @@ |
registrar_.Add(this, NotificationType::EXTENSIONS_READY, |
Source<Profile>(profile)); |
- background_mode_data_[profile]->applications_->AddObserver(this); |
+ // Listen for the application shutting down so we can decrement our KeepAlive |
+ // count. |
+ registrar_.Add(this, NotificationType::APP_TERMINATING, |
+ NotificationService::AllSources()); |
+ |
+ applications_.AddObserver(this); |
} |
-/////////////////////////////////////////////////////////////////////////////// |
-// BackgroundModeManager, NotificationObserver overrides |
+BackgroundModeManager::~BackgroundModeManager() { |
+ applications_.RemoveObserver(this); |
+ |
+ // We're going away, so exit background mode (does nothing if we aren't in |
+ // background mode currently). This is primarily needed for unit tests, |
+ // because in an actual running system we'd get an APP_TERMINATING |
+ // notification before being destroyed. |
+ EndBackgroundMode(); |
+} |
+ |
void BackgroundModeManager::Observe(NotificationType type, |
const NotificationSource& source, |
const NotificationDetails& details) { |
@@ -248,9 +139,8 @@ |
if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) { |
// Extensions loaded after the ExtensionsService is ready should be |
// treated as new installs. |
- Profile* profile = Source<Profile>(source).ptr(); |
- if (profile->GetExtensionService()->is_ready()) |
- OnBackgroundAppInstalled(extension, profile); |
+ if (profile_->GetExtensionService()->is_ready()) |
+ OnBackgroundAppInstalled(extension); |
OnBackgroundAppLoaded(); |
} |
} |
@@ -267,8 +157,7 @@ |
if (info->already_disabled) |
return; |
OnBackgroundAppUnloaded(); |
- Profile* profile = Source<Profile>(source).ptr(); |
- OnBackgroundAppUninstalled(profile); |
+ OnBackgroundAppUninstalled(); |
} |
break; |
case NotificationType::APP_TERMINATING: |
@@ -288,20 +177,6 @@ |
} |
} |
-/////////////////////////////////////////////////////////////////////////////// |
-// BackgroundModeManager, BackgroundApplicationListModel::Observer overrides |
-void BackgroundModeManager::OnApplicationDataChanged( |
- const Extension* extension, Profile* profile) { |
- UpdateContextMenuEntryIcon(extension, profile); |
-} |
- |
-void BackgroundModeManager::OnApplicationListChanged(Profile* profile) { |
- UpdateStatusTrayIconContextMenu(profile); |
-} |
- |
- |
-/////////////////////////////////////////////////////////////////////////////// |
-// BackgroundModeManager, private |
void BackgroundModeManager::EndKeepAliveForStartup() { |
if (keep_alive_for_startup_) { |
keep_alive_for_startup_ = false; |
@@ -316,8 +191,6 @@ |
void BackgroundModeManager::OnBackgroundAppLoaded() { |
// When a background app loads, increment our count and also enable |
// KeepAlive mode if the preference is set. |
- // The count here is across all profiles since we must have background |
- // mode if there is even one. |
background_app_count_++; |
if (background_app_count_ == 1) |
StartBackgroundMode(); |
@@ -336,21 +209,9 @@ |
BrowserList::StartKeepAlive(); |
// Display a status icon to exit Chrome. |
- InitStatusTrayIcons(); |
+ CreateStatusTrayIcon(); |
} |
-void BackgroundModeManager::InitStatusTrayIcons() { |
- // Only initialize status tray icons for those profiles which actually |
- // have a background app running. |
- for (std::map<Profile*, BackgroundModeInfo>::iterator it = |
- background_mode_data_.begin(); |
- it != background_mode_data_.end(); |
- ++it) { |
- if (it->second->HasBackgroundApp()) |
- CreateStatusTrayIcon(it->first); |
- } |
-} |
- |
void BackgroundModeManager::OnBackgroundAppUnloaded() { |
// When a background app unloads, decrement our count and also end |
// KeepAlive mode if appropriate. |
@@ -367,13 +228,7 @@ |
// End KeepAlive mode and blow away our status tray icon. |
BrowserList::EndKeepAlive(); |
- // There is a status tray icon for each profile. Blow them all away. |
- for (std::map<Profile*, BackgroundModeInfo>::iterator it = |
- background_mode_data_.begin(); |
- it != background_mode_data_.end(); |
- ++it) { |
- RemoveStatusTrayIcon(it->first); |
- } |
+ RemoveStatusTrayIcon(); |
} |
void BackgroundModeManager::EnableBackgroundMode() { |
@@ -395,7 +250,7 @@ |
} |
void BackgroundModeManager::OnBackgroundAppInstalled( |
- const Extension* extension, Profile* profile) { |
+ const Extension* extension) { |
// Background mode is disabled - don't do anything. |
if (!IsBackgroundModePrefEnabled()) |
return; |
@@ -405,84 +260,58 @@ |
if (background_app_count_ == 0) |
EnableLaunchOnStartup(true); |
- // Check if we need a status tray icon and make one if we do. |
- CreateStatusTrayIcon(profile); |
- |
// Notify the user that a background app has been installed. |
if (extension) // NULL when called by unit tests. |
- DisplayAppInstalledNotification(extension, profile); |
+ DisplayAppInstalledNotification(extension); |
} |
-void BackgroundModeManager::OnBackgroundAppUninstalled(Profile* profile) { |
- // Check if we need to remove the status tray icon if there are no |
- // more background apps. |
- BackgroundModeInfo bmd = GetBackgroundModeInfo(profile); |
- DCHECK(bmd.get()); |
- // If there are still background apps for this profile, don't remove |
- // the status tray icon. |
- if (!bmd->HasBackgroundApp()) |
- RemoveStatusTrayIcon(profile); |
- |
+void BackgroundModeManager::OnBackgroundAppUninstalled() { |
// When uninstalling a background app, disable launch on startup if |
// we have no more background apps. |
if (background_app_count_ == 0) |
EnableLaunchOnStartup(false); |
} |
-void BackgroundModeManager::CreateStatusTrayIcon(Profile* profile) { |
+void BackgroundModeManager::CreateStatusTrayIcon() { |
// Only need status icons on windows/linux. ChromeOS doesn't allow exiting |
// Chrome and Mac can use the dock icon instead. |
- |
- // Since there are multiple profiles which share the status tray, we now |
- // use the browser process to keep track of it. |
#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) |
if (!status_tray_) |
- status_tray_ = g_browser_process->status_tray(); |
+ status_tray_ = profile_->GetStatusTray(); |
#endif |
// If the platform doesn't support status icons, or we've already created |
// our status icon, just return. |
- BackgroundModeInfo bmd = GetBackgroundModeInfo(profile); |
- if (!status_tray_ || bmd->status_icon_) |
+ if (!status_tray_ || status_icon_) |
return; |
- |
- bmd->status_icon_ = status_tray_->CreateStatusIcon(); |
- if (!bmd->status_icon_) |
+ status_icon_ = status_tray_->CreateStatusIcon(); |
+ if (!status_icon_) |
return; |
- // Set the image and add ourselves as a click observer on it. |
- // TODO(rlp): Status tray icon should have submenus for each profile. |
+ // Set the image and add ourselves as a click observer on it |
SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
IDR_STATUS_TRAY_ICON); |
- bmd->status_icon_->SetImage(*bitmap); |
- bmd->status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); |
- UpdateStatusTrayIconContextMenu(profile); |
+ status_icon_->SetImage(*bitmap); |
+ status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); |
+ UpdateStatusTrayIconContextMenu(); |
} |
void BackgroundModeManager::UpdateContextMenuEntryIcon( |
- const Extension* extension, Profile* profile) { |
- BackgroundModeInfo bmd = GetBackgroundModeInfo(profile); |
- DCHECK(bmd.get()); |
- bmd->UpdateContextMenuEntryIcon(extension); |
+ const Extension* extension) { |
+ if (!context_menu_) |
+ return; |
+ context_menu_->SetIcon( |
+ context_menu_application_offset_ + applications_.GetPosition(extension), |
+ *(applications_.GetIcon(extension))); |
+ status_icon_->SetContextMenu(context_menu_); // for Update effect |
} |
-void BackgroundModeManager::UpdateStatusTrayIconContextMenu(Profile* profile) { |
- BackgroundModeInfo bmd = GetBackgroundModeInfo(profile); |
- DCHECK(bmd.get()); |
- if (!bmd->status_icon_) { |
- // If no status icon exists, it's either because one wasn't created when |
- // it should have been which can happen when extensions load after the |
- // profile has already been registered with the background mode manager. |
- // The other case is if we aren't in background mode. |
- if (in_background_mode_) |
- CreateStatusTrayIcon(profile); |
- else |
- return; |
- } |
+void BackgroundModeManager::UpdateStatusTrayIconContextMenu() { |
+ if (!status_icon_) |
+ return; |
- // TODO(rlp): Add current profile color. |
// Create a context menu item for Chrome. |
- ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(bmd.get()); |
+ ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(this); |
// Add About item |
menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT, |
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
@@ -490,43 +319,105 @@ |
menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); |
menu->AddSeparator(); |
int position = 0; |
- bmd->context_menu_application_offset_ = menu->GetItemCount(); |
- for (ExtensionList::const_iterator cursor = bmd->applications_->begin(); |
- cursor != bmd->applications_->end(); |
+ context_menu_application_offset_ = menu->GetItemCount(); |
+ for (ExtensionList::const_iterator cursor = applications_.begin(); |
+ cursor != applications_.end(); |
++cursor, ++position) { |
- const SkBitmap* icon = bmd->applications_->GetIcon(*cursor); |
- DCHECK(position == bmd->applications_->GetPosition(*cursor)); |
+ const SkBitmap* icon = applications_.GetIcon(*cursor); |
+ DCHECK(position == applications_.GetPosition(*cursor)); |
const std::string& name = (*cursor)->name(); |
menu->AddItem(position, UTF8ToUTF16(name)); |
if (icon) |
menu->SetIcon(menu->GetItemCount() - 1, *icon); |
} |
- if (bmd->applications_->size() > 0) |
+ if (applications_.size() > 0) |
menu->AddSeparator(); |
menu->AddCheckItemWithStringId( |
IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND, |
IDS_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); |
menu->AddItemWithStringId(IDC_EXIT, IDS_EXIT); |
- bmd->context_menu_ = menu; |
- bmd->status_icon_->SetContextMenu(menu); |
+ context_menu_ = menu; |
+ status_icon_->SetContextMenu(menu); |
} |
-void BackgroundModeManager::RemoveStatusTrayIcon(Profile* profile) { |
- BackgroundModeInfo bmd = GetBackgroundModeInfo(profile); |
- DCHECK(bmd.get()); |
+bool BackgroundModeManager::IsCommandIdChecked(int command_id) const { |
+ DCHECK(command_id == IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); |
+ return true; |
+} |
- if (bmd->status_icon_) |
- status_tray_->RemoveStatusIcon(bmd->status_icon_); |
- bmd->status_icon_ = NULL; |
- bmd->context_menu_ = NULL; // Do not delete, points within |status_icon_|. |
+bool BackgroundModeManager::IsCommandIdEnabled(int command_id) const { |
+ // For now, we do not support disabled items. |
+ return true; |
} |
-BackgroundModeManager::BackgroundModeInfo |
-BackgroundModeManager::GetBackgroundModeInfo(Profile* profile) { |
- DCHECK(background_mode_data_.find(profile) != background_mode_data_.end()); |
- return background_mode_data_[profile]; |
+bool BackgroundModeManager::GetAcceleratorForCommandId( |
+ int command_id, |
+ ui::Accelerator* accelerator) { |
+ // No accelerators for status icon context menus. |
+ return false; |
} |
+void BackgroundModeManager::RemoveStatusTrayIcon() { |
+ if (status_icon_) |
+ status_tray_->RemoveStatusIcon(status_icon_); |
+ status_icon_ = NULL; |
+ context_menu_ = NULL; // Do not delete, points within |status_icon_|. |
+} |
+ |
+void BackgroundModeManager::ExecuteApplication(int item) { |
+ DCHECK(item >= 0 && item < static_cast<int>(applications_.size())); |
+ Browser* browser = BrowserList::GetLastActive(); |
+ if (!browser) { |
+ Browser::OpenEmptyWindow(profile_); |
+ browser = BrowserList::GetLastActive(); |
+ } |
+ const Extension* extension = applications_.GetExtension(item); |
+ browser->OpenApplicationTab(profile_, extension, NEW_FOREGROUND_TAB); |
+} |
+ |
+void BackgroundModeManager::ExecuteCommand(int item) { |
+ switch (item) { |
+ case IDC_ABOUT: |
+ GetBrowserWindow()->OpenAboutChromeDialog(); |
+ break; |
+ case IDC_EXIT: |
+ UserMetrics::RecordAction(UserMetricsAction("Exit")); |
+ BrowserList::CloseAllBrowsersAndExit(); |
+ break; |
+ case IDC_OPTIONS: |
+ GetBrowserWindow()->OpenOptionsDialog(); |
+ break; |
+ case IDC_TASK_MANAGER: |
+ GetBrowserWindow()->OpenTaskManager(true); |
+ break; |
+ case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { |
+ // Background mode must already be enabled (as otherwise this menu would |
+ // not be visible). |
+ DCHECK(IsBackgroundModePrefEnabled()); |
+ DCHECK(BrowserList::WillKeepAlive()); |
+ |
+ // Set the background mode pref to "disabled" - the resulting notification |
+ // will result in a call to DisableBackgroundMode(). |
+ PrefService* service = g_browser_process->local_state(); |
+ DCHECK(service); |
+ service->SetBoolean(prefs::kBackgroundModeEnabled, false); |
+ break; |
+ } |
+ default: |
+ ExecuteApplication(item); |
+ break; |
+ } |
+} |
+ |
+Browser* BackgroundModeManager::GetBrowserWindow() { |
+ Browser* browser = BrowserList::GetLastActive(); |
+ if (!browser) { |
+ Browser::OpenEmptyWindow(profile_); |
+ browser = BrowserList::GetLastActive(); |
+ } |
+ return browser; |
+} |
+ |
// static |
bool BackgroundModeManager::IsBackgroundModePermanentlyDisabled( |
const CommandLine* command_line) { |
@@ -549,4 +440,10 @@ |
PrefService* service = g_browser_process->local_state(); |
DCHECK(service); |
return service->GetBoolean(prefs::kBackgroundModeEnabled); |
-} |
+} |
+ |
+// static |
+void BackgroundModeManager::RegisterPrefs(PrefService* prefs) { |
+ prefs->RegisterBooleanPref(prefs::kUserCreatedLoginItem, false); |
+ prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true); |
+} |