summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/background/background_mode_manager.cc26
-rw-r--r--chrome/browser/background/background_mode_manager.h16
-rw-r--r--chrome/browser/browser_process.h3
-rw-r--r--chrome/browser/browser_process_impl.cc5
-rw-r--r--chrome/browser/browser_process_impl.h2
-rw-r--r--chrome/browser/extensions/background_app_browsertest.cc78
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc2
-rw-r--r--chrome/browser/extensions/extension_browsertest.h2
-rw-r--r--chrome/browser/extensions/extension_service.cc28
-rw-r--r--chrome/browser/extensions/extension_service.h11
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/test/base/testing_browser_process.cc6
-rw-r--r--chrome/test/base/testing_browser_process.h2
-rw-r--r--chrome/test/data/extensions/background_app/BackgroundApp.html11
-rw-r--r--chrome/test/data/extensions/background_app/BackgroundApp.js6
-rw-r--r--chrome/test/data/extensions/background_app/background.js39
-rw-r--r--chrome/test/data/extensions/background_app/manifest.json11
17 files changed, 241 insertions, 8 deletions
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index 1e54e65..8bb5d71 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -309,7 +309,12 @@ void BackgroundModeManager::Observe(
// treated as new installs.
if (extensions::ExtensionSystem::Get(profile)->extension_service()->
is_ready()) {
- OnBackgroundAppInstalled(extension);
+ bool is_being_reloaded = false;
+ CheckReloadStatus(extension, &is_being_reloaded);
+ // No need to show the notification if we showed to the user
+ // previously for this app.
+ if (!is_being_reloaded)
+ OnBackgroundAppInstalled(extension);
}
}
}
@@ -623,8 +628,25 @@ void BackgroundModeManager::OnBackgroundAppInstalled(
CreateStatusTrayIcon();
// Notify the user that a background app has been installed.
- if (extension) // NULL when called by unit tests.
+ if (extension) { // NULL when called by unit tests.
DisplayAppInstalledNotification(extension);
+ }
+}
+
+void BackgroundModeManager::CheckReloadStatus(
+ const Extension* extension,
+ bool* is_being_reloaded) {
+ // Walk the BackgroundModeData for all profiles to see if one of their
+ // extensions is being reloaded.
+ for (BackgroundModeInfoMap::const_iterator it =
+ background_mode_data_.begin();
+ it != background_mode_data_.end();
+ ++it) {
+ Profile* profile = it->first;
+ // If the extension is being reloaded, no need to show a notification.
+ if (profile->GetExtensionService()->IsBeingReloaded(extension->id()))
+ *is_being_reloaded = true;
+ }
}
void BackgroundModeManager::CreateStatusTrayIcon() {
diff --git a/chrome/browser/background/background_mode_manager.h b/chrome/browser/background/background_mode_manager.h
index 1600cd1..e1c8051 100644
--- a/chrome/browser/background/background_mode_manager.h
+++ b/chrome/browser/background/background_mode_manager.h
@@ -85,6 +85,9 @@ class BackgroundModeManager
ProfileInfoCacheStorage);
FRIEND_TEST_ALL_PREFIXES(BackgroundModeManagerTest,
ProfileInfoCacheObserver);
+ FRIEND_TEST_ALL_PREFIXES(BackgroundAppBrowserTest,
+ ReloadBackgroundApp);
+
class BackgroundModeData : public ui::SimpleMenuModel::Delegate {
public:
explicit BackgroundModeData(
@@ -183,7 +186,15 @@ class BackgroundModeManager
// Invoked when an extension is installed so we can ensure that
// launch-on-startup is enabled if appropriate. |extension| can be NULL when
// called from unit tests.
- void OnBackgroundAppInstalled(const extensions::Extension* extension);
+ void OnBackgroundAppInstalled(
+ const extensions::Extension* extension);
+
+ // Walk the list of profiles and see if an extension or app is being
+ // currently upgraded or reloaded by any profile. If so, update the
+ // output variables appropriately.
+ void CheckReloadStatus(
+ const extensions::Extension* extension,
+ bool* is_being_reloaded);
// Called to make sure that our launch-on-startup mode is properly set.
// (virtual so we can override for tests).
@@ -191,7 +202,8 @@ class BackgroundModeManager
// Invoked when a background app is installed so we can display a
// platform-specific notification to the user.
- void DisplayAppInstalledNotification(const extensions::Extension* extension);
+ virtual void DisplayAppInstalledNotification(
+ const extensions::Extension* extension);
// Invoked to put Chrome in KeepAlive mode - chrome runs in the background
// and has a status bar icon.
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index d6f8595..0824b1c 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -13,6 +13,7 @@
#include <string>
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/ui/host_desktop.h"
@@ -175,6 +176,8 @@ class BrowserProcess {
// Returns the object that manages background applications.
virtual BackgroundModeManager* background_mode_manager() = 0;
+ virtual void set_background_mode_manager_for_test(
+ scoped_ptr<BackgroundModeManager> manager) = 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
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 44bf2da..6673807 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -704,6 +704,11 @@ BackgroundModeManager* BrowserProcessImpl::background_mode_manager() {
#endif
}
+void BrowserProcessImpl::set_background_mode_manager_for_test(
+ scoped_ptr<BackgroundModeManager> manager) {
+ background_mode_manager_ = manager.Pass();
+}
+
StatusTray* BrowserProcessImpl::status_tray() {
DCHECK(CalledOnValidThread());
if (!status_tray_.get())
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 201eb92..020bd42 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -110,6 +110,8 @@ class BrowserProcessImpl : public BrowserProcess,
virtual DownloadStatusUpdater* download_status_updater() OVERRIDE;
virtual DownloadRequestLimiter* download_request_limiter() OVERRIDE;
virtual BackgroundModeManager* background_mode_manager() OVERRIDE;
+ virtual void set_background_mode_manager_for_test(
+ scoped_ptr<BackgroundModeManager> manager) OVERRIDE;
virtual StatusTray* status_tray() OVERRIDE;
virtual SafeBrowsingService* safe_browsing_service() OVERRIDE;
virtual safe_browsing::ClientSideDetectionService*
diff --git a/chrome/browser/extensions/background_app_browsertest.cc b/chrome/browser/extensions/background_app_browsertest.cc
new file mode 100644
index 0000000..7951e40
--- /dev/null
+++ b/chrome/browser/extensions/background_app_browsertest.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 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/background_mode_manager.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/test/base/ui_test_utils.h"
+
+class TestBackgroundModeManager : public BackgroundModeManager {
+ public:
+ TestBackgroundModeManager(CommandLine* command_line,
+ ProfileInfoCache* profile_cache)
+ : BackgroundModeManager(command_line, profile_cache),
+ showed_background_app_installed_notification_for_test_(false) {}
+
+ virtual ~TestBackgroundModeManager() {}
+
+ virtual void DisplayAppInstalledNotification(
+ const extensions::Extension* extension) OVERRIDE {
+ showed_background_app_installed_notification_for_test_ = true;
+ }
+
+ bool showed_background_app_installed_notification_for_test() {
+ return showed_background_app_installed_notification_for_test_;
+ }
+
+ void set_showed_background_app_installed_notification_for_test(
+ bool showed) {
+ showed_background_app_installed_notification_for_test_ = showed;
+ }
+
+ private:
+ // Tracks if we have shown a "Background App Installed" notification to the
+ // user. Used for unit tests only.
+ bool showed_background_app_installed_notification_for_test_;
+
+ FRIEND_TEST_ALL_PREFIXES(BackgroundAppBrowserTest,
+ ReloadBackgroundApp);
+
+ DISALLOW_COPY_AND_ASSIGN(TestBackgroundModeManager);
+};
+
+class BackgroundAppBrowserTest: public ExtensionBrowserTest {};
+
+// Tests that if we reload a background app, we don't get a popup bubble
+// telling us that a new background app has been installed.
+IN_PROC_BROWSER_TEST_F(BackgroundAppBrowserTest, ReloadBackgroundApp) {
+
+ // Pass this in to the browser test.
+ scoped_ptr<BackgroundModeManager> test_background_mode_manager(
+ new TestBackgroundModeManager(
+ CommandLine::ForCurrentProcess(),
+ &(g_browser_process->profile_manager()->GetProfileInfoCache())));
+ g_browser_process->set_background_mode_manager_for_test(
+ test_background_mode_manager.Pass());
+ TestBackgroundModeManager* manager =
+ reinterpret_cast<TestBackgroundModeManager*>(
+ g_browser_process->background_mode_manager());
+
+ // Load our background extension
+ ASSERT_FALSE(
+ manager->showed_background_app_installed_notification_for_test());
+ const extensions::Extension* extension = LoadExtension(
+ test_data_dir_.AppendASCII("background_app"));
+ ASSERT_FALSE(extension == NULL);
+
+ // Set the test flag to not shown.
+ manager->set_showed_background_app_installed_notification_for_test(false);
+
+ // Reload our background extension
+ ReloadExtension(extension->id());
+
+ // Ensure that we did not see a "Background extension loaded" dialog.
+ EXPECT_FALSE(
+ manager->showed_background_app_installed_notification_for_test());
+}
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index c2ec75b..126f27b 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -452,7 +452,7 @@ const Extension* ExtensionBrowserTest::InstallOrUpdateExtension(
return service->GetExtensionById(last_loaded_extension_id_, false);
}
-void ExtensionBrowserTest::ReloadExtension(const std::string& extension_id) {
+void ExtensionBrowserTest::ReloadExtension(const std::string extension_id) {
ExtensionService* service = extensions::ExtensionSystem::Get(
profile())->extension_service();
service->ReloadExtension(extension_id);
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h
index ef2b4c8..2b750c3 100644
--- a/chrome/browser/extensions/extension_browsertest.h
+++ b/chrome/browser/extensions/extension_browsertest.h
@@ -170,7 +170,7 @@ class ExtensionBrowserTest : virtual public InProcessBrowserTest,
std::string(), path, INSTALL_UI_TYPE_CANCEL, 0);
}
- void ReloadExtension(const std::string& extension_id);
+ void ReloadExtension(const std::string extension_id);
void UnloadExtension(const std::string& extension_id);
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index ab91a0b..2458305f 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -669,7 +669,7 @@ bool ExtensionService::UpdateExtension(const std::string& id,
return true;
}
-void ExtensionService::ReloadExtension(const std::string& extension_id) {
+void ExtensionService::ReloadExtension(const std::string extension_id) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// If the extension is already reloading, don't reload again.
@@ -713,12 +713,15 @@ void ExtensionService::ReloadExtension(const std::string& extension_id) {
// If we're reloading a component extension, use the component extension
// loader's reloader.
if (component_loader_->Exists(extension_id)) {
+ SetBeingReloaded(extension_id, true);
component_loader_->Reload(extension_id);
+ SetBeingReloaded(extension_id, false);
return;
}
// Check the installed extensions to see if what we're reloading was already
// installed.
+ SetBeingReloaded(extension_id, true);
scoped_ptr<ExtensionInfo> installed_extension(
extension_prefs_->GetInstalledExtensionInfo(extension_id));
if (installed_extension.get() &&
@@ -731,6 +734,8 @@ void ExtensionService::ReloadExtension(const std::string& extension_id) {
CHECK(!path.empty());
extensions::UnpackedInstaller::Create(this)->Load(path);
}
+ // When reloading is done, mark this extension as done reloading.
+ SetBeingReloaded(extension_id, false);
}
bool ExtensionService::UninstallExtension(
@@ -2863,6 +2868,27 @@ void ExtensionService::SetBeingUpgraded(const Extension* extension,
extension_runtime_data_[extension->id()].being_upgraded = value;
}
+bool ExtensionService::IsBeingReloaded(
+ const std::string& extension_id) const {
+ return ContainsKey(extensions_being_reloaded_, extension_id);
+}
+
+void ExtensionService::SetBeingReloaded(const std::string& extension_id,
+ bool isBeingReloaded) {
+ LOG(INFO) << "****** " << __FUNCTION__;
+ LOG(INFO) << "****** " << __FUNCTION__ << " extension_id is: "
+ << extension_id << " and isBeingReloaded is " << isBeingReloaded;
+ LOG(INFO) << "****** " << __FUNCTION__ << " Set size is "
+ << extensions_being_reloaded_.size();
+ if (isBeingReloaded) {
+ extensions_being_reloaded_.insert(extension_id);
+ LOG(INFO) << "****** " << __FUNCTION__ << " insert succeeded.";
+ } else {
+ extensions_being_reloaded_.erase(extension_id);
+ LOG(INFO) << "****** " << __FUNCTION__ << " erase succeeded.";
+ }
+}
+
bool ExtensionService::HasUsedWebRequest(const Extension* extension) const {
ExtensionRuntimeDataMap::const_iterator it =
extension_runtime_data_.find(extension->id());
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index b21c86a..8d0c6c3 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -249,6 +249,11 @@ class ExtensionService
bool IsBeingUpgraded(const extensions::Extension* extension) const;
void SetBeingUpgraded(const extensions::Extension* extension, bool value);
+ // Getter and setter for the flag that specifies whether the extension is
+ // being reloaded.
+ bool IsBeingReloaded(const std::string& extension_name) const;
+ void SetBeingReloaded(const std::string& extension_id, bool value);
+
// Getter and setter for the flag that specifies if the extension has used
// the webrequest API.
// TODO(mpcomplete): remove. http://crbug.com/100411
@@ -311,7 +316,7 @@ class ExtensionService
// Reloads the specified extension, sending the onLaunched() event to it if it
// currently has any window showing.
- void ReloadExtension(const std::string& extension_id);
+ void ReloadExtension(const std::string extension_id);
// Uninstalls the specified extension. Callers should only call this method
// with extensions that exist. |external_uninstall| is a magical parameter
@@ -917,6 +922,10 @@ class ExtensionService
extensions::ProcessMap process_map_;
+ // A set of the extension ids currently being reloaded. We use this to
+ // avoid showing a "new install" notice for an extension reinstall.
+ std::set<std::string> extensions_being_reloaded_;
+
scoped_ptr<ExtensionErrorUI> extension_error_ui_;
// Sequenced task runner for extension related file operations.
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index d08550c..0521450 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1380,6 +1380,7 @@
'browser/extensions/api/webstore_private/webstore_private_apitest.cc',
'browser/extensions/app_background_page_apitest.cc',
'browser/extensions/app_process_apitest.cc',
+ 'browser/extensions/background_app_browsertest.cc',
'browser/extensions/background_page_apitest.cc',
'browser/extensions/background_scripts_apitest.cc',
'browser/extensions/chrome_app_api_browsertest.cc',
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 3fe39f2..ea1469b 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -7,6 +7,7 @@
#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
+#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
@@ -149,6 +150,11 @@ BackgroundModeManager* TestingBrowserProcess::background_mode_manager() {
return NULL;
}
+void TestingBrowserProcess::set_background_mode_manager_for_test(
+ scoped_ptr<BackgroundModeManager> manager) {
+ NOTREACHED();
+}
+
StatusTray* TestingBrowserProcess::status_tray() {
return NULL;
}
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h
index 300f192..983d766 100644
--- a/chrome/test/base/testing_browser_process.h
+++ b/chrome/test/base/testing_browser_process.h
@@ -62,6 +62,8 @@ class TestingBrowserProcess : public BrowserProcess {
virtual GpuModeManager* gpu_mode_manager() OVERRIDE;
virtual RenderWidgetSnapshotTaker* GetRenderWidgetSnapshotTaker() OVERRIDE;
virtual BackgroundModeManager* background_mode_manager() OVERRIDE;
+ virtual void set_background_mode_manager_for_test(
+ scoped_ptr<BackgroundModeManager> manager) OVERRIDE;
virtual StatusTray* status_tray() OVERRIDE;
virtual SafeBrowsingService* safe_browsing_service() OVERRIDE;
virtual safe_browsing::ClientSideDetectionService*
diff --git a/chrome/test/data/extensions/background_app/BackgroundApp.html b/chrome/test/data/extensions/background_app/BackgroundApp.html
new file mode 100644
index 0000000..dad2443
--- /dev/null
+++ b/chrome/test/data/extensions/background_app/BackgroundApp.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Background App Popup</title>
+ <!-- JavaScript and HTML must be in separate files for security. -->
+ <script src="BackgroundApp.js"></script>
+ </head>
+ <body>
+ Simple Background App
+ </body>
+</html>
diff --git a/chrome/test/data/extensions/background_app/BackgroundApp.js b/chrome/test/data/extensions/background_app/BackgroundApp.js
new file mode 100644
index 0000000..d5ee7e2
--- /dev/null
+++ b/chrome/test/data/extensions/background_app/BackgroundApp.js
@@ -0,0 +1,6 @@
+// Copyright 2013 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.
+
+// This is a simple v2 app with background permission and a background script.
+
diff --git a/chrome/test/data/extensions/background_app/background.js b/chrome/test/data/extensions/background_app/background.js
new file mode 100644
index 0000000..77efd49
--- /dev/null
+++ b/chrome/test/data/extensions/background_app/background.js
@@ -0,0 +1,39 @@
+// Copyright 2013 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.
+
+// This is a minimal sample of a Apps V2 app with background permission.
+//
+// This function gets called in the packaged app model on launch.
+chrome.app.runtime.onLaunched.addListener(function() {
+ console.log("Background App Launched!");
+
+ // We'll set up push messaging so we have something to keep the background
+ // app registered.
+ setupPush();
+});
+
+// This function gets called in the packaged app model on install.
+chrome.runtime.onInstalled.addListener(function() {
+ console.log("Background App installed!");
+});
+
+// This function gets called in the packaged app model on shutdown.
+chrome.runtime.onSuspend.addListener(function() {
+ console.log("Background App shutting down");
+});
+
+// Register for push messages.
+// This should be called every time the Push Messaging App starts up.
+function setupPush() {
+ chrome.pushMessaging.onMessage.addListener(messageCallback);
+
+ // Ensure that adding the listener took effect.
+ var listeners = chrome.pushMessaging.onMessage.hasListeners();
+ console.log('registered listener for push messages ' + listeners);
+}
+
+// This callback recieves the pushed message from the push server.
+function messageCallback(message) {
+ console.log("push messaging callback seen");
+}
diff --git a/chrome/test/data/extensions/background_app/manifest.json b/chrome/test/data/extensions/background_app/manifest.json
new file mode 100644
index 0000000..eb2ecc3
--- /dev/null
+++ b/chrome/test/data/extensions/background_app/manifest.json
@@ -0,0 +1,11 @@
+{
+ "background": {
+ "scripts": [ "background.js" ]
+ },
+ "description": "A simple app with background permission set.",
+ "manifest_version": 2,
+ "name": "Background App",
+ "permissions": [ "background" ],
+ "update_url": "http://clients2.google.com/service/update2/crx",
+ "version": "1.2"
+}