Prune shared extension module after extension updating.

When an extension is updated, the imported module of the extension could be changed in the new version. If the imported modules are removed in the new version, we need check and remove the shared modules if necessary.

BUG=393232

Review URL: https://codereview.chromium.org/386033002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283574 0039d316-1c4b-4281-b951-d872f2087c98
parent 6fa58150
...@@ -221,7 +221,8 @@ void DriveAppProvider::OnDriveAppRegistryUpdated() { ...@@ -221,7 +221,8 @@ void DriveAppProvider::OnDriveAppRegistryUpdated() {
void DriveAppProvider::OnExtensionInstalled( void DriveAppProvider::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension) { const Extension* extension,
bool is_update) {
// Bail if the |extension| is installed from a converter. The post install // Bail if the |extension| is installed from a converter. The post install
// processing will be handled in OnLocalAppConverted. // processing will be handled in OnLocalAppConverted.
if (!pending_converters_.empty() && if (!pending_converters_.empty() &&
......
...@@ -74,7 +74,8 @@ class DriveAppProvider : public drive::DriveAppRegistryObserver, ...@@ -74,7 +74,8 @@ class DriveAppProvider : public drive::DriveAppRegistryObserver,
// extensions::ExtensionRegistryObserver overrides: // extensions::ExtensionRegistryObserver overrides:
virtual void OnExtensionInstalled( virtual void OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled( virtual void OnExtensionUninstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension) OVERRIDE;
......
...@@ -947,7 +947,8 @@ void ManagementEventRouter::OnExtensionUnloaded( ...@@ -947,7 +947,8 @@ void ManagementEventRouter::OnExtensionUnloaded(
void ManagementEventRouter::OnExtensionInstalled( void ManagementEventRouter::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension) { const Extension* extension,
bool is_update) {
BroadcastEvent(extension, management::OnInstalled::kEventName); BroadcastEvent(extension, management::OnInstalled::kEventName);
} }
......
...@@ -245,7 +245,8 @@ class ManagementEventRouter : public ExtensionRegistryObserver { ...@@ -245,7 +245,8 @@ class ManagementEventRouter : public ExtensionRegistryObserver {
const Extension* extension, const Extension* extension,
UnloadedExtensionInfo::Reason reason) OVERRIDE; UnloadedExtensionInfo::Reason reason) OVERRIDE;
virtual void OnExtensionInstalled(content::BrowserContext* browser_context, virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
......
...@@ -226,7 +226,8 @@ void ErrorConsole::OnExtensionLoaded(content::BrowserContext* browser_context, ...@@ -226,7 +226,8 @@ void ErrorConsole::OnExtensionLoaded(content::BrowserContext* browser_context,
void ErrorConsole::OnExtensionInstalled( void ErrorConsole::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension) { const Extension* extension,
bool is_update) {
// We don't want to have manifest errors from previous installs. We want // We don't want to have manifest errors from previous installs. We want
// to keep runtime errors, though, because extensions are reloaded on a // to keep runtime errors, though, because extensions are reloaded on a
// refresh of chrome:extensions, and we don't want to wipe our history // refresh of chrome:extensions, and we don't want to wipe our history
......
...@@ -133,7 +133,8 @@ class ErrorConsole : public content::NotificationObserver, ...@@ -133,7 +133,8 @@ class ErrorConsole : public content::NotificationObserver,
virtual void OnExtensionLoaded(content::BrowserContext* browser_context, virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
virtual void OnExtensionInstalled(content::BrowserContext* browser_context, virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
......
...@@ -1820,7 +1820,7 @@ void ExtensionService::FinishInstallation( ...@@ -1820,7 +1820,7 @@ void ExtensionService::FinishInstallation(
AddExtension(extension); AddExtension(extension);
// Notify observers that need to know when an installation is complete. // Notify observers that need to know when an installation is complete.
registry_->TriggerOnInstalled(extension); registry_->TriggerOnInstalled(extension, is_update);
// Check extensions that may have been delayed only because this shared module // Check extensions that may have been delayed only because this shared module
// was not available. // was not available.
...@@ -1878,7 +1878,7 @@ void ExtensionService::PromoteEphemeralApp( ...@@ -1878,7 +1878,7 @@ void ExtensionService::PromoteEphemeralApp(
registry_->TriggerOnLoaded(extension); registry_->TriggerOnLoaded(extension);
} }
registry_->TriggerOnInstalled(extension); registry_->TriggerOnInstalled(extension, true);
if (!is_from_sync && extension_sync_service_) if (!is_from_sync && extension_sync_service_)
extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); extension_sync_service_->SyncExtensionChangeIfNeeded(*extension);
......
...@@ -175,7 +175,8 @@ void ExternalInstallManager::OnExtensionLoaded( ...@@ -175,7 +175,8 @@ void ExternalInstallManager::OnExtensionLoaded(
void ExternalInstallManager::OnExtensionInstalled( void ExternalInstallManager::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension) { const Extension* extension,
bool is_update) {
// Certain extension locations are specific enough that we can // Certain extension locations are specific enough that we can
// auto-acknowledge any extension that came from one of them. // auto-acknowledge any extension that came from one of them.
if (Manifest::IsPolicyLocation(extension->location()) || if (Manifest::IsPolicyLocation(extension->location()) ||
......
...@@ -59,7 +59,8 @@ class ExternalInstallManager : public ExtensionRegistryObserver, ...@@ -59,7 +59,8 @@ class ExternalInstallManager : public ExtensionRegistryObserver,
virtual void OnExtensionLoaded(content::BrowserContext* browser_context, virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
virtual void OnExtensionInstalled(content::BrowserContext* browser_context, virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/extensions/shared_module_service.h" #include "chrome/browser/extensions/shared_module_service.h"
#include <set>
#include <vector> #include <vector>
#include "base/version.h" #include "base/version.h"
...@@ -130,35 +131,58 @@ scoped_ptr<ExtensionSet> SharedModuleService::GetDependentExtensions( ...@@ -130,35 +131,58 @@ scoped_ptr<ExtensionSet> SharedModuleService::GetDependentExtensions(
return dependents.PassAs<ExtensionSet>(); return dependents.PassAs<ExtensionSet>();
} }
void SharedModuleService::OnExtensionUninstalled( void SharedModuleService::PruneSharedModules() {
content::BrowserContext* browser_context,
const Extension* extension) {
// Uninstalls shared modules that were only referenced by |extension|.
if (!SharedModuleInfo::ImportsModules(extension))
return;
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
ExtensionService* service = ExtensionService* service =
ExtensionSystem::Get(browser_context_)->extension_service(); ExtensionSystem::Get(browser_context_)->extension_service();
const ImportInfoVector& imports = SharedModuleInfo::GetImports(extension); ExtensionSet set_to_check;
for (ImportInfoVector::const_iterator iter = imports.begin(); set_to_check.InsertAll(registry->enabled_extensions());
iter != imports.end(); set_to_check.InsertAll(registry->disabled_extensions());
set_to_check.InsertAll(*service->delayed_installs());
std::vector<std::string> shared_modules;
std::set<std::string> used_shared_modules;
for (ExtensionSet::const_iterator iter = set_to_check.begin();
iter != set_to_check.end();
++iter) { ++iter) {
const Extension* imported_module = if (SharedModuleInfo::IsSharedModule(iter->get()))
registry->GetExtensionById(iter->extension_id, shared_modules.push_back(iter->get()->id());
ExtensionRegistry::EVERYTHING);
if (imported_module && imported_module->from_webstore()) { const ImportInfoVector& imports = SharedModuleInfo::GetImports(iter->get());
scoped_ptr<ExtensionSet> dependents = for (ImportInfoVector::const_iterator imports_iter = imports.begin();
GetDependentExtensions(imported_module); imports_iter != imports.end();
if (dependents->is_empty()) { ++imports_iter) {
service->UninstallExtension( used_shared_modules.insert(imports_iter->extension_id);
iter->extension_id,
ExtensionService::UNINSTALL_REASON_ORPHANED_SHARED_MODULE,
NULL); // Ignore error.
}
} }
} }
std::vector<std::string>::const_iterator shared_modules_iter;
for (shared_modules_iter = shared_modules.begin();
shared_modules_iter != shared_modules.end();
shared_modules_iter++) {
if (used_shared_modules.count(*shared_modules_iter))
continue;
service->UninstallExtension(
*shared_modules_iter,
ExtensionService::UNINSTALL_REASON_ORPHANED_SHARED_MODULE,
NULL); // Ignore error.
}
}
void SharedModuleService::OnExtensionInstalled(
content::BrowserContext* browser_context,
const Extension* extension,
bool is_update) {
if (is_update)
PruneSharedModules();
}
void SharedModuleService::OnExtensionUninstalled(
content::BrowserContext* browser_context,
const Extension* extension) {
PruneSharedModules();
} }
} // namespace extensions } // namespace extensions
...@@ -55,7 +55,13 @@ class SharedModuleService : public ExtensionRegistryObserver { ...@@ -55,7 +55,13 @@ class SharedModuleService : public ExtensionRegistryObserver {
scoped_ptr<ExtensionSet> GetDependentExtensions(const Extension* extension); scoped_ptr<ExtensionSet> GetDependentExtensions(const Extension* extension);
private: private:
// Uninstall shared modules which are not used by other extensions.
void PruneSharedModules();
// ExtensionRegistryObserver implementation. // ExtensionRegistryObserver implementation.
virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
......
...@@ -25,15 +25,18 @@ namespace { ...@@ -25,15 +25,18 @@ namespace {
// Return an extension with |id| which imports a module with the given // Return an extension with |id| which imports a module with the given
// |import_id|. // |import_id|.
scoped_refptr<Extension> CreateExtensionImportingModule( scoped_refptr<Extension> CreateExtensionImportingModule(
const std::string& import_id, const std::string& id) { const std::string& import_id,
scoped_ptr<base::DictionaryValue> manifest = const std::string& id,
DictionaryBuilder() const std::string& version) {
.Set("name", "Has Dependent Modules") DictionaryBuilder builder;
.Set("version", "1.0") builder.Set("name", "Has Dependent Modules")
.Set("manifest_version", 2) .Set("version", version)
.Set("import", .Set("manifest_version", 2);
ListBuilder().Append(DictionaryBuilder().Set("id", import_id))) if (!import_id.empty()) {
.Build(); builder.Set("import",
ListBuilder().Append(DictionaryBuilder().Set("id", import_id)));
}
scoped_ptr<base::DictionaryValue> manifest = builder.Build();
return ExtensionBuilder().SetManifest(manifest.Pass()) return ExtensionBuilder().SetManifest(manifest.Pass())
.AddFlags(Extension::FROM_WEBSTORE) .AddFlags(Extension::FROM_WEBSTORE)
...@@ -53,27 +56,37 @@ class SharedModuleServiceUnitTest : public ExtensionServiceTestBase { ...@@ -53,27 +56,37 @@ class SharedModuleServiceUnitTest : public ExtensionServiceTestBase {
virtual void SetUp() OVERRIDE; virtual void SetUp() OVERRIDE;
// Install an extension and notify the ExtensionService. // Install an extension and notify the ExtensionService.
testing::AssertionResult InstallExtension(const Extension* extension); testing::AssertionResult InstallExtension(const Extension* extension,
bool is_update);
ScopedCurrentChannel current_channel_; ScopedCurrentChannel current_channel_;
}; };
void SharedModuleServiceUnitTest::SetUp() { void SharedModuleServiceUnitTest::SetUp() {
ExtensionServiceTestBase::SetUp(); ExtensionServiceTestBase::SetUp();
InitializeGoodInstalledExtensionService(); InitializeGoodInstalledExtensionService();
service_->Init(); service()->Init();
} }
testing::AssertionResult SharedModuleServiceUnitTest::InstallExtension( testing::AssertionResult SharedModuleServiceUnitTest::InstallExtension(
const Extension* extension) { const Extension* extension,
// Verify the extension is not already installed. bool is_update) {
if (registry()->GetExtensionById(extension->id(),
ExtensionRegistry::ENABLED)) { const Extension* old = registry()->GetExtensionById(
return testing::AssertionFailure() << "Extension already installed."; extension->id(),
ExtensionRegistry::ENABLED);
// Verify the extension is not already installed, if it is not update.
if (!is_update) {
if (old)
return testing::AssertionFailure() << "Extension already installed.";
} else {
if (!old)
return testing::AssertionFailure() << "The extension does not exist.";
} }
// Notify the service that the extension is installed. This adds it to the // Notify the service that the extension is installed. This adds it to the
// registry, notifies interested parties, etc. // registry, notifies interested parties, etc.
service_->OnExtensionInstalled( service()->OnExtensionInstalled(
extension, syncer::StringOrdinal(), kInstallFlagInstallImmediately); extension, syncer::StringOrdinal(), kInstallFlagInstallImmediately);
// Verify that the extension is now installed. // Verify that the extension is now installed.
...@@ -90,17 +103,17 @@ TEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) { ...@@ -90,17 +103,17 @@ TEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) {
std::string import_id = id_util::GenerateId("id"); std::string import_id = id_util::GenerateId("id");
std::string extension_id = id_util::GenerateId("extension_id"); std::string extension_id = id_util::GenerateId("extension_id");
scoped_refptr<Extension> extension = scoped_refptr<Extension> extension =
CreateExtensionImportingModule(import_id, extension_id); CreateExtensionImportingModule(import_id, extension_id, "1.0");
PendingExtensionManager* pending_extension_manager = PendingExtensionManager* pending_extension_manager =
service_->pending_extension_manager(); service()->pending_extension_manager();
// Verify that we don't currently want to install the imported module. // Verify that we don't currently want to install the imported module.
EXPECT_FALSE(pending_extension_manager->IsIdPending(import_id)); EXPECT_FALSE(pending_extension_manager->IsIdPending(import_id));
// Try to satisfy imports for the extension. This should queue the imported // Try to satisfy imports for the extension. This should queue the imported
// module's installation. // module's installation.
service_->shared_module_service()->SatisfyImports(extension); service()->shared_module_service()->SatisfyImports(extension);
EXPECT_TRUE(pending_extension_manager->IsIdPending(import_id)); EXPECT_TRUE(pending_extension_manager->IsIdPending(import_id));
} }
...@@ -120,17 +133,17 @@ TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) { ...@@ -120,17 +133,17 @@ TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) {
.SetID(id_util::GenerateId("shared_module")) .SetID(id_util::GenerateId("shared_module"))
.Build(); .Build();
EXPECT_TRUE(InstallExtension(shared_module)); EXPECT_TRUE(InstallExtension(shared_module, false));
std::string extension_id = id_util::GenerateId("extension_id"); std::string extension_id = id_util::GenerateId("extension_id");
// Create and install an extension that imports our new module. // Create and install an extension that imports our new module.
scoped_refptr<Extension> importing_extension = scoped_refptr<Extension> importing_extension =
CreateExtensionImportingModule(shared_module->id(), extension_id); CreateExtensionImportingModule(shared_module->id(), extension_id, "1.0");
EXPECT_TRUE(InstallExtension(importing_extension)); EXPECT_TRUE(InstallExtension(importing_extension, false));
// Uninstall the extension that imports our module. // Uninstall the extension that imports our module.
base::string16 error; base::string16 error;
service_->UninstallExtension(importing_extension->id(), service()->UninstallExtension(importing_extension->id(),
ExtensionService::UNINSTALL_REASON_FOR_TESTING, ExtensionService::UNINSTALL_REASON_FOR_TESTING,
&error); &error);
EXPECT_TRUE(error.empty()); EXPECT_TRUE(error.empty());
...@@ -142,6 +155,77 @@ TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) { ...@@ -142,6 +155,77 @@ TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) {
ExtensionRegistry::EVERYTHING)); ExtensionRegistry::EVERYTHING));
} }
TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUpdate) {
// Create two modules which export a resource, and install them.
scoped_ptr<base::DictionaryValue> manifest_1 =
DictionaryBuilder()
.Set("name", "Shared Module 1")
.Set("version", "1.0")
.Set("manifest_version", 2)
.Set("export",
DictionaryBuilder().Set("resources",
ListBuilder().Append("foo.js"))).Build();
scoped_refptr<Extension> shared_module_1 =
ExtensionBuilder().SetManifest(manifest_1.Pass())
.AddFlags(Extension::FROM_WEBSTORE)
.SetID(id_util::GenerateId("shared_module_1"))
.Build();
EXPECT_TRUE(InstallExtension(shared_module_1, false));
scoped_ptr<base::DictionaryValue> manifest_2 =
DictionaryBuilder()
.Set("name", "Shared Module 2")
.Set("version", "1.0")
.Set("manifest_version", 2)
.Set("export",
DictionaryBuilder().Set("resources",
ListBuilder().Append("foo.js"))).Build();
scoped_refptr<Extension> shared_module_2 =
ExtensionBuilder().SetManifest(manifest_2.Pass())
.AddFlags(Extension::FROM_WEBSTORE)
.SetID(id_util::GenerateId("shared_module_2"))
.Build();
EXPECT_TRUE(InstallExtension(shared_module_2, false));
std::string extension_id = id_util::GenerateId("extension_id");
// Create and install an extension v1.0 that imports our new module 1.
scoped_refptr<Extension> importing_extension_1 =
CreateExtensionImportingModule(shared_module_1->id(),
extension_id,
"1.0");
EXPECT_TRUE(InstallExtension(importing_extension_1, false));
// Create and install a new version of the extension that imports our new
// module 2.
scoped_refptr<Extension> importing_extension_2 =
CreateExtensionImportingModule(shared_module_2->id(),
extension_id,
"1.1");
EXPECT_TRUE(InstallExtension(importing_extension_2, true));
// Since the extension v1.1 depends the module 2 insteand module 1.
// So the module 1 should be uninstalled.
EXPECT_FALSE(registry()->GetExtensionById(shared_module_1->id(),
ExtensionRegistry::EVERYTHING));
EXPECT_TRUE(registry()->GetExtensionById(shared_module_2->id(),
ExtensionRegistry::EVERYTHING));
// Create and install a new version of the extension that does not import any
// module.
scoped_refptr<Extension> importing_extension_3 =
CreateExtensionImportingModule("", extension_id, "1.2");
EXPECT_TRUE(InstallExtension(importing_extension_3, true));
// Since the extension v1.2 does not depend any module, so the all models
// should have been uninstalled.
EXPECT_FALSE(registry()->GetExtensionById(shared_module_1->id(),
ExtensionRegistry::EVERYTHING));
EXPECT_FALSE(registry()->GetExtensionById(shared_module_2->id(),
ExtensionRegistry::EVERYTHING));
}
TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) { TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) {
std::string whitelisted_id = id_util::GenerateId("whitelisted"); std::string whitelisted_id = id_util::GenerateId("whitelisted");
std::string nonwhitelisted_id = id_util::GenerateId("nonwhitelisted"); std::string nonwhitelisted_id = id_util::GenerateId("nonwhitelisted");
...@@ -163,17 +247,21 @@ TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) { ...@@ -163,17 +247,21 @@ TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) {
.SetID(id_util::GenerateId("shared_module")) .SetID(id_util::GenerateId("shared_module"))
.Build(); .Build();
EXPECT_TRUE(InstallExtension(shared_module)); EXPECT_TRUE(InstallExtension(shared_module, false));
// Create and install an extension with the whitelisted ID. // Create and install an extension with the whitelisted ID.
scoped_refptr<Extension> whitelisted_extension = scoped_refptr<Extension> whitelisted_extension =
CreateExtensionImportingModule(shared_module->id(), whitelisted_id); CreateExtensionImportingModule(shared_module->id(),
EXPECT_TRUE(InstallExtension(whitelisted_extension)); whitelisted_id,
"1.0");
EXPECT_TRUE(InstallExtension(whitelisted_extension, false));
// Try to install an extension with an ID that is not whitelisted. // Try to install an extension with an ID that is not whitelisted.
scoped_refptr<Extension> nonwhitelisted_extension = scoped_refptr<Extension> nonwhitelisted_extension =
CreateExtensionImportingModule(shared_module->id(), nonwhitelisted_id); CreateExtensionImportingModule(shared_module->id(),
EXPECT_FALSE(InstallExtension(nonwhitelisted_extension)); nonwhitelisted_id,
"1.0");
EXPECT_FALSE(InstallExtension(nonwhitelisted_extension, false));
} }
} // namespace extensions } // namespace extensions
...@@ -385,7 +385,8 @@ void WebstoreInstaller::Observe(int type, ...@@ -385,7 +385,8 @@ void WebstoreInstaller::Observe(int type,
void WebstoreInstaller::OnExtensionInstalled( void WebstoreInstaller::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension) { const Extension* extension,
bool is_update) {
CHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context))); CHECK(profile_->IsSameProfile(Profile::FromBrowserContext(browser_context)));
if (pending_modules_.empty()) if (pending_modules_.empty())
return; return;
......
...@@ -200,7 +200,8 @@ class WebstoreInstaller : public content::NotificationObserver, ...@@ -200,7 +200,8 @@ class WebstoreInstaller : public content::NotificationObserver,
// ExtensionRegistryObserver. // ExtensionRegistryObserver.
virtual void OnExtensionInstalled(content::BrowserContext* browser_context, virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension,
bool is_update) OVERRIDE;
// Removes the reference to the delegate passed in the constructor. Used when // Removes the reference to the delegate passed in the constructor. Used when
// the delegate object must be deleted before this object. // the delegate object must be deleted before this object.
......
...@@ -285,7 +285,8 @@ void HotwordService::InstallHotwordExtensionFromWebstore() { ...@@ -285,7 +285,8 @@ void HotwordService::InstallHotwordExtensionFromWebstore() {
void HotwordService::OnExtensionInstalled( void HotwordService::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) { const extensions::Extension* extension,
bool is_update) {
if (extension->id() != extension_misc::kHotwordExtensionId || if (extension->id() != extension_misc::kHotwordExtensionId ||
profile_ != Profile::FromBrowserContext(browser_context)) profile_ != Profile::FromBrowserContext(browser_context))
......
...@@ -50,7 +50,8 @@ class HotwordService : public content::NotificationObserver, ...@@ -50,7 +50,8 @@ class HotwordService : public content::NotificationObserver,
// Overridden from ExtensionRegisterObserver: // Overridden from ExtensionRegisterObserver:
virtual void OnExtensionInstalled( virtual void OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled( virtual void OnExtensionUninstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension) OVERRIDE;
......
...@@ -157,7 +157,8 @@ class ExtensionsMatchChecker : public StatusChangeChecker, ...@@ -157,7 +157,8 @@ class ExtensionsMatchChecker : public StatusChangeChecker,
extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE; extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
virtual void OnExtensionInstalled( virtual void OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUninstalled( virtual void OnExtensionUninstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension) OVERRIDE;
...@@ -222,7 +223,8 @@ void ExtensionsMatchChecker::OnExtensionUnloaded( ...@@ -222,7 +223,8 @@ void ExtensionsMatchChecker::OnExtensionUnloaded(
void ExtensionsMatchChecker::OnExtensionInstalled( void ExtensionsMatchChecker::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) { const extensions::Extension* extension,
bool is_update) {
CheckExitCondition(); CheckExitCondition();
} }
......
...@@ -619,7 +619,8 @@ void SyncFileSystemService::OnRemoteServiceStateUpdated( ...@@ -619,7 +619,8 @@ void SyncFileSystemService::OnRemoteServiceStateUpdated(
void SyncFileSystemService::OnExtensionInstalled( void SyncFileSystemService::OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension) { const Extension* extension,
bool is_update) {
GURL app_origin = Extension::GetBaseURLFromExtensionId(extension->id()); GURL app_origin = Extension::GetBaseURLFromExtensionId(extension->id());
DVLOG(1) << "Handle extension notification for INSTALLED: " << app_origin; DVLOG(1) << "Handle extension notification for INSTALLED: " << app_origin;
// NOTE: When an app is uninstalled and re-installed in a sequence, // NOTE: When an app is uninstalled and re-installed in a sequence,
......
...@@ -137,7 +137,8 @@ class SyncFileSystemService ...@@ -137,7 +137,8 @@ class SyncFileSystemService
// extensions::ExtensionRegistryObserver implementations. // extensions::ExtensionRegistryObserver implementations.
virtual void OnExtensionInstalled( virtual void OnExtensionInstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) OVERRIDE; const extensions::Extension* extension,
bool is_update) OVERRIDE;
virtual void OnExtensionUnloaded( virtual void OnExtensionUnloaded(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension, const extensions::Extension* extension,
......
...@@ -67,11 +67,13 @@ void ExtensionRegistry::TriggerOnWillBeInstalled(const Extension* extension, ...@@ -67,11 +67,13 @@ void ExtensionRegistry::TriggerOnWillBeInstalled(const Extension* extension,
browser_context_, extension, is_update, from_ephemeral, old_name)); browser_context_, extension, is_update, from_ephemeral, old_name));
} }
void ExtensionRegistry::TriggerOnInstalled(const Extension* extension) { void ExtensionRegistry::TriggerOnInstalled(const Extension* extension,
bool is_update) {
DCHECK(GenerateInstalledExtensionsSet()->Contains(extension->id())); DCHECK(GenerateInstalledExtensionsSet()->Contains(extension->id()));
FOR_EACH_OBSERVER(ExtensionRegistryObserver, FOR_EACH_OBSERVER(ExtensionRegistryObserver,
observers_, observers_,
OnExtensionInstalled(browser_context_, extension)); OnExtensionInstalled(
browser_context_, extension, is_update));
} }
void ExtensionRegistry::TriggerOnUninstalled(const Extension* extension) { void ExtensionRegistry::TriggerOnUninstalled(const Extension* extension) {
......
...@@ -88,7 +88,8 @@ class ExtensionRegistry : public KeyedService { ...@@ -88,7 +88,8 @@ class ExtensionRegistry : public KeyedService {
// Invokes the observer method OnExtensionInstalled(). The extension must be // Invokes the observer method OnExtensionInstalled(). The extension must be
// contained in one of the registry's extension sets. // contained in one of the registry's extension sets.
void TriggerOnInstalled(const Extension* extension); void TriggerOnInstalled(const Extension* extension,
bool is_update);
// Invokes the observer method OnExtensionUninstalled(). The extension must // Invokes the observer method OnExtensionUninstalled(). The extension must
// not be any installed extension with |extension|'s ID. // not be any installed extension with |extension|'s ID.
......
...@@ -63,7 +63,8 @@ class ExtensionRegistryObserver { ...@@ -63,7 +63,8 @@ class ExtensionRegistryObserver {
// extension is tracked in one of the ExtensionRegistry sets, but is not // extension is tracked in one of the ExtensionRegistry sets, but is not
// necessarily enabled. // necessarily enabled.
virtual void OnExtensionInstalled(content::BrowserContext* browser_context, virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension) {} const Extension* extension,
bool is_update) {}
// Called after an extension is uninstalled. The extension no longer exists in // Called after an extension is uninstalled. The extension no longer exists in
// any of the ExtensionRegistry sets (enabled, disabled, etc.). // any of the ExtensionRegistry sets (enabled, disabled, etc.).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment