| Index: chrome/browser/background_mode_manager.cc
 | 
| ===================================================================
 | 
| --- chrome/browser/background_mode_manager.cc	(revision 86624)
 | 
| +++ chrome/browser/background_mode_manager.cc	(working copy)
 | 
| @@ -29,26 +29,114 @@
 | 
|  #include "ui/base/l10n/l10n_util.h"
 | 
|  #include "ui/base/resource/resource_bundle.h"
 | 
|  
 | 
| -void BackgroundModeManager::OnApplicationDataChanged(
 | 
| +
 | 
| +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(
 | 
|      const Extension* extension) {
 | 
| -  UpdateContextMenuEntryIcon(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::OnApplicationListChanged() {
 | 
| -  UpdateStatusTrayIconContextMenu();
 | 
| +bool BackgroundModeManager::BackgroundModeData::HasBackgroundApp() {
 | 
| +  return (applications_->size() > 0);
 | 
|  }
 | 
|  
 | 
| -BackgroundModeManager::BackgroundModeManager(Profile* profile,
 | 
| -                                             CommandLine* command_line)
 | 
| -    : profile_(profile),
 | 
| -      applications_(profile),
 | 
| +///////////////////////////////////////////////////////////////////////////////
 | 
| +//  BackgroundModeManager, public
 | 
| +BackgroundModeManager::BackgroundModeManager(CommandLine* command_line)
 | 
| +    : status_tray_(NULL),
 | 
|        background_app_count_(0),
 | 
| -      context_menu_(NULL),
 | 
| -      context_menu_application_offset_(0),
 | 
|        in_background_mode_(false),
 | 
| -      keep_alive_for_startup_(false),
 | 
| -      status_tray_(NULL),
 | 
| -      status_icon_(NULL) {
 | 
| +      keep_alive_for_startup_(false) {
 | 
|    // If background mode is currently disabled, just exit - don't listen for any
 | 
|    // notifications.
 | 
|    if (IsBackgroundModePermanentlyDisabled(command_line))
 | 
| @@ -72,9 +160,43 @@
 | 
|    // 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 (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKeepAliveForTest))
 | 
| +  if (command_line->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.
 | 
| @@ -89,24 +211,11 @@
 | 
|    registrar_.Add(this, NotificationType::EXTENSIONS_READY,
 | 
|                   Source<Profile>(profile));
 | 
|  
 | 
| -  // Listen for the application shutting down so we can decrement our KeepAlive
 | 
| -  // count.
 | 
| -  registrar_.Add(this, NotificationType::APP_TERMINATING,
 | 
| -                 NotificationService::AllSources());
 | 
| -
 | 
| -  applications_.AddObserver(this);
 | 
| +  background_mode_data_[profile]->applications_->AddObserver(this);
 | 
|  }
 | 
|  
 | 
| -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();
 | 
| -}
 | 
| -
 | 
| +///////////////////////////////////////////////////////////////////////////////
 | 
| +//  BackgroundModeManager, NotificationObserver overrides
 | 
|  void BackgroundModeManager::Observe(NotificationType type,
 | 
|                                      const NotificationSource& source,
 | 
|                                      const NotificationDetails& details) {
 | 
| @@ -139,8 +248,9 @@
 | 
|          if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) {
 | 
|            // Extensions loaded after the ExtensionsService is ready should be
 | 
|            // treated as new installs.
 | 
| -          if (profile_->GetExtensionService()->is_ready())
 | 
| -            OnBackgroundAppInstalled(extension);
 | 
| +          Profile* profile = Source<Profile>(source).ptr();
 | 
| +          if (profile->GetExtensionService()->is_ready())
 | 
| +            OnBackgroundAppInstalled(extension, profile);
 | 
|            OnBackgroundAppLoaded();
 | 
|          }
 | 
|        }
 | 
| @@ -157,7 +267,8 @@
 | 
|          if (info->already_disabled)
 | 
|            return;
 | 
|          OnBackgroundAppUnloaded();
 | 
| -        OnBackgroundAppUninstalled();
 | 
| +        Profile* profile = Source<Profile>(source).ptr();
 | 
| +        OnBackgroundAppUninstalled(profile);
 | 
|        }
 | 
|        break;
 | 
|      case NotificationType::APP_TERMINATING:
 | 
| @@ -177,6 +288,20 @@
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +///////////////////////////////////////////////////////////////////////////////
 | 
| +//  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;
 | 
| @@ -191,6 +316,8 @@
 | 
|  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();
 | 
| @@ -209,9 +336,21 @@
 | 
|    BrowserList::StartKeepAlive();
 | 
|  
 | 
|    // Display a status icon to exit Chrome.
 | 
| -  CreateStatusTrayIcon();
 | 
| +  InitStatusTrayIcons();
 | 
|  }
 | 
|  
 | 
| +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.
 | 
| @@ -228,7 +367,13 @@
 | 
|  
 | 
|    // End KeepAlive mode and blow away our status tray icon.
 | 
|    BrowserList::EndKeepAlive();
 | 
| -  RemoveStatusTrayIcon();
 | 
| +  // 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);
 | 
| +  }
 | 
|  }
 | 
|  
 | 
|  void BackgroundModeManager::EnableBackgroundMode() {
 | 
| @@ -250,7 +395,7 @@
 | 
|  }
 | 
|  
 | 
|  void BackgroundModeManager::OnBackgroundAppInstalled(
 | 
| -    const Extension* extension) {
 | 
| +    const Extension* extension, Profile* profile) {
 | 
|    // Background mode is disabled - don't do anything.
 | 
|    if (!IsBackgroundModePrefEnabled())
 | 
|      return;
 | 
| @@ -260,58 +405,84 @@
 | 
|    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);
 | 
| +    DisplayAppInstalledNotification(extension, profile);
 | 
|  }
 | 
|  
 | 
| -void BackgroundModeManager::OnBackgroundAppUninstalled() {
 | 
| +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);
 | 
| +
 | 
|    // 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() {
 | 
| +void BackgroundModeManager::CreateStatusTrayIcon(Profile* profile) {
 | 
|    // 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_ = profile_->GetStatusTray();
 | 
| +    status_tray_ = g_browser_process->status_tray();
 | 
|  #endif
 | 
|  
 | 
|    // If the platform doesn't support status icons, or we've already created
 | 
|    // our status icon, just return.
 | 
| -  if (!status_tray_ || status_icon_)
 | 
| +  BackgroundModeInfo bmd = GetBackgroundModeInfo(profile);
 | 
| +  if (!status_tray_ || bmd->status_icon_)
 | 
|      return;
 | 
| -  status_icon_ = status_tray_->CreateStatusIcon();
 | 
| -  if (!status_icon_)
 | 
| +
 | 
| +  bmd->status_icon_ = status_tray_->CreateStatusIcon();
 | 
| +  if (!bmd->status_icon_)
 | 
|      return;
 | 
|  
 | 
| -  // Set the image and add ourselves as a click observer on it
 | 
| +  // Set the image and add ourselves as a click observer on it.
 | 
| +  // TODO(rlp): Status tray icon should have submenus for each profile.
 | 
|    SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
 | 
|        IDR_STATUS_TRAY_ICON);
 | 
| -  status_icon_->SetImage(*bitmap);
 | 
| -  status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
 | 
| -  UpdateStatusTrayIconContextMenu();
 | 
| +  bmd->status_icon_->SetImage(*bitmap);
 | 
| +  bmd->status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
 | 
| +  UpdateStatusTrayIconContextMenu(profile);
 | 
|  }
 | 
|  
 | 
|  void BackgroundModeManager::UpdateContextMenuEntryIcon(
 | 
| -    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
 | 
| +    const Extension* extension, Profile* profile) {
 | 
| +  BackgroundModeInfo bmd = GetBackgroundModeInfo(profile);
 | 
| +  DCHECK(bmd.get());
 | 
| +  bmd->UpdateContextMenuEntryIcon(extension);
 | 
|  }
 | 
|  
 | 
| -void BackgroundModeManager::UpdateStatusTrayIconContextMenu() {
 | 
| -  if (!status_icon_)
 | 
| -    return;
 | 
| +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;
 | 
| +  }
 | 
|  
 | 
| +  // TODO(rlp): Add current profile color.
 | 
|    // Create a context menu item for Chrome.
 | 
| -  ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(this);
 | 
| +  ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(bmd.get());
 | 
|    // Add About item
 | 
|    menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT,
 | 
|        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
 | 
| @@ -319,105 +490,43 @@
 | 
|    menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
 | 
|    menu->AddSeparator();
 | 
|    int position = 0;
 | 
| -  context_menu_application_offset_ = menu->GetItemCount();
 | 
| -  for (ExtensionList::const_iterator cursor = applications_.begin();
 | 
| -       cursor != applications_.end();
 | 
| +  bmd->context_menu_application_offset_ = menu->GetItemCount();
 | 
| +  for (ExtensionList::const_iterator cursor = bmd->applications_->begin();
 | 
| +       cursor != bmd->applications_->end();
 | 
|         ++cursor, ++position) {
 | 
| -    const SkBitmap* icon = applications_.GetIcon(*cursor);
 | 
| -    DCHECK(position == applications_.GetPosition(*cursor));
 | 
| +    const SkBitmap* icon = bmd->applications_->GetIcon(*cursor);
 | 
| +    DCHECK(position == bmd->applications_->GetPosition(*cursor));
 | 
|      const std::string& name = (*cursor)->name();
 | 
|      menu->AddItem(position, UTF8ToUTF16(name));
 | 
|      if (icon)
 | 
|        menu->SetIcon(menu->GetItemCount() - 1, *icon);
 | 
|    }
 | 
| -  if (applications_.size() > 0)
 | 
| +  if (bmd->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);
 | 
| -  context_menu_ = menu;
 | 
| -  status_icon_->SetContextMenu(menu);
 | 
| +  bmd->context_menu_ = menu;
 | 
| +  bmd->status_icon_->SetContextMenu(menu);
 | 
|  }
 | 
|  
 | 
| -bool BackgroundModeManager::IsCommandIdChecked(int command_id) const {
 | 
| -  DCHECK(command_id == IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND);
 | 
| -  return true;
 | 
| -}
 | 
| +void BackgroundModeManager::RemoveStatusTrayIcon(Profile* profile) {
 | 
| +  BackgroundModeInfo bmd = GetBackgroundModeInfo(profile);
 | 
| +  DCHECK(bmd.get());
 | 
|  
 | 
| -bool BackgroundModeManager::IsCommandIdEnabled(int command_id) const {
 | 
| -  // For now, we do not support disabled items.
 | 
| -  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::GetAcceleratorForCommandId(
 | 
| -    int command_id,
 | 
| -    ui::Accelerator* accelerator) {
 | 
| -  // No accelerators for status icon context menus.
 | 
| -  return false;
 | 
| +BackgroundModeManager::BackgroundModeInfo
 | 
| +BackgroundModeManager::GetBackgroundModeInfo(Profile* profile) {
 | 
| +  DCHECK(background_mode_data_.find(profile) != background_mode_data_.end());
 | 
| +  return background_mode_data_[profile];
 | 
|  }
 | 
|  
 | 
| -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) {
 | 
| @@ -440,10 +549,4 @@
 | 
|    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);
 | 
| -}
 | 
| +}
 | 
| 
 |