summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlimasdf@gmail.com <limasdf@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-22 08:45:15 +0000
committerlimasdf@gmail.com <limasdf@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-22 08:45:15 +0000
commit17f07823f46562542f60361beffe217b6bc94a77 (patch)
tree96121bbabec15b17a2b8b7890f30a53b72e4d6d3
parentb1712ec30f0518ba9ed02a0eed88a89cc7ab00b3 (diff)
downloadchromium_src-17f07823f46562542f60361beffe217b6bc94a77.zip
chromium_src-17f07823f46562542f60361beffe217b6bc94a77.tar.gz
chromium_src-17f07823f46562542f60361beffe217b6bc94a77.tar.bz2
Add a function triggering extension installed to ExtensionRegistryObserver.
This can be replace chrome::NOTIFICATION_EXTENSION_INSTALLED with ExtensionRegistryObserver. And apply it to WebStoreInstaller and InstallTracker. R=kalman@chromium.org BUG=354459 TEST=unit_test, manual(install app from webstore) Review URL: https://codereview.chromium.org/279073003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272143 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_service.cc3
-rw-r--r--chrome/browser/extensions/install_tracker.cc45
-rw-r--r--chrome/browser/extensions/install_tracker.h8
-rw-r--r--chrome/browser/extensions/webstore_installer.cc74
-rw-r--r--chrome/browser/extensions/webstore_installer.h18
-rw-r--r--extensions/browser/extension_registry.cc12
-rw-r--r--extensions/browser/extension_registry.h8
-rw-r--r--extensions/browser/extension_registry_observer.h15
-rw-r--r--extensions/browser/extension_registry_unittest.cc18
9 files changed, 138 insertions, 63 deletions
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 702b7fc..cfb45b9 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -1935,6 +1935,9 @@ void ExtensionService::FinishInstallation(const Extension* extension) {
content::Source<Profile>(profile_),
content::Details<const extensions::InstalledExtensionInfo>(&details));
+ ExtensionRegistry::Get(profile_)
+ ->TriggerOnWillBeInstalled(extension, is_update, old_name);
+
bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension);
// Unpacked extensions default to allowing file access, but if that has been
diff --git a/chrome/browser/extensions/install_tracker.cc b/chrome/browser/extensions/install_tracker.cc
index 81e72fed..09eec52 100644
--- a/chrome/browser/extensions/install_tracker.cc
+++ b/chrome/browser/extensions/install_tracker.cc
@@ -21,8 +21,6 @@ InstallTracker::InstallTracker(Profile* profile,
: extension_registry_observer_(this) {
extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
- content::Source<Profile>(profile));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile));
registrar_.Add(this,
@@ -95,31 +93,10 @@ void InstallTracker::Shutdown() {
FOR_EACH_OBSERVER(InstallObserver, observers_, OnShutdown());
}
-void InstallTracker::OnExtensionLoaded(content::BrowserContext* browser_context,
- const Extension* extension) {
- FOR_EACH_OBSERVER(InstallObserver, observers_, OnExtensionLoaded(extension));
-}
-
-void InstallTracker::OnExtensionUnloaded(
- content::BrowserContext* browser_context,
- const Extension* extension,
- UnloadedExtensionInfo::Reason reason) {
- FOR_EACH_OBSERVER(
- InstallObserver, observers_, OnExtensionUnloaded(extension));
-}
-
void InstallTracker::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
- const Extension* extension =
- content::Details<const InstalledExtensionInfo>(details).ptr()->
- extension;
- FOR_EACH_OBSERVER(InstallObserver, observers_,
- OnExtensionInstalled(extension));
- break;
- }
case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
const Extension* extension =
content::Details<const Extension>(details).ptr();
@@ -151,6 +128,28 @@ void InstallTracker::Observe(int type,
}
}
+void InstallTracker::OnExtensionLoaded(content::BrowserContext* browser_context,
+ const Extension* extension) {
+ FOR_EACH_OBSERVER(InstallObserver, observers_, OnExtensionLoaded(extension));
+}
+
+void InstallTracker::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ FOR_EACH_OBSERVER(
+ InstallObserver, observers_, OnExtensionUnloaded(extension));
+}
+
+void InstallTracker::OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ const std::string& old_name) {
+ FOR_EACH_OBSERVER(
+ InstallObserver, observers_, OnExtensionInstalled(extension));
+}
+
void InstallTracker::OnAppsReordered() {
FOR_EACH_OBSERVER(InstallObserver, observers_, OnAppsReordered());
}
diff --git a/chrome/browser/extensions/install_tracker.h b/chrome/browser/extensions/install_tracker.h
index 8342ec9..6728cf6 100644
--- a/chrome/browser/extensions/install_tracker.h
+++ b/chrome/browser/extensions/install_tracker.h
@@ -53,7 +53,7 @@ class InstallTracker : public KeyedService,
private:
void OnAppsReordered();
- // content::NotificationObserver.
+ // content::NotificationObserver implementation.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
@@ -65,12 +65,16 @@ class InstallTracker : public KeyedService,
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) OVERRIDE;
+ virtual void OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ const std::string& old_name) OVERRIDE;
ObserverList<InstallObserver> observers_;
content::NotificationRegistrar registrar_;
PrefChangeRegistrar pref_change_registrar_;
- // Listen to extension load, unloaded notifications.
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
diff --git a/chrome/browser/extensions/webstore_installer.cc b/chrome/browser/extensions/webstore_installer.cc
index 95b961a..512d008 100644
--- a/chrome/browser/extensions/webstore_installer.cc
+++ b/chrome/browser/extensions/webstore_installer.cc
@@ -48,6 +48,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
@@ -277,6 +278,7 @@ WebstoreInstaller::WebstoreInstaller(Profile* profile,
scoped_ptr<Approval> approval,
InstallSource source)
: content::WebContentsObserver(web_contents),
+ extension_registry_observer_(this),
profile_(profile),
delegate_(delegate),
id_(id),
@@ -290,10 +292,9 @@ WebstoreInstaller::WebstoreInstaller(Profile* profile,
registrar_.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
- content::Source<Profile>(profile->GetOriginalProfile()));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
content::Source<CrxInstaller>(NULL));
+ extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
}
void WebstoreInstaller::Start() {
@@ -375,40 +376,6 @@ void WebstoreInstaller::Observe(int type,
break;
}
- case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
- CHECK(profile_->IsSameProfile(content::Source<Profile>(source).ptr()));
- const Extension* extension =
- content::Details<const InstalledExtensionInfo>(details)->extension;
- if (pending_modules_.empty())
- return;
- SharedModuleInfo::ImportInfo info = pending_modules_.front();
- if (extension->id() != info.extension_id)
- return;
- pending_modules_.pop_front();
-
- if (pending_modules_.empty()) {
- CHECK_EQ(extension->id(), id_);
- ReportSuccess();
- } else {
- const Version version_required(info.minimum_version);
- if (version_required.IsValid() &&
- extension->version()->CompareTo(version_required) < 0) {
- // It should not happen, CrxInstaller will make sure the version is
- // equal or newer than version_required.
- ReportFailure(kDependencyNotFoundError,
- FAILURE_REASON_DEPENDENCY_NOT_FOUND);
- } else if (!SharedModuleInfo::IsSharedModule(extension)) {
- // It should not happen, CrxInstaller will make sure it is a shared
- // module.
- ReportFailure(kDependencyNotSharedModuleError,
- FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE);
- } else {
- DownloadNextPendingModule();
- }
- }
- break;
- }
-
case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: {
CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr();
CHECK(crx_installer);
@@ -432,6 +399,41 @@ void WebstoreInstaller::Observe(int type,
}
}
+void WebstoreInstaller::OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ const std::string& old_name) {
+ CHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
+ if (pending_modules_.empty())
+ return;
+ SharedModuleInfo::ImportInfo info = pending_modules_.front();
+ if (extension->id() != info.extension_id)
+ return;
+ pending_modules_.pop_front();
+
+ if (pending_modules_.empty()) {
+ CHECK_EQ(extension->id(), id_);
+ ReportSuccess();
+ } else {
+ const Version version_required(info.minimum_version);
+ if (version_required.IsValid() &&
+ extension->version()->CompareTo(version_required) < 0) {
+ // It should not happen, CrxInstaller will make sure the version is
+ // equal or newer than version_required.
+ ReportFailure(kDependencyNotFoundError,
+ FAILURE_REASON_DEPENDENCY_NOT_FOUND);
+ } else if (!SharedModuleInfo::IsSharedModule(extension)) {
+ // It should not happen, CrxInstaller will make sure it is a shared
+ // module.
+ ReportFailure(kDependencyNotSharedModuleError,
+ FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE);
+ } else {
+ DownloadNextPendingModule();
+ }
+ }
+}
+
void WebstoreInstaller::InvalidateDelegate() {
delegate_ = NULL;
}
diff --git a/chrome/browser/extensions/webstore_installer.h b/chrome/browser/extensions/webstore_installer.h
index c0e2d50..c2d1646 100644
--- a/chrome/browser/extensions/webstore_installer.h
+++ b/chrome/browser/extensions/webstore_installer.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/scoped_observer.h"
#include "base/supports_user_data.h"
#include "base/timer/timer.h"
#include "base/values.h"
@@ -22,6 +23,7 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
+#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/manifest_handlers/shared_module_info.h"
#include "ui/gfx/image/image_skia.h"
#include "url/gurl.h"
@@ -40,14 +42,17 @@ namespace extensions {
class CrxInstaller;
class Extension;
+class ExtensionRegistry;
class Manifest;
// Downloads and installs extensions from the web store.
class WebstoreInstaller : public content::NotificationObserver,
+ public ExtensionRegistryObserver,
public content::DownloadItem::Observer,
public content::WebContentsObserver,
public base::RefCountedThreadSafe<
- WebstoreInstaller, content::BrowserThread::DeleteOnUIThread> {
+ WebstoreInstaller,
+ content::BrowserThread::DeleteOnUIThread> {
public:
enum InstallSource {
// Inline installs trigger slightly different behavior (install source
@@ -188,11 +193,18 @@ class WebstoreInstaller : public content::NotificationObserver,
// Starts downloading and installing the extension.
void Start();
- // content::NotificationObserver
+ // content::NotificationObserver.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // ExtensionRegistryObserver.
+ virtual void OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ const std::string& old_name) OVERRIDE;
+
// Removes the reference to the delegate passed in the constructor. Used when
// the delegate object must be deleted before this object.
void InvalidateDelegate();
@@ -249,6 +261,8 @@ class WebstoreInstaller : public content::NotificationObserver,
void RecordInterrupt(const content::DownloadItem* download) const;
content::NotificationRegistrar registrar_;
+ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+ extension_registry_observer_;
Profile* profile_;
Delegate* delegate_;
std::string id_;
diff --git a/extensions/browser/extension_registry.cc b/extensions/browser/extension_registry.cc
index ac6c274..76783f0 100644
--- a/extensions/browser/extension_registry.cc
+++ b/extensions/browser/extension_registry.cc
@@ -53,6 +53,18 @@ void ExtensionRegistry::TriggerOnUnloaded(
OnExtensionUnloaded(browser_context_, extension, reason));
}
+void ExtensionRegistry::TriggerOnWillBeInstalled(const Extension* extension,
+ bool is_update,
+ const std::string& old_name) {
+ DCHECK(is_update ==
+ GenerateInstalledExtensionsSet()->Contains(extension->id()));
+ DCHECK(is_update == !old_name.empty());
+ FOR_EACH_OBSERVER(ExtensionRegistryObserver,
+ observers_,
+ OnExtensionWillBeInstalled(
+ browser_context_, extension, is_update, old_name));
+}
+
const Extension* ExtensionRegistry::GetExtensionById(const std::string& id,
int include_mask) const {
std::string lowercase_id = StringToLowerASCII(id);
diff --git a/extensions/browser/extension_registry.h b/extensions/browser/extension_registry.h
index d8df24b..65ee751 100644
--- a/extensions/browser/extension_registry.h
+++ b/extensions/browser/extension_registry.h
@@ -74,6 +74,14 @@ class ExtensionRegistry : public KeyedService {
void TriggerOnUnloaded(const Extension* extension,
UnloadedExtensionInfo::Reason reason);
+ // If this is a fresh install then |is_update| is false and there must not be
+ // any installed extension with |extension|'s ID. If this is an update then
+ // |is_update| is true and must be an installed extension with |extension|'s
+ // ID, and |old_name| must be non-empty.
+ void TriggerOnWillBeInstalled(const Extension* extension,
+ bool is_update,
+ const std::string& old_name);
+
// Find an extension by ID using |include_mask| to pick the sets to search:
// * enabled_extensions() --> ExtensionRegistry::ENABLED
// * disabled_extensions() --> ExtensionRegistry::DISABLED
diff --git a/extensions/browser/extension_registry_observer.h b/extensions/browser/extension_registry_observer.h
index 5880add..6ad0666 100644
--- a/extensions/browser/extension_registry_observer.h
+++ b/extensions/browser/extension_registry_observer.h
@@ -33,6 +33,21 @@ class ExtensionRegistryObserver {
virtual void OnExtensionUnloaded(content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {}
+
+ // Called when |extension| is about to be installed. |is_update| is true if
+ // the installation is the result of it updating, in which case |old_name| is
+ // the name of the extension's previous version.
+ // The ExtensionRegistry will not be tracking |extension| at the time this
+ // event is fired, but will be immediately afterwards (note: not necessarily
+ // enabled; it might be installed in the disabled or even blacklisted sets,
+ // for example).
+ // Note that it's much more common to care about extensions being loaded
+ // (OnExtensionLoaded).
+ virtual void OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ const std::string& old_name) {}
};
} // namespace extensions
diff --git a/extensions/browser/extension_registry_unittest.cc b/extensions/browser/extension_registry_unittest.cc
index f212f6c..8281ee0 100644
--- a/extensions/browser/extension_registry_unittest.cc
+++ b/extensions/browser/extension_registry_unittest.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/memory/ref_counted.h"
+#include "base/strings/string_util.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension.h"
#include "extensions/common/test_util.h"
@@ -37,10 +38,12 @@ class TestObserver : public ExtensionRegistryObserver {
void Reset() {
loaded_.clear();
unloaded_.clear();
+ installed_.clear();
}
const ExtensionList& loaded() { return loaded_; }
const ExtensionList& unloaded() { return unloaded_; }
+ const ExtensionList& installed() { return installed_; }
private:
virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
@@ -55,8 +58,17 @@ class TestObserver : public ExtensionRegistryObserver {
unloaded_.push_back(extension);
}
+ virtual void OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ const std::string& old_name) OVERRIDE {
+ installed_.push_back(extension);
+ }
+
ExtensionList loaded_;
ExtensionList unloaded_;
+ ExtensionList installed_;
};
TEST_F(ExtensionRegistryTest, FillAndClearRegistry) {
@@ -215,13 +227,19 @@ TEST_F(ExtensionRegistryTest, Observer) {
EXPECT_TRUE(observer.loaded().empty());
EXPECT_TRUE(observer.unloaded().empty());
+ EXPECT_TRUE(observer.installed().empty());
scoped_refptr<const Extension> extension =
test_util::CreateExtensionWithID("id");
+ registry.TriggerOnWillBeInstalled(extension, false, base::EmptyString());
+ EXPECT_TRUE(HasSingleExtension(observer.installed(), extension.get()));
+
registry.AddEnabled(extension);
registry.TriggerOnLoaded(extension);
+ registry.TriggerOnWillBeInstalled(extension, true, "foo");
+
EXPECT_TRUE(HasSingleExtension(observer.loaded(), extension.get()));
EXPECT_TRUE(observer.unloaded().empty());
observer.Reset();