summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-18 20:55:45 +0000
committeratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-18 20:55:45 +0000
commit4c793f0298cbafa6826ef1bc2d85d92bf64320ba (patch)
tree5e6e6a34051417ee4c6847f397713c5d56e99d0d
parent0906270c4485c74cf35fed76aee21458702ce68c (diff)
downloadchromium_src-4c793f0298cbafa6826ef1bc2d85d92bf64320ba.zip
chromium_src-4c793f0298cbafa6826ef1bc2d85d92bf64320ba.tar.gz
chromium_src-4c793f0298cbafa6826ef1bc2d85d92bf64320ba.tar.bz2
Added BackgroundModeManager which tracks when background apps are loaded/unloaded
and puts Chrome into BackgroundMode appropriately. Added EXTENSION_UNINSTALLING notification which is sent out when a notification is about to be uninstalled. Refactored StatusTray code to move StatusTray under the profile rather than attaching it to the browser process, and removed StatusTrayManager which is no longer needed now that BackgroundModeManager handles creating status icons. BUG=43382 TEST=background_mode_manager_unittests.cc Review URL: http://codereview.chromium.org/3134011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56596 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/background_contents_service.cc16
-rw-r--r--chrome/browser/background_contents_service.h4
-rw-r--r--chrome/browser/background_mode_manager.cc201
-rw-r--r--chrome/browser/background_mode_manager.h117
-rw-r--r--chrome/browser/background_mode_manager_unittest.cc46
-rw-r--r--chrome/browser/browser_init.cc9
-rw-r--r--chrome/browser/browser_prefs.cc2
-rw-r--r--chrome/browser/browser_process.h5
-rw-r--r--chrome/browser/browser_process_impl.cc13
-rw-r--r--chrome/browser/browser_process_impl.h4
-rw-r--r--chrome/browser/cocoa/status_icons/status_tray_mac.h2
-rw-r--r--chrome/browser/cocoa/status_icons/status_tray_mac.mm2
-rw-r--r--chrome/browser/extensions/app_background_page_apitest.cc2
-rw-r--r--chrome/browser/extensions/extensions_service.cc6
-rw-r--r--chrome/browser/gtk/status_icons/status_tray_gtk.cc2
-rw-r--r--chrome/browser/gtk/status_icons/status_tray_gtk.h2
-rw-r--r--chrome/browser/gtk/status_icons/status_tray_gtk_unittest.cc5
-rw-r--r--chrome/browser/profile.cc4
-rw-r--r--chrome/browser/profile.h7
-rw-r--r--chrome/browser/profile_impl.cc17
-rw-r--r--chrome/browser/profile_impl.h3
-rw-r--r--chrome/browser/status_icons/status_tray.cc26
-rw-r--r--chrome/browser/status_icons/status_tray.h35
-rw-r--r--chrome/browser/status_icons/status_tray_manager.cc57
-rw-r--r--chrome/browser/status_icons/status_tray_manager.h31
-rw-r--r--chrome/browser/status_icons/status_tray_unittest.cc37
-rw-r--r--chrome/browser/views/status_icons/status_tray_gtk.cc10
-rw-r--r--chrome/browser/views/status_icons/status_tray_win.cc7
-rw-r--r--chrome/browser/views/status_icons/status_tray_win.h2
-rw-r--r--chrome/browser/views/status_icons/status_tray_win_unittest.cc5
-rw-r--r--chrome/chrome_browser.gypi6
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/notification_type.h7
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h2
-rw-r--r--chrome/test/testing_browser_process.h4
-rw-r--r--chrome/test/testing_profile.h3
39 files changed, 497 insertions, 214 deletions
diff --git a/chrome/browser/background_contents_service.cc b/chrome/browser/background_contents_service.cc
index 3202bac..edd3219 100644
--- a/chrome/browser/background_contents_service.cc
+++ b/chrome/browser/background_contents_service.cc
@@ -40,8 +40,7 @@ const char kFrameNameKey[] = "name";
BackgroundContentsService::BackgroundContentsService(
Profile* profile, const CommandLine* command_line)
- : prefs_(NULL),
- always_keep_alive_(command_line->HasSwitch(switches::kKeepAliveForTest)) {
+ : prefs_(NULL) {
// Don't load/store preferences if the proper switch is not enabled, or if
// the parent profile is off the record.
if (!profile->IsOffTheRecord() &&
@@ -85,14 +84,6 @@ void BackgroundContentsService::StartObserving(Profile* profile) {
// BackgroundContents.
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
Source<Profile>(profile));
-
- if (always_keep_alive_ && !profile->IsOffTheRecord()) {
- // For testing, keep the browser process alive until there is an explicit
- // shutdown.
- registrar_.Add(this, NotificationType::APP_TERMINATING,
- NotificationService::AllSources());
- BrowserList::StartKeepAlive();
- }
}
void BackgroundContentsService::Observe(NotificationType type,
@@ -121,11 +112,6 @@ void BackgroundContentsService::Observe(NotificationType type,
ShutdownAssociatedBackgroundContents(
ASCIIToUTF16(Details<Extension>(details)->id()));
break;
- case NotificationType::APP_TERMINATING:
- // Performing an explicit shutdown, so allow the browser process to exit.
- DCHECK(always_keep_alive_);
- BrowserList::EndKeepAlive();
- break;
default:
NOTREACHED();
break;
diff --git a/chrome/browser/background_contents_service.h b/chrome/browser/background_contents_service.h
index 2512c4d..e9d7df0a 100644
--- a/chrome/browser/background_contents_service.h
+++ b/chrome/browser/background_contents_service.h
@@ -127,10 +127,6 @@ class BackgroundContentsService : private NotificationObserver,
typedef std::map<string16, BackgroundContentsInfo> BackgroundContentsMap;
BackgroundContentsMap contents_map_;
- // If true, should always keep the browser process alive regardless of whether
- // there are any BackgroundContents (used for manual/automated testing).
- bool always_keep_alive_;
-
DISALLOW_COPY_AND_ASSIGN(BackgroundContentsService);
};
diff --git a/chrome/browser/background_mode_manager.cc b/chrome/browser/background_mode_manager.cc
new file mode 100644
index 0000000..44ce468
--- /dev/null
+++ b/chrome/browser/background_mode_manager.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/command_line.h"
+#include "chrome/browser/background_mode_manager.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/status_icons/status_icon.h"
+#include "chrome/browser/status_icons/status_tray.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/pref_names.h"
+#include "grit/browser_resources.h"
+#include "grit/chromium_strings.h"
+#include "grit/theme_resources.h"
+
+BackgroundModeManager::BackgroundModeManager(Profile* profile)
+ : profile_(profile),
+ background_app_count_(0),
+ status_tray_(NULL) {
+ // If background mode is disabled for unittests, just exit - don't listen for
+ // any notifications.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableBackgroundMode))
+ return;
+
+ // Only need status icons on windows/linux. ChromeOS doesn't allow exiting
+ // Chrome and Mac can use the dock icon instead.
+#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
+ status_tray_ = profile->GetStatusTray();
+#endif
+
+ // If the -keep-alive-for-test flag is passed, then always keep chrome running
+ // in the background until the user explicitly terminates it.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kKeepAliveForTest)) {
+ StartBackgroundMode();
+ registrar_.Add(this, NotificationType::APP_TERMINATING,
+ NotificationService::AllSources());
+ }
+
+ // When an extension is installed, make sure launch on startup is properly
+ // set if appropriate. Likewise, turn off launch on startup when the last
+ // background app is uninstalled.
+ registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
+ Source<Profile>(profile));
+ registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
+ Source<Profile>(profile));
+ // Listen for when extensions are loaded/unloaded so we can track the
+ // number of background apps.
+ registrar_.Add(this, NotificationType::EXTENSION_LOADED,
+ Source<Profile>(profile));
+ registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
+ Source<Profile>(profile));
+
+ // Check for the presence of background apps after all extensions have been
+ // loaded, to handle the case where an extension has been manually removed
+ // while Chrome was not running.
+ registrar_.Add(this, NotificationType::EXTENSIONS_READY,
+ Source<Profile>(profile));
+
+}
+
+BackgroundModeManager::~BackgroundModeManager() {
+}
+
+bool BackgroundModeManager::IsBackgroundModeEnabled() {
+ return profile_->GetPrefs()->GetBoolean(prefs::kBackgroundModeEnabled);
+}
+
+void BackgroundModeManager::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type.value) {
+ case NotificationType::EXTENSIONS_READY:
+ EnableLaunchOnStartup(IsBackgroundModeEnabled() &&
+ background_app_count_ > 0);
+ break;
+ case NotificationType::EXTENSION_LOADED:
+ if (IsBackgroundApp(Details<Extension>(details).ptr()))
+ OnBackgroundAppLoaded();
+ break;
+ case NotificationType::EXTENSION_UNLOADED:
+ if (IsBackgroundApp(Details<Extension>(details).ptr()))
+ OnBackgroundAppUnloaded();
+ break;
+ case NotificationType::EXTENSION_INSTALLED:
+ if (IsBackgroundApp(Details<Extension>(details).ptr()))
+ OnBackgroundAppInstalled();
+ break;
+ case NotificationType::EXTENSION_UNINSTALLED:
+ if (IsBackgroundApp(Details<Extension>(details).ptr()))
+ OnBackgroundAppUninstalled();
+ break;
+ case NotificationType::APP_TERMINATING:
+ // Performing an explicit shutdown, so allow the browser process to exit.
+ // (we only listen for this notification if the keep-alive-for-test flag
+ // is passed).
+ DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kKeepAliveForTest));
+ EndBackgroundMode();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+bool BackgroundModeManager::IsBackgroundApp(Extension* extension) {
+ return extension->HasApiPermission(Extension::kBackgroundPermission);
+}
+
+void BackgroundModeManager::OnBackgroundAppLoaded() {
+ // When a background app loads, increment our count and also enable
+ // KeepAlive mode if the preference is set.
+ background_app_count_++;
+ if (background_app_count_ == 1 && IsBackgroundModeEnabled())
+ StartBackgroundMode();
+}
+
+void BackgroundModeManager::StartBackgroundMode() {
+ // Put ourselves in KeepAlive mode and create a status tray icon.
+ BrowserList::StartKeepAlive();
+
+ // Display a status icon to exit Chrome.
+ CreateStatusTrayIcon();
+}
+
+void BackgroundModeManager::OnBackgroundAppUnloaded() {
+ // When a background app unloads, decrement our count and also end
+ // KeepAlive mode if appropriate.
+ background_app_count_--;
+ DCHECK(background_app_count_ == 0);
+ if (background_app_count_ == 0 && IsBackgroundModeEnabled())
+ EndBackgroundMode();
+}
+
+void BackgroundModeManager::EndBackgroundMode() {
+ // End KeepAlive mode and blow away our status tray icon.
+ BrowserList::EndKeepAlive();
+ RemoveStatusTrayIcon();
+}
+
+void BackgroundModeManager::OnBackgroundAppInstalled() {
+ // We're installing a background app. If this is the first background app
+ // being installed, make sure we are set to launch on startup.
+ if (IsBackgroundModeEnabled() && background_app_count_ == 0)
+ EnableLaunchOnStartup(true);
+}
+
+void BackgroundModeManager::OnBackgroundAppUninstalled() {
+ // When uninstalling a background app, disable launch on startup if it's the
+ // last one.
+ if (IsBackgroundModeEnabled() && background_app_count_ == 1)
+ EnableLaunchOnStartup(false);
+}
+
+void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
+ // TODO(atwilson): Add platform-specific code to enable/disable launch on
+ // startup.
+}
+
+void BackgroundModeManager::CreateStatusTrayIcon() {
+ // If the platform doesn't support status icons, or we've already created
+ // our status icon, just return.
+ if (!status_tray_ || status_icon_)
+ return;
+ status_icon_ = status_tray_->CreateStatusIcon();
+ if (!status_icon_)
+ return;
+
+ // Set the image and add ourselves as a click observer on it
+ SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_STATUS_TRAY_ICON);
+ status_icon_->SetImage(*bitmap);
+ status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
+ status_icon_->AddObserver(this);
+}
+
+void BackgroundModeManager::RemoveStatusTrayIcon() {
+ if (status_icon_)
+ status_tray_->RemoveStatusIcon(status_icon_);
+ status_icon_ = NULL;
+}
+
+void BackgroundModeManager::OnClicked() {
+ UserMetrics::RecordAction(UserMetricsAction("Exit"), profile_);
+ BrowserList::CloseAllBrowsersAndExit();
+}
+
+// static
+void BackgroundModeManager::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true);
+}
diff --git a/chrome/browser/background_mode_manager.h b/chrome/browser/background_mode_manager.h
new file mode 100644
index 0000000..fa5296b
--- /dev/null
+++ b/chrome/browser/background_mode_manager.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_BACKGROUND_MODE_MANAGER_H_
+#define CHROME_BROWSER_BACKGROUND_MODE_MANAGER_H_
+#pragma once
+
+#include "base/gtest_prod_util.h"
+#include "chrome/browser/status_icons/status_icon.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+
+class Extension;
+class PrefService;
+class Profile;
+class StatusIcon;
+class StatusTray;
+
+// BackgroundModeManager is responsible for switching Chrome into and out of
+// "background mode" and for providing UI for the user to exit Chrome when there
+// are no open browser windows.
+//
+// Chrome enters background mode whenever there is an application with the
+// "background" permission installed and the appropriate user preference is
+// set (kBackgroundModeEnabled). This class monitors the set of installed/loaded
+// extensions to ensure that Chrome enters/exits background mode at the
+// appropriate time.
+//
+// When Chrome is in background mode, it will continue running even after the
+// last browser window is closed, until the user explicitly exits the app.
+// Additionally, when in background mode, Chrome will launch on OS login with
+// no open windows to allow apps with the "background" permission to run in the
+// background.
+class BackgroundModeManager
+ : private NotificationObserver,
+ private StatusIcon::Observer {
+ public:
+ explicit BackgroundModeManager(Profile* profile);
+ virtual ~BackgroundModeManager();
+
+ static void RegisterUserPrefs(PrefService* prefs);
+ private:
+ friend class TestBackgroundModeManager;
+ friend class BackgroundModeManagerTest;
+ FRIEND_TEST_ALL_PREFIXES(BackgroundModeManagerTest,
+ BackgroundAppLoadUnload);
+ FRIEND_TEST_ALL_PREFIXES(BackgroundModeManagerTest,
+ BackgroundAppInstallUninstall);
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // StatusIcon::Observer implementation.
+ virtual void OnClicked();
+
+ // Called when an extension is loaded to manage count of background apps.
+ void OnBackgroundAppLoaded();
+
+ // Called when an extension is unloaded to manage count of background apps.
+ void OnBackgroundAppUnloaded();
+
+ // Invoked when an extension is installed so we can ensure that
+ // launch-on-startup is enabled if appropriate.
+ void OnBackgroundAppInstalled();
+
+ // Invoked when an extension is uninstalled so we can ensure that
+ // launch-on-startup is disabled if appropriate.
+ void OnBackgroundAppUninstalled();
+
+ // Returns true if the passed extension is a background app.
+ bool IsBackgroundApp(Extension* extension);
+
+ // Returns true if the background mode preference is enabled
+ bool IsBackgroundModeEnabled();
+
+ // Called to make sure that our launch-on-startup mode is properly set.
+ // (virtual so we can override for tests).
+ virtual void EnableLaunchOnStartup(bool should_launch);
+
+ // Invoked to put Chrome in KeepAlive mode - chrome runs in the background
+ // and has a status bar icon.
+ void StartBackgroundMode();
+
+ // Invoked to take Chrome out of KeepAlive mode - chrome stops running in
+ // the background and removes its status bar icon.
+ void EndBackgroundMode();
+
+ // Create a status tray icon to allow the user to shutdown Chrome when running
+ // in background mode. Virtual to enable testing.
+ virtual void CreateStatusTrayIcon();
+
+ // Removes the status tray icon because we are exiting background mode.
+ // Virtual to enable testing.
+ virtual void RemoveStatusTrayIcon();
+
+ NotificationRegistrar registrar_;
+
+ // The parent profile for this object.
+ Profile* profile_;
+
+ // The number of background apps currently loaded.
+ int background_app_count_;
+
+ // Reference to our status tray (owned by our parent profile). If null, the
+ // platform doesn't support status icons.
+ StatusTray* status_tray_;
+
+ // Reference to our status icon (if any) - owned by the StatusTray.
+ StatusIcon* status_icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundModeManager);
+};
+
+#endif // CHROME_BROWSER_BACKGROUND_MODE_MANAGER_H_
diff --git a/chrome/browser/background_mode_manager_unittest.cc b/chrome/browser/background_mode_manager_unittest.cc
new file mode 100644
index 0000000..087b4fe
--- /dev/null
+++ b/chrome/browser/background_mode_manager_unittest.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/background_mode_manager.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/test/testing_profile.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class TestBackgroundModeManager : public BackgroundModeManager {
+ public:
+ explicit TestBackgroundModeManager(Profile* profile)
+ : BackgroundModeManager(profile) {
+ }
+ MOCK_METHOD1(EnableLaunchOnStartup, void(bool));
+ MOCK_METHOD0(CreateStatusTrayIcon, void());
+ MOCK_METHOD0(RemoveStatusTrayIcon, void());
+};
+
+TEST(BackgroundModeManagerTest, BackgroundAppLoadUnload) {
+ TestingProfile profile;
+ TestBackgroundModeManager manager(&profile);
+ EXPECT_FALSE(BrowserList::WillKeepAlive());
+ // Call to AppLoaded() will cause the status tray to be created, then call to
+ // unloaded will result in call to remove the icon.
+ EXPECT_CALL(manager, CreateStatusTrayIcon());
+ manager.OnBackgroundAppLoaded();
+ EXPECT_TRUE(BrowserList::WillKeepAlive());
+ EXPECT_CALL(manager, RemoveStatusTrayIcon());
+ manager.OnBackgroundAppUnloaded();
+ EXPECT_FALSE(BrowserList::WillKeepAlive());
+}
+
+TEST(BackgroundModeManagerTest, BackgroundAppInstallUninstall) {
+ TestingProfile profile;
+ TestBackgroundModeManager manager(&profile);
+ // Call to AppInstalled() will cause chrome to be set to launch on startup,
+ // and call to AppUninstalling() set chrome to not launch on startup.
+ EXPECT_CALL(manager, EnableLaunchOnStartup(true));
+ manager.OnBackgroundAppInstalled();
+ manager.OnBackgroundAppLoaded();
+ EXPECT_CALL(manager, EnableLaunchOnStartup(false));
+ manager.OnBackgroundAppUninstalled();
+ manager.OnBackgroundAppUnloaded();
+}
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index 8dbe4a9..5e1f459 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -41,7 +41,6 @@
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/shell_integration.h"
-#include "chrome/browser/status_icons/status_tray_manager.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -443,14 +442,6 @@ bool BrowserInit::LaunchBrowser(const CommandLine& command_line,
chromeos::SystemKeyEventListener::instance();
}
#endif
-
- if (command_line.HasSwitch(switches::kRestoreBackgroundContents) ||
- command_line.HasSwitch(switches::kKeepAliveForTest)) {
- // Create status icons
- StatusTrayManager* tray = g_browser_process->status_tray_manager();
- if (tray)
- tray->Init(profile);
- }
return true;
}
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc
index 9c13d88..c6222a7 100644
--- a/chrome/browser/browser_prefs.cc
+++ b/chrome/browser/browser_prefs.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/autofill/autofill_manager.h"
#include "chrome/browser/background_contents_service.h"
+#include "chrome/browser/background_mode_manager.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_shutdown.h"
@@ -101,6 +102,7 @@ void RegisterLocalState(PrefService* local_state) {
void RegisterUserPrefs(PrefService* user_prefs) {
// User prefs
AutoFillManager::RegisterUserPrefs(user_prefs);
+ BackgroundModeManager::RegisterUserPrefs(user_prefs);
SessionStartupPref::RegisterUserPrefs(user_prefs);
Browser::RegisterUserPrefs(user_prefs);
PasswordManager::RegisterUserPrefs(user_prefs);
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index 417d333..a853c74 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -29,7 +29,6 @@ class NotificationUIManager;
class PrefService;
class ProfileManager;
class ResourceDispatcherHost;
-class StatusTrayManager;
class TabCloseableStateWatcher;
class ThumbnailGenerator;
@@ -69,10 +68,6 @@ class BrowserProcess {
// Returns the manager for desktop notifications.
virtual NotificationUIManager* notification_ui_manager() = 0;
- // Returns the status tray manager (provides APIs for manipulating status
- // icons).
- virtual StatusTrayManager* status_tray_manager() = 0;
-
// Returns the thread that we perform I/O coordination on (network requests,
// communication with renderers, etc.
// NOTE: You should ONLY use this to pass to IPC or other objects which must
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index a1fbf55..f314388 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -43,7 +43,6 @@
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/status_icons/status_tray_manager.h"
#include "chrome/browser/tab_closeable_state_watcher.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
@@ -359,13 +358,6 @@ NotificationUIManager* BrowserProcessImpl::notification_ui_manager() {
return notification_ui_manager_.get();
}
-StatusTrayManager* BrowserProcessImpl::status_tray_manager() {
- DCHECK(CalledOnValidThread());
- if (!status_tray_manager_.get())
- CreateStatusTrayManager();
- return status_tray_manager_.get();
-}
-
IconManager* BrowserProcessImpl::icon_manager() {
DCHECK(CalledOnValidThread());
if (!created_icon_manager_)
@@ -644,11 +636,6 @@ void BrowserProcessImpl::CreateNotificationUIManager() {
created_notification_ui_manager_ = true;
}
-void BrowserProcessImpl::CreateStatusTrayManager() {
- DCHECK(status_tray_manager_.get() == NULL);
- status_tray_manager_.reset(new StatusTrayManager());
-}
-
void BrowserProcessImpl::CreateTabCloseableStateWatcher() {
DCHECK(tab_closeable_state_watcher_.get() == NULL);
tab_closeable_state_watcher_.reset(TabCloseableStateWatcher::Create());
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index b26127d..9118ff6 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -51,7 +51,6 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
virtual DevToolsManager* devtools_manager();
virtual Clipboard* clipboard();
virtual NotificationUIManager* notification_ui_manager();
- virtual StatusTrayManager* status_tray_manager();
virtual IconManager* icon_manager();
virtual ThumbnailGenerator* GetThumbnailGenerator();
virtual AutomationProviderList* InitAutomationProviderList();
@@ -157,9 +156,6 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe {
bool created_notification_ui_manager_;
scoped_ptr<NotificationUIManager> notification_ui_manager_;
- // Manager for status tray.
- scoped_ptr<StatusTrayManager> status_tray_manager_;
-
scoped_ptr<AutomationProviderList> automation_provider_list_;
scoped_ptr<GoogleURLTracker> google_url_tracker_;
diff --git a/chrome/browser/cocoa/status_icons/status_tray_mac.h b/chrome/browser/cocoa/status_icons/status_tray_mac.h
index 074251b..3552db4 100644
--- a/chrome/browser/cocoa/status_icons/status_tray_mac.h
+++ b/chrome/browser/cocoa/status_icons/status_tray_mac.h
@@ -14,7 +14,7 @@ class StatusTrayMac : public StatusTray {
protected:
// Factory method for creating a status icon.
- virtual StatusIcon* CreateStatusIcon();
+ virtual StatusIcon* CreatePlatformStatusIcon();
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayMac);
diff --git a/chrome/browser/cocoa/status_icons/status_tray_mac.mm b/chrome/browser/cocoa/status_icons/status_tray_mac.mm
index 8c9449b..d4e176f 100644
--- a/chrome/browser/cocoa/status_icons/status_tray_mac.mm
+++ b/chrome/browser/cocoa/status_icons/status_tray_mac.mm
@@ -13,6 +13,6 @@ StatusTray* StatusTray::Create() {
StatusTrayMac::StatusTrayMac() {
}
-StatusIcon* StatusTrayMac::CreateStatusIcon() {
+StatusIcon* StatusTrayMac::CreatePlatformStatusIcon() {
return new StatusIconMac();
}
diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc
index a75fc50..5980921 100644
--- a/chrome/browser/extensions/app_background_page_apitest.cc
+++ b/chrome/browser/extensions/app_background_page_apitest.cc
@@ -13,6 +13,8 @@ class AppBackgroundPageApiTest : public ExtensionApiTest {
void SetUpCommandLine(CommandLine* command_line) {
ExtensionApiTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kDisablePopupBlocking);
+ // Tests rely on chrome exiting, so disable background mode.
+ command_line->AppendSwitch(switches::kDisableBackgroundMode);
}
};
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index ad26fc6..61de28b 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -374,6 +374,12 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
// Callers should not send us nonexistant extensions.
DCHECK(extension);
+ // Notify interested parties that we're uninstalling this extension.
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_UNINSTALLED,
+ Source<Profile>(profile_),
+ Details<Extension>(extension));
+
// Get hold of information we need after unloading, since the extension
// pointer will be invalid then.
GURL extension_url(extension->url());
diff --git a/chrome/browser/gtk/status_icons/status_tray_gtk.cc b/chrome/browser/gtk/status_icons/status_tray_gtk.cc
index 6b2764e..98cf98c 100644
--- a/chrome/browser/gtk/status_icons/status_tray_gtk.cc
+++ b/chrome/browser/gtk/status_icons/status_tray_gtk.cc
@@ -12,7 +12,7 @@ StatusTrayGtk::StatusTrayGtk() {
StatusTrayGtk::~StatusTrayGtk() {
}
-StatusIcon* StatusTrayGtk::CreateStatusIcon() {
+StatusIcon* StatusTrayGtk::CreatePlatformStatusIcon() {
return new StatusIconGtk();
}
diff --git a/chrome/browser/gtk/status_icons/status_tray_gtk.h b/chrome/browser/gtk/status_icons/status_tray_gtk.h
index ec443ca..5e0241b 100644
--- a/chrome/browser/gtk/status_icons/status_tray_gtk.h
+++ b/chrome/browser/gtk/status_icons/status_tray_gtk.h
@@ -15,7 +15,7 @@ class StatusTrayGtk : public StatusTray {
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreateStatusIcon();
+ virtual StatusIcon* CreatePlatformStatusIcon();
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayGtk);
diff --git a/chrome/browser/gtk/status_icons/status_tray_gtk_unittest.cc b/chrome/browser/gtk/status_icons/status_tray_gtk_unittest.cc
index 5bc2c2b..89f9524 100644
--- a/chrome/browser/gtk/status_icons/status_tray_gtk_unittest.cc
+++ b/chrome/browser/gtk/status_icons/status_tray_gtk_unittest.cc
@@ -27,7 +27,7 @@ TEST(StatusTrayGtkTest, CreateTray) {
TEST(StatusTrayGtkTest, CreateIcon) {
// Create an icon, set the images and tooltip, then shut it down.
StatusTrayGtk tray;
- StatusIcon* icon = tray.GetStatusIcon(ASCIIToUTF16("test"));
+ StatusIcon* icon = tray.CreateStatusIcon();
SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_STATUS_TRAY_ICON);
icon->SetImage(*bitmap);
@@ -38,8 +38,7 @@ TEST(StatusTrayGtkTest, CreateIcon) {
TEST(StatusTrayGtkTest, ClickOnIcon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayGtk tray;
- StatusIconGtk* icon = static_cast<StatusIconGtk*>(
- tray.GetStatusIcon(ASCIIToUTF16("test")));
+ StatusIconGtk* icon = static_cast<StatusIconGtk*>(tray.CreateStatusIcon());
MockStatusIconObserver observer;
icon->AddObserver(&observer);
EXPECT_CALL(observer, OnClicked());
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 26392e8..51d74f0 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -203,6 +203,10 @@ class OffTheRecordProfileImpl : public Profile,
return background_contents_service_.get();
}
+ virtual StatusTray* GetStatusTray() {
+ return GetOriginalProfile()->GetStatusTray();
+ }
+
virtual UserScriptMaster* GetUserScriptMaster() {
return GetOriginalProfile()->GetUserScriptMaster();
}
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index 6403c8f..da63eae 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -35,6 +35,7 @@ class DatabaseTracker;
class AutocompleteClassifier;
class BackgroundContentsService;
+class BackgroundModeManager;
class BookmarkModel;
class BrowserThemeProvider;
class ChromeAppCacheService;
@@ -65,6 +66,7 @@ class SessionService;
class SpellCheckHost;
class SSLConfigServiceManager;
class SSLHostState;
+class StatusTray;
class TransportSecurityPersister;
class SQLitePersistentCookieStore;
class TabRestoreService;
@@ -405,6 +407,11 @@ class Profile {
// Returns the service that manages BackgroundContents for this profile.
virtual BackgroundContentsService* GetBackgroundContentsService() = 0;
+ // Returns the StatusTray, which provides an API for displaying status icons
+ // in the system status tray. Returns NULL if status icons are not supported
+ // on this platform (or this is a unit test).
+ virtual StatusTray* GetStatusTray() = 0;
+
// Marks the profile as cleanly shutdown.
//
// NOTE: this is invoked internally on a normal shutdown, but is public so
diff --git a/chrome/browser/profile_impl.cc b/chrome/browser/profile_impl.cc
index bc11cc5..84a2b17 100644
--- a/chrome/browser/profile_impl.cc
+++ b/chrome/browser/profile_impl.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/autocomplete/autocomplete_classifier.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/background_contents_service.h"
+#include "chrome/browser/background_mode_manager.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_prefs.h"
@@ -56,6 +57,7 @@
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/ssl/ssl_host_state.h"
+#include "chrome/browser/status_icons/status_tray.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_factory_impl.h"
#include "chrome/browser/tabs/pinned_tab_service.h"
@@ -335,6 +337,15 @@ ProfileImpl::ProfileImpl(const FilePath& path)
pinned_tab_service_.reset(new PinnedTabService(this));
+ // Initialize the BackgroundModeManager - this has to be done here before
+ // InitExtensions() is called because it relies on receiving notifications
+ // when extensions are loaded. BackgroundModeManager is not needed under
+ // ChromeOS because Chrome is always running (no need for special keep-alive
+ // or launch-on-startup support).
+#if !defined(OS_CHROMEOS)
+ background_mode_manager_.reset(new BackgroundModeManager(this));
+#endif
+
background_contents_service_.reset(
new BackgroundContentsService(this, CommandLine::ForCurrentProcess()));
@@ -580,6 +591,12 @@ BackgroundContentsService* ProfileImpl::GetBackgroundContentsService() {
return background_contents_service_.get();
}
+StatusTray* ProfileImpl::GetStatusTray() {
+ if (!status_tray_.get())
+ status_tray_.reset(StatusTray::Create());
+ return status_tray_.get();
+}
+
UserScriptMaster* ProfileImpl::GetUserScriptMaster() {
return user_script_master_.get();
}
diff --git a/chrome/browser/profile_impl.h b/chrome/browser/profile_impl.h
index 45e3b92..6e2230f 100644
--- a/chrome/browser/profile_impl.h
+++ b/chrome/browser/profile_impl.h
@@ -87,6 +87,7 @@ class ProfileImpl : public Profile,
virtual WebKitContext* GetWebKitContext();
virtual DesktopNotificationService* GetDesktopNotificationService();
virtual BackgroundContentsService* GetBackgroundContentsService();
+ virtual StatusTray* GetStatusTray();
virtual void MarkAsCleanShutdown();
virtual void InitExtensions();
virtual NTPResourceCache* GetNTPResourceCache();
@@ -181,6 +182,8 @@ class ProfileImpl : public Profile,
scoped_refptr<WebKitContext> webkit_context_;
scoped_ptr<DesktopNotificationService> desktop_notification_service_;
scoped_ptr<BackgroundContentsService> background_contents_service_;
+ scoped_ptr<BackgroundModeManager> background_mode_manager_;
+ scoped_ptr<StatusTray> status_tray_;
scoped_refptr<PersonalDataManager> personal_data_manager_;
scoped_ptr<PinnedTabService> pinned_tab_service_;
bool history_service_created_;
diff --git a/chrome/browser/status_icons/status_tray.cc b/chrome/browser/status_icons/status_tray.cc
index b7ae49c..8648351 100644
--- a/chrome/browser/status_icons/status_tray.cc
+++ b/chrome/browser/status_icons/status_tray.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/status_icons/status_tray.h"
+#include <algorithm>
+
#include "base/stl_util-inl.h"
#include "chrome/browser/status_icons/status_icon.h"
@@ -16,29 +18,23 @@ StatusTray::~StatusTray() {
void StatusTray::RemoveAllIcons() {
// Walk any active status icons and delete them.
- STLDeleteContainerPairSecondPointers(status_icons_.begin(),
- status_icons_.end());
+ STLDeleteContainerPointers(status_icons_.begin(), status_icons_.end());
status_icons_.clear();
}
-StatusIcon* StatusTray::GetStatusIcon(const string16& identifier) {
- StatusIconMap::const_iterator iter = status_icons_.find(identifier);
- if (iter != status_icons_.end())
- return iter->second;
-
- // No existing StatusIcon, create a new one.
- StatusIcon* icon = CreateStatusIcon();
+StatusIcon* StatusTray::CreateStatusIcon() {
+ StatusIcon* icon = CreatePlatformStatusIcon();
if (icon)
- status_icons_[identifier] = icon;
+ status_icons_.push_back(icon);
return icon;
}
-void StatusTray::RemoveStatusIcon(const string16& identifier) {
- StatusIconMap::iterator iter = status_icons_.find(identifier);
+void StatusTray::RemoveStatusIcon(StatusIcon* icon) {
+ StatusIconList::iterator iter = std::find(
+ status_icons_.begin(), status_icons_.end(), icon);
if (iter != status_icons_.end()) {
- // Free the StatusIcon from the map (can't put scoped_ptr in a map, so we
- // have to do it manually).
- delete iter->second;
+ // Free the StatusIcon from the list.
+ delete *iter;
status_icons_.erase(iter);
}
}
diff --git a/chrome/browser/status_icons/status_tray.h b/chrome/browser/status_icons/status_tray.h
index 6052582..a0da771 100644
--- a/chrome/browser/status_icons/status_tray.h
+++ b/chrome/browser/status_icons/status_tray.h
@@ -6,8 +6,10 @@
#define CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_H_
#pragma once
-#include "base/hash_tables.h"
-#include "base/scoped_ptr.h"
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
class StatusIcon;
@@ -16,38 +18,37 @@ class StatusIcon;
class StatusTray {
public:
// Static factory method that is implemented separately for each platform to
- // produce the appropriate platform-specific instance.
+ // produce the appropriate platform-specific instance. Returns NULL if this
+ // platform does not support status icons.
static StatusTray* Create();
virtual ~StatusTray();
- // Gets the current status icon associated with this identifier, or creates
- // a new one if none exists. The StatusTray retains ownership of the
- // StatusIcon. Returns NULL if the status tray icon could not be created.
- StatusIcon* GetStatusIcon(const string16& identifier);
+ // Creates a new StatusIcon. The StatusTray retains ownership of the
+ // StatusIcon. Returns NULL if the StatusIcon could not be created.
+ StatusIcon* CreateStatusIcon();
// Removes the current status icon associated with this identifier, if any.
- void RemoveStatusIcon(const string16& identifier);
+ void RemoveStatusIcon(StatusIcon* icon);
protected:
StatusTray();
- // Factory method for creating a status icon.
- virtual StatusIcon* CreateStatusIcon() = 0;
+ // Factory method for creating a status icon for this platform.
+ virtual StatusIcon* CreatePlatformStatusIcon() = 0;
// Removes all StatusIcons (used by derived classes to clean up in case they
// track external state used by the StatusIcons).
void RemoveAllIcons();
- typedef base::hash_map<string16, StatusIcon*> StatusIconMap;
+ typedef std::vector<StatusIcon*> StatusIconList;
// Returns the list of active status icons so subclasses can operate on them.
- const StatusIconMap& status_icons() { return status_icons_; }
+ const StatusIconList& status_icons() { return status_icons_; }
private:
- // Map containing all active StatusIcons.
- // Key: String identifiers (passed in to GetStatusIcon)
- // Value: The StatusIcon associated with that identifier (strong pointer -
- // StatusIcons are freed when the StatusTray destructor is called).
- StatusIconMap status_icons_;
+ FRIEND_TEST_ALL_PREFIXES(StatusTrayTest, CreateRemove);
+
+ // List containing all active StatusIcons.
+ StatusIconList status_icons_;
DISALLOW_COPY_AND_ASSIGN(StatusTray);
};
diff --git a/chrome/browser/status_icons/status_tray_manager.cc b/chrome/browser/status_icons/status_tray_manager.cc
deleted file mode 100644
index 57b6ed9..0000000
--- a/chrome/browser/status_icons/status_tray_manager.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/status_icons/status_tray_manager.h"
-
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "base/logging.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_window.h"
-#include "chrome/browser/status_icons/status_tray.h"
-#include "grit/browser_resources.h"
-#include "grit/chromium_strings.h"
-#include "grit/theme_resources.h"
-
-StatusTrayManager::StatusTrayManager() : profile_(NULL) {
-}
-
-StatusTrayManager::~StatusTrayManager() {
-}
-
-void StatusTrayManager::Init(Profile* profile) {
-#if !(defined(OS_LINUX) && defined(TOOLKIT_VIEWS))
- DCHECK(profile);
- profile_ = profile;
- status_tray_.reset(StatusTray::Create());
- StatusIcon* icon = status_tray_->GetStatusIcon(ASCIIToUTF16("chrome_main"));
- if (icon) {
- // Create an icon and add ourselves as a click observer on it
- SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
- IDR_STATUS_TRAY_ICON);
- SkBitmap* pressed = ResourceBundle::GetSharedInstance().GetBitmapNamed(
- IDR_STATUS_TRAY_ICON_PRESSED);
- icon->SetImage(*bitmap);
- icon->SetPressedImage(*pressed);
- icon->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
- icon->AddObserver(this);
- }
-#endif
-}
-
-void StatusTrayManager::OnClicked() {
- // When the tray icon is clicked, bring up the extensions page for now.
- Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
- if (browser) {
- // Bring up the existing browser window and show the extensions tab.
- browser->window()->Activate();
- browser->ShowExtensionsTab();
- } else {
- // No windows are currently open, so open a new one.
- Browser::OpenExtensionsWindow(profile_);
- }
-}
diff --git a/chrome/browser/status_icons/status_tray_manager.h b/chrome/browser/status_icons/status_tray_manager.h
deleted file mode 100644
index 6829f94..0000000
--- a/chrome/browser/status_icons/status_tray_manager.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_MANAGER_H_
-#define CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_MANAGER_H_
-#pragma once
-
-#include "base/scoped_ptr.h"
-#include "chrome/browser/status_icons/status_icon.h"
-
-class Profile;
-class StatusTray;
-
-// Manages the set of status tray icons and associated UI.
-class StatusTrayManager : private StatusIcon::Observer {
- public:
- StatusTrayManager();
- virtual ~StatusTrayManager();
-
- void Init(Profile* profile);
-
- private:
- // Overriden from StatusIcon::Observer:
- virtual void OnClicked();
-
- scoped_ptr<StatusTray> status_tray_;
- Profile* profile_;
-};
-
-#endif // CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_MANAGER_H_
diff --git a/chrome/browser/status_icons/status_tray_unittest.cc b/chrome/browser/status_icons/status_tray_unittest.cc
index 957faa7..26219bd 100644
--- a/chrome/browser/status_icons/status_tray_unittest.cc
+++ b/chrome/browser/status_icons/status_tray_unittest.cc
@@ -21,35 +21,26 @@ class MockStatusIcon : public StatusIcon {
class TestStatusTray : public StatusTray {
public:
- MOCK_METHOD0(CreateStatusIcon, StatusIcon*());
+ MOCK_METHOD0(CreatePlatformStatusIcon, StatusIcon*());
};
TEST(StatusTrayTest, Create) {
// Check for creation and leaks.
TestStatusTray tray;
- EXPECT_CALL(tray, CreateStatusIcon()).WillOnce(Return(new MockStatusIcon()));
- tray.GetStatusIcon(ASCIIToUTF16("test"));
+ EXPECT_CALL(tray,
+ CreatePlatformStatusIcon()).WillOnce(Return(new MockStatusIcon()));
+ tray.CreateStatusIcon();
}
-TEST(StatusTrayTest, GetIconTwice) {
+// Make sure that removing an icon removes it from the list.
+TEST(StatusTrayTest, CreateRemove) {
TestStatusTray tray;
- string16 id = ASCIIToUTF16("test");
- // We should not try to create a new icon if we get the same ID twice.
- EXPECT_CALL(tray, CreateStatusIcon()).WillOnce(Return(new MockStatusIcon()));
- StatusIcon* icon = tray.GetStatusIcon(id);
- EXPECT_EQ(icon, tray.GetStatusIcon(id));
-}
-
-TEST(StatusTrayTest, GetIconAfterRemove) {
- TestStatusTray tray;
- string16 id = ASCIIToUTF16("test");
- EXPECT_CALL(tray, CreateStatusIcon()).Times(2)
- .WillOnce(Return(new MockStatusIcon()))
- .WillOnce(Return(new MockStatusIcon()));
- StatusIcon* icon = tray.GetStatusIcon(id);
- EXPECT_EQ(icon, tray.GetStatusIcon(id));
-
- // If we remove the icon, then we should create a new one the next time in.
- tray.RemoveStatusIcon(id);
- tray.GetStatusIcon(id);
+ EXPECT_CALL(tray,
+ CreatePlatformStatusIcon()).WillOnce(Return(new MockStatusIcon()));
+ StatusIcon* icon = tray.CreateStatusIcon();
+ EXPECT_EQ(1U, tray.status_icons_.size());
+ tray.RemoveStatusIcon(icon);
+ EXPECT_EQ(0U, tray.status_icons_.size());
+ // Calling again should do nothing.
+ tray.RemoveStatusIcon(icon);
}
diff --git a/chrome/browser/views/status_icons/status_tray_gtk.cc b/chrome/browser/views/status_icons/status_tray_gtk.cc
new file mode 100644
index 0000000..7cd0666
--- /dev/null
+++ b/chrome/browser/views/status_icons/status_tray_gtk.cc
@@ -0,0 +1,10 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/status_icons/status_tray.h"
+
+// Status icons are not currently supported on linux/views.
+StatusTray* StatusTray::Create() {
+ return NULL;
+}
diff --git a/chrome/browser/views/status_icons/status_tray_win.cc b/chrome/browser/views/status_icons/status_tray_win.cc
index 8c1a998..5a4587f 100644
--- a/chrome/browser/views/status_icons/status_tray_win.cc
+++ b/chrome/browser/views/status_icons/status_tray_win.cc
@@ -49,11 +49,10 @@ LRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd,
case WM_LBUTTONDOWN:
// Walk our icons, find which one was clicked on, and invoke its
// DispatchClickEvent() method.
- for (StatusIconMap::const_iterator iter = status_icons().begin();
+ for (StatusIconList::const_iterator iter = status_icons().begin();
iter != status_icons().end();
++iter) {
- StatusIconWin* win_icon =
- static_cast<StatusIconWin*>(iter->second);
+ StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter);
if (win_icon->icon_id() == wparam)
win_icon->DispatchClickEvent();
}
@@ -70,7 +69,7 @@ StatusTrayWin::~StatusTrayWin() {
UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL));
}
-StatusIcon* StatusTrayWin::CreateStatusIcon() {
+StatusIcon* StatusTrayWin::CreatePlatformStatusIcon() {
return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage);
}
diff --git a/chrome/browser/views/status_icons/status_tray_win.h b/chrome/browser/views/status_icons/status_tray_win.h
index efdb13b..a2e322c 100644
--- a/chrome/browser/views/status_icons/status_tray_win.h
+++ b/chrome/browser/views/status_icons/status_tray_win.h
@@ -22,7 +22,7 @@ class StatusTrayWin : public StatusTray {
LPARAM lparam);
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreateStatusIcon();
+ virtual StatusIcon* CreatePlatformStatusIcon();
private:
// Static callback invoked when a message comes in to our messaging window.
diff --git a/chrome/browser/views/status_icons/status_tray_win_unittest.cc b/chrome/browser/views/status_icons/status_tray_win_unittest.cc
index 635c7df..e5499b9e 100644
--- a/chrome/browser/views/status_icons/status_tray_win_unittest.cc
+++ b/chrome/browser/views/status_icons/status_tray_win_unittest.cc
@@ -27,7 +27,7 @@ TEST(StatusTrayWinTest, CreateTray) {
TEST(StatusTrayWinTest, CreateIcon) {
// Create an icon, set the images and tooltip, then shut it down.
StatusTrayWin tray;
- StatusIcon* icon = tray.GetStatusIcon(ASCIIToUTF16("test"));
+ StatusIcon* icon = tray.CreateStatusIcon();
SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_STATUS_TRAY_ICON);
icon->SetImage(*bitmap);
@@ -38,8 +38,7 @@ TEST(StatusTrayWinTest, CreateIcon) {
TEST(StatusTrayWinTest, ClickOnIcon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayWin tray;
- StatusIconWin* icon = static_cast<StatusIconWin*>(
- tray.GetStatusIcon(ASCIIToUTF16("test")));
+ StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon());
MockStatusIconObserver observer;
icon->AddObserver(&observer);
EXPECT_CALL(observer, OnClicked());
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 2adbedb..e3e4158 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -232,6 +232,8 @@
'browser/automation/ui_controls.h',
'browser/back_forward_menu_model.cc',
'browser/back_forward_menu_model.h',
+ 'browser/background_mode_manager.h',
+ 'browser/background_mode_manager.cc',
'browser/background_contents_service.h',
'browser/background_contents_service.cc',
'browser/blocked_plugin_manager.cc',
@@ -2421,8 +2423,6 @@
'browser/status_bubble.h',
'browser/status_icons/status_tray.cc',
'browser/status_icons/status_tray.h',
- 'browser/status_icons/status_tray_manager.cc',
- 'browser/status_icons/status_tray_manager.h',
'browser/status_icons/status_icon.cc',
'browser/status_icons/status_icon.h',
'browser/transport_security_persister.cc',
@@ -2894,6 +2894,7 @@
'browser/views/status_bubble_views.h',
'browser/views/status_icons/status_icon_win.cc',
'browser/views/status_icons/status_icon_win.h',
+ 'browser/views/status_icons/status_tray_gtk.cc',
'browser/views/status_icons/status_tray_win.cc',
'browser/views/status_icons/status_tray_win.h',
'browser/views/tab_icon_view.cc',
@@ -3511,6 +3512,7 @@
['include', '^browser/views/select_file_dialog.cc'],
['include', '^browser/views/status_bubble_views.cc'],
['include', '^browser/views/status_bubble_views.h'],
+ ['include', '^browser/views/status_icons/status_tray_gtk.cc'],
['include', '^browser/views/tab_contents/native_tab_contents_container_gtk.cc'],
['include', '^browser/views/tab_contents/native_tab_contents_container_gtk.h'],
['include', '^browser/views/tab_contents/render_view_context_menu_views.cc'],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index f8dde06..6879af7 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -717,6 +717,7 @@
'browser/automation/automation_provider_unittest.cc',
'browser/back_forward_menu_model_unittest.cc',
'browser/background_contents_service_unittest.cc',
+ 'browser/background_mode_manager_unittest.cc',
'browser/bookmarks/bookmark_codec_unittest.cc',
'browser/bookmarks/bookmark_context_menu_controller_unittest.cc',
'browser/bookmarks/bookmark_drag_data_unittest.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 605e740..5dfeb0c 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -122,6 +122,10 @@ const char kDisableAudio[] = "disable-audio";
const char kDisableAuthNegotiateCnameLookup[] =
"disable-auth-negotiate-cname-lookup";
+// Disable background mode (background apps will not keep chrome running in the
+// background) - used when running tests involving background apps.
+const char kDisableBackgroundMode[] = "disable-background-mode";
+
// Disable limits on the number of backing stores. Can prevent blinking for
// users with many windows/tabs and lots of memory.
const char kDisableBackingStoreLimit[] = "disable-backing-store-limit";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index bf1b4b7..770f6d9 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -49,6 +49,7 @@ extern const char kDisableApplicationCache[];
extern const char kDisableApps[];
extern const char kDisableAudio[];
extern const char kDisableAuthNegotiateCnameLookup[];
+extern const char kDisableBackgroundMode[];
extern const char kDisableBackingStoreLimit[];
extern const char kDisableByteRangeSupport[];
extern const char kDisableContentPrefetch[];
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 48871b4..252f70d 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -787,6 +787,13 @@ class NotificationType {
// details about why the install failed.
EXTENSION_INSTALL_ERROR,
+ // Sent when a new extension is being uninstalled. When this notification
+ // is sent, the ExtensionsService still is tracking this extension (it has
+ // not been unloaded yet). This will be followed by an EXTENSION_UNLOADED
+ // or EXTENSION_UNLOADED_DISABLED when the extension is actually unloaded.
+ // The details are an Extension and the source is a Profile.
+ EXTENSION_UNINSTALLED,
+
// Sent when an extension is unloaded. This happens when an extension is
// uninstalled or disabled. The details are an Extension, and the source is
// a Profile.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 40183d1..02f92424 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -687,6 +687,10 @@ const char kPreferencesWindowPlacement[] = "preferences.window_placement";
// renderer's in-memory cache of objects.
const char kMemoryCacheSize[] = "renderer.memory_cache.size";
+// Boolean that records if chrome should run in background mode when background
+// apps are installed.
+const char kBackgroundModeEnabled[] = "background_mode.enabled";
+
// String which specifies where to download files to by default.
const char kDownloadDefaultDirectory[] = "download.default_directory";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index f27005a..18503a0 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -250,6 +250,8 @@ extern const char kKeywordEditorWindowPlacement[];
extern const char kPreferencesWindowPlacement[];
extern const char kMemoryCacheSize[];
+extern const char kBackgroundModeEnabled[];
+
extern const char kDownloadDefaultDirectory[];
extern const char kDownloadExtensionsToOpen[];
extern const char kDownloadDirUpgraded[];
diff --git a/chrome/test/testing_browser_process.h b/chrome/test/testing_browser_process.h
index 82db3af..65f6cca 100644
--- a/chrome/test/testing_browser_process.h
+++ b/chrome/test/testing_browser_process.h
@@ -103,10 +103,6 @@ class TestingBrowserProcess : public BrowserProcess {
return NULL;
}
- virtual StatusTrayManager* status_tray_manager() {
- return NULL;
- }
-
virtual GoogleURLTracker* google_url_tracker() {
return NULL;
}
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index a4814f5..0db9952 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -236,6 +236,9 @@ class TestingProfile : public Profile {
virtual BackgroundContentsService* GetBackgroundContentsService() {
return NULL;
}
+ virtual StatusTray* GetStatusTray() {
+ return NULL;
+ }
virtual FilePath last_selected_directory() {
return last_selected_directory_;
}