Send an onInstalled event for shared module update

BUG=276723

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276871 0039d316-1c4b-4281-b951-d872f2087c98
parent aae79574
...@@ -183,4 +183,10 @@ ContentVerifier* ShellExtensionSystem::content_verifier() { ...@@ -183,4 +183,10 @@ ContentVerifier* ShellExtensionSystem::content_verifier() {
return NULL; return NULL;
} }
scoped_ptr<ExtensionSet> ShellExtensionSystem::GetDependentExtensions(
const Extension* extension) {
scoped_ptr<ExtensionSet> empty(new ExtensionSet());
return empty.PassAs<ExtensionSet>();
}
} // namespace extensions } // namespace extensions
...@@ -70,6 +70,8 @@ class ShellExtensionSystem : public ExtensionSystem { ...@@ -70,6 +70,8 @@ class ShellExtensionSystem : public ExtensionSystem {
const UnloadedExtensionInfo::Reason reason) OVERRIDE; const UnloadedExtensionInfo::Reason reason) OVERRIDE;
virtual const OneShotEvent& ready() const OVERRIDE; virtual const OneShotEvent& ready() const OVERRIDE;
virtual ContentVerifier* content_verifier() OVERRIDE; virtual ContentVerifier* content_verifier() OVERRIDE;
virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE;
private: private:
content::BrowserContext* browser_context_; // Not owned. content::BrowserContext* browser_context_; // Not owned.
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "chrome/browser/extensions/extension_warning_set.h" #include "chrome/browser/extensions/extension_warning_set.h"
#include "chrome/browser/extensions/install_verifier.h" #include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/navigation_observer.h" #include "chrome/browser/extensions/navigation_observer.h"
#include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/extensions/standard_management_policy_provider.h" #include "chrome/browser/extensions/standard_management_policy_provider.h"
#include "chrome/browser/extensions/state_store.h" #include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/extensions/unpacked_installer.h"
...@@ -495,6 +496,12 @@ ContentVerifier* ExtensionSystemImpl::content_verifier() { ...@@ -495,6 +496,12 @@ ContentVerifier* ExtensionSystemImpl::content_verifier() {
return shared_->content_verifier(); return shared_->content_verifier();
} }
scoped_ptr<ExtensionSet> ExtensionSystemImpl::GetDependentExtensions(
const Extension* extension) {
return extension_service()->shared_module_service()->GetDependentExtensions(
extension);
}
void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( void ExtensionSystemImpl::RegisterExtensionWithRequestContexts(
const Extension* extension) { const Extension* extension) {
base::Time install_time; base::Time install_time;
......
...@@ -59,6 +59,8 @@ class ExtensionSystemImpl : public ExtensionSystem { ...@@ -59,6 +59,8 @@ class ExtensionSystemImpl : public ExtensionSystem {
virtual const OneShotEvent& ready() const OVERRIDE; virtual const OneShotEvent& ready() const OVERRIDE;
virtual ContentVerifier* content_verifier() OVERRIDE; // shared virtual ContentVerifier* content_verifier() OVERRIDE; // shared
virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE;
private: private:
friend class ExtensionSystemSharedFactory; friend class ExtensionSystemSharedFactory;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
using extensions::Extension; using extensions::Extension;
...@@ -35,3 +36,21 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SharedModuleWhitelist) { ...@@ -35,3 +36,21 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SharedModuleWhitelist) {
test_data_dir_.AppendASCII("shared_module") test_data_dir_.AppendASCII("shared_module")
.AppendASCII("import_not_in_whitelist"), 0)); .AppendASCII("import_not_in_whitelist"), 0));
} }
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SharedModuleInstallEvent) {
ExtensionTestMessageListener listener1("ready", false);
const Extension* extension = LoadExtension(
test_data_dir_.AppendASCII("shared_module").AppendASCII("shared"));
ASSERT_TRUE(extension);
ASSERT_TRUE(InstallExtension(
test_data_dir_.AppendASCII("shared_module").AppendASCII("import_pass"),
1));
EXPECT_TRUE(listener1.WaitUntilSatisfied());
ExtensionTestMessageListener listener2("shared_module_updated", false);
ReloadExtension(extension->id());
EXPECT_TRUE(listener2.WaitUntilSatisfied());
}
...@@ -104,7 +104,7 @@ SharedModuleService::ImportStatus SharedModuleService::SatisfyImports( ...@@ -104,7 +104,7 @@ SharedModuleService::ImportStatus SharedModuleService::SatisfyImports(
return status; return status;
} }
scoped_ptr<const ExtensionSet> SharedModuleService::GetDependentExtensions( scoped_ptr<ExtensionSet> SharedModuleService::GetDependentExtensions(
const Extension* extension) { const Extension* extension) {
scoped_ptr<ExtensionSet> dependents(new ExtensionSet()); scoped_ptr<ExtensionSet> dependents(new ExtensionSet());
...@@ -127,7 +127,7 @@ scoped_ptr<const ExtensionSet> SharedModuleService::GetDependentExtensions( ...@@ -127,7 +127,7 @@ scoped_ptr<const ExtensionSet> SharedModuleService::GetDependentExtensions(
} }
} }
} }
return dependents.PassAs<const ExtensionSet>(); return dependents.PassAs<ExtensionSet>();
} }
void SharedModuleService::OnExtensionUninstalled( void SharedModuleService::OnExtensionUninstalled(
...@@ -149,7 +149,7 @@ void SharedModuleService::OnExtensionUninstalled( ...@@ -149,7 +149,7 @@ void SharedModuleService::OnExtensionUninstalled(
registry->GetExtensionById(iter->extension_id, registry->GetExtensionById(iter->extension_id,
ExtensionRegistry::EVERYTHING); ExtensionRegistry::EVERYTHING);
if (imported_module && imported_module->from_webstore()) { if (imported_module && imported_module->from_webstore()) {
scoped_ptr<const ExtensionSet> dependents = scoped_ptr<ExtensionSet> dependents =
GetDependentExtensions(imported_module); GetDependentExtensions(imported_module);
if (dependents->is_empty()) { if (dependents->is_empty()) {
service->UninstallExtension(iter->extension_id, service->UninstallExtension(iter->extension_id,
......
...@@ -51,11 +51,10 @@ class SharedModuleService : public ExtensionRegistryObserver { ...@@ -51,11 +51,10 @@ class SharedModuleService : public ExtensionRegistryObserver {
// list if |extension| came from the webstore. // list if |extension| came from the webstore.
ImportStatus SatisfyImports(const Extension* extension); ImportStatus SatisfyImports(const Extension* extension);
private:
// Returns a set of extensions that import a given extension. // Returns a set of extensions that import a given extension.
scoped_ptr<const ExtensionSet> GetDependentExtensions( scoped_ptr<ExtensionSet> GetDependentExtensions(const Extension* extension);
const Extension* extension);
private:
// ExtensionRegistryObserver implementation. // ExtensionRegistryObserver implementation.
virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE; const Extension* extension) OVERRIDE;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "chrome/browser/extensions/error_console/error_console.h" #include "chrome/browser/extensions/error_console/error_console.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/install_verifier.h" #include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/extensions/standard_management_policy_provider.h" #include "chrome/browser/extensions/standard_management_policy_provider.h"
#include "chrome/browser/extensions/state_store.h" #include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/extensions/user_script_master.h"
...@@ -187,6 +188,12 @@ ContentVerifier* TestExtensionSystem::content_verifier() { ...@@ -187,6 +188,12 @@ ContentVerifier* TestExtensionSystem::content_verifier() {
return NULL; return NULL;
} }
scoped_ptr<ExtensionSet> TestExtensionSystem::GetDependentExtensions(
const Extension* extension) {
return extension_service()->shared_module_service()->GetDependentExtensions(
extension);
}
// static // static
KeyedService* TestExtensionSystem::Build(content::BrowserContext* profile) { KeyedService* TestExtensionSystem::Build(content::BrowserContext* profile) {
return new TestExtensionSystem(static_cast<Profile*>(profile)); return new TestExtensionSystem(static_cast<Profile*>(profile));
......
...@@ -78,6 +78,8 @@ class TestExtensionSystem : public ExtensionSystem { ...@@ -78,6 +78,8 @@ class TestExtensionSystem : public ExtensionSystem {
virtual QuotaService* quota_service() OVERRIDE; virtual QuotaService* quota_service() OVERRIDE;
virtual const OneShotEvent& ready() const OVERRIDE; virtual const OneShotEvent& ready() const OVERRIDE;
virtual ContentVerifier* content_verifier() OVERRIDE; virtual ContentVerifier* content_verifier() OVERRIDE;
virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) OVERRIDE;
void SetReady() { void SetReady() {
LOG(INFO) << "SetReady()"; LOG(INFO) << "SetReady()";
......
...@@ -8,4 +8,15 @@ if (typeof fail_exported != 'undefined') ...@@ -8,4 +8,15 @@ if (typeof fail_exported != 'undefined')
if (typeof pass_exported == 'undefined') if (typeof pass_exported == 'undefined')
chrome.test.notifyFail('pass.js was not exported correctly.'); chrome.test.notifyFail('pass.js was not exported correctly.');
chrome.runtime.onInstalled.addListener(function(details) {
if (details.reason == 'shared_module_update' &&
details.previousVersion == '1.0' &&
// This ID corresponds to the public key in 'shared'.
details.id == 'gpcckkmippodnppallflahfabmeilgjg') {
chrome.test.sendMessage('shared_module_updated');
}
});
chrome.test.sendMessage('ready');
chrome.test.notifyPass(); chrome.test.notifyPass();
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "extensions/common/error_utils.h" #include "extensions/common/error_utils.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/manifest_handlers/shared_module_info.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "webkit/browser/fileapi/isolated_context.h" #include "webkit/browser/fileapi/isolated_context.h"
...@@ -45,10 +46,12 @@ namespace { ...@@ -45,10 +46,12 @@ namespace {
const char kNoBackgroundPageError[] = "You do not have a background page."; const char kNoBackgroundPageError[] = "You do not have a background page.";
const char kPageLoadError[] = "Background page failed to load."; const char kPageLoadError[] = "Background page failed to load.";
const char kInstallId[] = "id";
const char kInstallReason[] = "reason"; const char kInstallReason[] = "reason";
const char kInstallReasonChromeUpdate[] = "chrome_update"; const char kInstallReasonChromeUpdate[] = "chrome_update";
const char kInstallReasonUpdate[] = "update"; const char kInstallReasonUpdate[] = "update";
const char kInstallReasonInstall[] = "install"; const char kInstallReasonInstall[] = "install";
const char kInstallReasonSharedModuleUpdate[] = "shared_module_update";
const char kInstallPreviousVersion[] = "previousVersion"; const char kInstallPreviousVersion[] = "previousVersion";
const char kInvalidUrlError[] = "Invalid URL."; const char kInvalidUrlError[] = "Invalid URL.";
const char kPlatformInfoUnavailable[] = "Platform information unavailable."; const char kPlatformInfoUnavailable[] = "Platform information unavailable.";
...@@ -334,6 +337,30 @@ void RuntimeEventRouter::DispatchOnInstalledEvent( ...@@ -334,6 +337,30 @@ void RuntimeEventRouter::DispatchOnInstalledEvent(
new Event(runtime::OnInstalled::kEventName, event_args.Pass())); new Event(runtime::OnInstalled::kEventName, event_args.Pass()));
system->event_router()->DispatchEventWithLazyListener(extension_id, system->event_router()->DispatchEventWithLazyListener(extension_id,
event.Pass()); event.Pass());
if (old_version.IsValid()) {
const Extension* extension =
ExtensionRegistry::Get(context)->enabled_extensions().GetByID(
extension_id);
if (extension && SharedModuleInfo::IsSharedModule(extension)) {
scoped_ptr<ExtensionSet> dependents =
system->GetDependentExtensions(extension);
for (ExtensionSet::const_iterator i = dependents->begin();
i != dependents->end();
i++) {
scoped_ptr<base::ListValue> sm_event_args(new base::ListValue());
base::DictionaryValue* sm_info = new base::DictionaryValue();
sm_event_args->Append(sm_info);
sm_info->SetString(kInstallReason, kInstallReasonSharedModuleUpdate);
sm_info->SetString(kInstallPreviousVersion, old_version.GetString());
sm_info->SetString(kInstallId, extension_id);
scoped_ptr<Event> sm_event(
new Event(runtime::OnInstalled::kEventName, sm_event_args.Pass()));
system->event_router()->DispatchEventWithLazyListener((*i)->id(),
sm_event.Pass());
}
}
}
} }
// static // static
......
...@@ -30,6 +30,7 @@ class ContentVerifier; ...@@ -30,6 +30,7 @@ class ContentVerifier;
class ErrorConsole; class ErrorConsole;
class EventRouter; class EventRouter;
class Extension; class Extension;
class ExtensionSet;
class ExtensionWarningService; class ExtensionWarningService;
class InfoMap; class InfoMap;
class InstallVerifier; class InstallVerifier;
...@@ -128,6 +129,12 @@ class ExtensionSystem : public KeyedService { ...@@ -128,6 +129,12 @@ class ExtensionSystem : public KeyedService {
// Returns the content verifier, if any. // Returns the content verifier, if any.
virtual ContentVerifier* content_verifier() = 0; virtual ContentVerifier* content_verifier() = 0;
// Get a set of extensions that depend on the given extension.
// TODO(elijahtaylor): Move SharedModuleService out of chrome/browser
// so it can be retrieved from ExtensionSystem directly.
virtual scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) = 0;
}; };
} // namespace extensions } // namespace extensions
......
...@@ -352,13 +352,18 @@ ...@@ -352,13 +352,18 @@
"properties": { "properties": {
"reason": { "reason": {
"type": "string", "type": "string",
"enum": ["install", "update", "chrome_update"], "enum": ["install", "update", "chrome_update", "shared_module_update"],
"description": "The reason that this event is being dispatched." "description": "The reason that this event is being dispatched."
}, },
"previousVersion": { "previousVersion": {
"type": "string", "type": "string",
"optional": true, "optional": true,
"description": "Indicates the previous version of the extension, which has just been updated. This is present only if 'reason' is 'update'." "description": "Indicates the previous version of the extension, which has just been updated. This is present only if 'reason' is 'update'."
},
"id": {
"type": "string",
"optional": true,
"description": "Indicates the ID of the imported shared module extension which updated. This is present only if 'reason' is 'shared_module_update'."
} }
} }
} }
......
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