summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_event_names.cc7
-rw-r--r--chrome/browser/extensions/extension_event_names.h11
-rw-r--r--chrome/browser/extensions/extension_management_api.cc77
-rw-r--r--chrome/browser/extensions/extension_management_api.h27
-rw-r--r--chrome/browser/extensions/extension_management_api_browsertest.cc30
-rw-r--r--chrome/browser/extensions/extensions_service.cc4
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/extensions/api/extension_api.json11
-rw-r--r--chrome/common/extensions/docs/experimental.management.html30
-rw-r--r--chrome/test/data/extensions/api_test/management/test/basics.js29
-rw-r--r--chrome/test/data/extensions/api_test/management/test/common.js2
-rw-r--r--chrome/test/data/extensions/api_test/management/test/uninstall.js11
-rw-r--r--chrome/test/data/extensions/management/install_event/background.html1
-rw-r--r--chrome/test/data/extensions/management/install_event/manifest.json7
-rw-r--r--chrome/test/data/extensions/management/install_event/test.js15
15 files changed, 222 insertions, 41 deletions
diff --git a/chrome/browser/extensions/extension_event_names.cc b/chrome/browser/extensions/extension_event_names.cc
index 421bab8..a70f293 100644
--- a/chrome/browser/extensions/extension_event_names.cc
+++ b/chrome/browser/extensions/extension_event_names.cc
@@ -13,9 +13,14 @@ const char kOnTabMoved[] = "tabs.onMoved";
const char kOnTabRemoved[] = "tabs.onRemoved";
const char kOnTabSelectionChanged[] = "tabs.onSelectionChanged";
const char kOnTabUpdated[] = "tabs.onUpdated";
+
const char kOnWindowCreated[] = "windows.onCreated";
const char kOnWindowFocusedChanged[] = "windows.onFocusChanged";
const char kOnWindowRemoved[] = "windows.onRemoved";
-} // namespace extension_event_names
+const char kOnExtensionInstalled[] = "experimental.management.onInstalled";
+const char kOnExtensionUninstalled[] = "experimental.management.onUninstalled";
+const char kOnExtensionEnabled[] = "experimental.management.onEnabled";
+const char kOnExtensionDisabled[] = "experimental.management.onDisabled";
+} // namespace extension_event_names
diff --git a/chrome/browser/extensions/extension_event_names.h b/chrome/browser/extensions/extension_event_names.h
index 4cbadfc..3c63f90 100644
--- a/chrome/browser/extensions/extension_event_names.h
+++ b/chrome/browser/extensions/extension_event_names.h
@@ -10,6 +10,7 @@
namespace extension_event_names {
+// Tabs.
extern const char kOnTabAttached[];
extern const char kOnTabCreated[];
extern const char kOnTabDetached[];
@@ -17,11 +18,19 @@ extern const char kOnTabMoved[];
extern const char kOnTabRemoved[];
extern const char kOnTabSelectionChanged[];
extern const char kOnTabUpdated[];
+
+// Windows.
extern const char kOnWindowCreated[];
extern const char kOnWindowFocusedChanged[];
extern const char kOnWindowRemoved[];
+// Management.
+extern const char kOnExtensionInstalled[];
+extern const char kOnExtensionUninstalled[];
+extern const char kOnExtensionEnabled[];
+extern const char kOnExtensionDisabled[];
+
+
}; // namespace extension_event_names
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_NAMES_H_
-
diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc
index 6be0476..4b581b2 100644
--- a/chrome/browser/extensions/extension_management_api.cc
+++ b/chrome/browser/extensions/extension_management_api.cc
@@ -7,12 +7,19 @@
#include <map>
#include <string>
+#include "base/basictypes.h"
+#include "base/json/json_writer.h"
#include "base/string_number_conversions.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/extensions/extension_event_names.h"
+#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/common/extensions/extension_error_utils.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
using base::IntToString;
+namespace events = extension_event_names;
const char kAppLaunchUrlKey[] = "appLaunchUrl";
const char kEnabledKey[] = "enabled";
@@ -26,7 +33,6 @@ const char kUrlKey[] = "url";
const char kNoExtensionError[] = "No extension with id *";
-
ExtensionsService* ExtensionManagementFunction::service() {
return profile()->GetExtensionsService();
}
@@ -128,3 +134,72 @@ bool UninstallFunction::RunImpl() {
service()->UninstallExtension(extension_id, false /* external_uninstall */);
return true;
}
+
+
+// static
+ExtensionManagementEventRouter* ExtensionManagementEventRouter::GetInstance() {
+ return Singleton<ExtensionManagementEventRouter>::get();
+}
+
+ExtensionManagementEventRouter::ExtensionManagementEventRouter() {}
+
+ExtensionManagementEventRouter::~ExtensionManagementEventRouter() {}
+
+void ExtensionManagementEventRouter::Init() {
+ NotificationType::Type types[] = {
+ NotificationType::EXTENSION_INSTALLED,
+ NotificationType::EXTENSION_UNINSTALLED,
+ NotificationType::EXTENSION_LOADED,
+ NotificationType::EXTENSION_UNLOADED
+ };
+
+ for (size_t i = 0; i < arraysize(types); i++) {
+ registrar_.Add(this,
+ types[i],
+ NotificationService::AllSources());
+ }
+}
+
+void ExtensionManagementEventRouter::Observe(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ const char* event_name = NULL;
+ switch (type.value) {
+ case NotificationType::EXTENSION_INSTALLED:
+ event_name = events::kOnExtensionInstalled;
+ break;
+ case NotificationType::EXTENSION_UNINSTALLED:
+ event_name = events::kOnExtensionUninstalled;
+ break;
+ case NotificationType::EXTENSION_LOADED:
+ event_name = events::kOnExtensionEnabled;
+ break;
+ case NotificationType::EXTENSION_UNLOADED:
+ event_name = events::kOnExtensionDisabled;
+ break;
+ default:
+ NOTREACHED();
+ return;
+ }
+
+ Profile* profile = Source<Profile>(source).ptr();
+ Extension* extension = Details<Extension>(details).ptr();
+ CHECK(profile);
+ CHECK(extension);
+
+ ExtensionsService* service = profile->GetExtensionsService();
+ bool enabled = service->GetExtensionById(extension->id(), false) != NULL;
+ ListValue args;
+ args.Append(CreateExtensionInfo(*extension, enabled));
+
+ std::string args_json;
+ base::JSONWriter::Write(&args, false /* pretty_print */, &args_json);
+
+ ExtensionMessageService* message_service =
+ profile->GetExtensionMessageService();
+ message_service->DispatchEventToRenderers(event_name,
+ args_json,
+ profile->IsOffTheRecord(),
+ GURL());
+}
diff --git a/chrome/browser/extensions/extension_management_api.h b/chrome/browser/extensions/extension_management_api.h
index c32c833..9d3108d 100644
--- a/chrome/browser/extensions/extension_management_api.h
+++ b/chrome/browser/extensions/extension_management_api.h
@@ -6,7 +6,10 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_API_H__
#pragma once
+#include "base/singleton.h"
#include "chrome/browser/extensions/extension_function.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
class ExtensionsService;
@@ -39,4 +42,28 @@ class UninstallFunction : public ExtensionManagementFunction {
DECLARE_EXTENSION_FUNCTION_NAME("experimental.management.uninstall");
};
+class ExtensionManagementEventRouter : public NotificationObserver {
+ public:
+ // Get the singleton instance of the event router.
+ static ExtensionManagementEventRouter* GetInstance();
+
+ // Performs one-time initialization of our singleton.
+ void Init();
+
+ private:
+ friend struct DefaultSingletonTraits<ExtensionManagementEventRouter>;
+
+ ExtensionManagementEventRouter();
+ virtual ~ExtensionManagementEventRouter();
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionManagementEventRouter);
+};
+
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_API_H__
diff --git a/chrome/browser/extensions/extension_management_api_browsertest.cc b/chrome/browser/extensions/extension_management_api_browsertest.cc
new file mode 100644
index 0000000..63fdfcf
--- /dev/null
+++ b/chrome/browser/extensions/extension_management_api_browsertest.cc
@@ -0,0 +1,30 @@
+// 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/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/extension_test_message_listener.h"
+#include "chrome/common/chrome_switches.h"
+
+
+class ExtensionManagementApiBrowserTest : public ExtensionBrowserTest {
+ virtual void SetUpCommandLine(CommandLine* command_line) {
+ ExtensionBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+ }
+};
+
+// We test this here instead of in an ExtensionApiTest because normal extensions
+// are not allowed to call the install function.
+IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, InstallEvent) {
+ ExtensionTestMessageListener listener1("ready");
+ ASSERT_TRUE(LoadExtension(
+ test_data_dir_.AppendASCII("management/install_event")));
+ ASSERT_TRUE(listener1.WaitUntilSatisfied());
+
+ ExtensionTestMessageListener listener2("got_event");
+ ASSERT_TRUE(LoadExtension(
+ test_data_dir_.AppendASCII("api_test/management/enabled_extension")));
+ ASSERT_TRUE(listener2.WaitUntilSatisfied());
+}
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 3fb4a91..5ea1ede 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -29,6 +29,7 @@
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_history_api.h"
#include "chrome/browser/extensions/extension_host.h"
+#include "chrome/browser/extensions/extension_management_api.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/extensions/external_extension_provider.h"
@@ -238,6 +239,7 @@ void ExtensionsService::InitEventRouters() {
ExtensionBookmarkEventRouter::GetSingleton()->Observe(
profile_->GetBookmarkModel());
ExtensionCookiesEventRouter::GetInstance()->Init();
+ ExtensionManagementEventRouter::GetInstance()->Init();
}
void ExtensionsService::Init() {
@@ -533,7 +535,7 @@ void ExtensionsService::LoadComponentExtensions() {
// In order for the --apps-gallery-url switch to work with the gallery
// process isolation, we must insert any provided value into the component
// app's launch url and web extent.
- if (extension->id() == extension_misc::kWebStoreAppId ) {
+ if (extension->id() == extension_misc::kWebStoreAppId) {
GURL gallery_url(CommandLine::ForCurrentProcess()
->GetSwitchValueASCII(switches::kAppsGalleryURL));
if (gallery_url.is_valid()) {
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index cff0ea7..1a61269 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1718,6 +1718,7 @@
'browser/extensions/extension_input_apitest.cc',
'browser/extensions/extension_install_ui_browsertest.cc',
'browser/extensions/extension_javascript_url_apitest.cc',
+ 'browser/extensions/extension_management_api_browsertest.cc',
'browser/extensions/extension_management_apitest.cc',
'browser/extensions/extension_management_browsertest.cc',
'browser/extensions/extension_messages_apitest.cc',
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index d8b3c02..1014714 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -3998,6 +3998,7 @@
{
"name": "callback",
"type": "function",
+ "optional": "true",
"parameters": []
}
]
@@ -4046,25 +4047,25 @@
"events": [
{
"name": "onInstalled",
- "description": "(NOT YET IMPLEMENTED)",
+ "description": "Fired when an app or extension has been installed.",
"type": "function",
"parameters": [{"name": "info", "$ref":"ExtensionInfo"}]
},
{
"name": "onUninstalled",
- "description": "(NOT YET IMPLEMENTED)",
+ "description": "Fired when an app or extension has been uninstalled.",
"type": "function",
- "parameters": [{"name": "id", "type": "string", "description": "The id of the extension that was uninstalled."}]
+ "parameters": [{"name": "info", "$ref":"ExtensionInfo"}]
},
{
"name": "onEnabled",
- "description": "(NOT YET IMPLEMENTED)",
+ "description": "Fired when an app or extension has been enabled.",
"type": "function",
"parameters": [{"name": "info", "$ref":"ExtensionInfo"}]
},
{
"name": "onDisabled",
- "description": "(NOT YET IMPLEMENTED)",
+ "description": "Fired when an app or extension has been disabled",
"type": "function",
"parameters": [{"name": "info", "$ref":"ExtensionInfo"}]
}
diff --git a/chrome/common/extensions/docs/experimental.management.html b/chrome/common/extensions/docs/experimental.management.html
index 4f3ac8d..479cd35 100644
--- a/chrome/common/extensions/docs/experimental.management.html
+++ b/chrome/common/extensions/docs/experimental.management.html
@@ -597,7 +597,7 @@
<!-- Note: intentionally longer 80 columns -->
<span>chrome.experimental.management.setEnabled</span>(<span class="null"><span style="display: none; ">, </span><span>string</span>
<var><span>id</span></var></span><span class="null"><span>, </span><span>boolean</span>
- <var><span>enabled</span></var></span><span class="null"><span>, </span><span>function</span>
+ <var><span>enabled</span></var></span><span class="optional"><span>, </span><span>function</span>
<var><span>callback</span></var></span>)</div>
<div class="description">
@@ -732,7 +732,7 @@
<!-- TYPE -->
<div style="display:inline">
(
- <span class="optional" style="display: none; ">optional</span>
+ <span class="optional">optional</span>
<span class="enum" style="display: none; ">enumerated</span>
<span id="typeTemplate">
<span style="display: none; ">
@@ -799,11 +799,11 @@
<div>
<div>
<h4>Callback function</h4>
- <p>
+ <p style="display: none; ">
The callback <em>parameter</em> should specify a function
that looks like this:
</p>
- <p style="display: none; ">
+ <p>
If you specify the <em>callback</em> parameter, it should
specify a function that looks like this:
</p>
@@ -1267,7 +1267,7 @@
<div class="summary">
<!-- Note: intentionally longer 80 columns -->
- <span class="subdued">chrome.experimental.management.</span><span>onUninstalled</span><span class="subdued">.addListener</span>(function(<span>string id</span>) <span class="subdued">{...}</span>);
+ <span class="subdued">chrome.experimental.management.</span><span>onUninstalled</span><span class="subdued">.addListener</span>(function(<span>ExtensionInfo info</span>) <span class="subdued">{...}</span>);
</div>
<div class="description">
@@ -1280,7 +1280,7 @@
<div>
<div>
<dt>
- <var>id</var>
+ <var>info</var>
<em>
<!-- TYPE -->
@@ -1289,15 +1289,15 @@
<span class="optional" style="display: none; ">optional</span>
<span class="enum" style="display: none; ">enumerated</span>
<span id="typeTemplate">
- <span style="display: none; ">
- <a> Type</a>
- </span>
<span>
- <span style="display: none; ">
+ <a href="experimental.management.html#type-ExtensionInfo">ExtensionInfo</a>
+ </span>
+ <span style="display: none; ">
+ <span>
array of <span><span></span></span>
</span>
- <span>string</span>
- <span style="display: none; "></span>
+ <span>paramType</span>
+ <span></span>
</span>
</span>
)
@@ -1305,10 +1305,12 @@
</em>
</dt>
- <dd class="todo" style="display: none; ">
+ <dd class="todo">
Undocumented.
</dd>
- <dd>The id of the extension that was uninstalled.</dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
diff --git a/chrome/test/data/extensions/api_test/management/test/basics.js b/chrome/test/data/extensions/api_test/management/test/basics.js
index ea5fc23..c998ca3d 100644
--- a/chrome/test/data/extensions/api_test/management/test/basics.js
+++ b/chrome/test/data/extensions/api_test/management/test/basics.js
@@ -17,8 +17,7 @@ function checkIcon(item, size, path) {
var tests = [
function simple() {
- chrome.management.getAll(function(items) {
- assertNoLastError();
+ chrome.management.getAll(callback(function(items) {
chrome.test.assertEq(5, items.length);
checkItem(items, "Extension Management API Test", true, false);
@@ -36,33 +35,35 @@ var tests = [
checkIcon(extension, 128, "icon_128.png");
checkIcon(extension, 48, "icon_48.png");
checkIcon(extension, 16, "icon_16.png");
-
- succeed();
- });
+ }));
},
// Disables an enabled app.
function disable() {
- chrome.management.getAll(function(items) {
- assertNoLastError();
+ listenOnce(chrome.management.onDisabled, function(info) {
+ assertEq(info.name, "enabled_app");
+ });
+
+ chrome.management.getAll(callback(function(items) {
checkItem(items, "enabled_app", true, true);
var enabled_app = getItemNamed(items, "enabled_app");
chrome.management.setEnabled(enabled_app.id, false, function() {
assertNoLastError();
chrome.management.getAll(function(items2) {
assertNoLastError();
- chrome.test.log("re-checking enabled_app");
checkItem(items2, "enabled_app", false, true);
- succeed();
+ assertTrue(event_fired);
});
});
- });
+ }));
},
// Enables a disabled extension.
function enable() {
- chrome.management.getAll(function(items) {
- assertNoLastError();
+ listenOnce(chrome.management.onEnabled, function(info) {
+ assertEq(info.name, "disabled_extension");
+ });
+ chrome.management.getAll(callback(function(items) {
checkItem(items, "disabled_extension", false, false);
var disabled = getItemNamed(items, "disabled_extension");
chrome.management.setEnabled(disabled.id, true, function() {
@@ -70,10 +71,10 @@ var tests = [
chrome.management.getAll(function(items2) {
assertNoLastError();
checkItem(items2, "disabled_extension", true, false);
- succeed();
+ assertTrue(event_fired);
});
});
- });
+ }));
}
];
diff --git a/chrome/test/data/extensions/api_test/management/test/common.js b/chrome/test/data/extensions/api_test/management/test/common.js
index 6385599..744ced4 100644
--- a/chrome/test/data/extensions/api_test/management/test/common.js
+++ b/chrome/test/data/extensions/api_test/management/test/common.js
@@ -12,6 +12,8 @@ var assertNoLastError = chrome.test.assertNoLastError;
var assertTrue = chrome.test.assertTrue;
var fail = chrome.test.fail;
var succeed = chrome.test.succeed;
+var listenOnce = chrome.test.listenOnce;
+var callback = chrome.test.callback;
function getItemNamed(list, name) {
for (var i = 0; i < list.length; i++) {
diff --git a/chrome/test/data/extensions/api_test/management/test/uninstall.js b/chrome/test/data/extensions/api_test/management/test/uninstall.js
index e4a120b..f425c8e 100644
--- a/chrome/test/data/extensions/api_test/management/test/uninstall.js
+++ b/chrome/test/data/extensions/api_test/management/test/uninstall.js
@@ -3,8 +3,11 @@
// found in the LICENSE file.
function uninstall(name) {
- chrome.management.getAll(function(items) {
- assertNoLastError();
+ listenOnce(chrome.management.onUninstalled, function(info) {
+ assertEq(info.name, name);
+ });
+
+ chrome.management.getAll(callback(function(items) {
var old_count = items.length;
var item = getItemNamed(items, name);
chrome.management.uninstall(item.id, function() {
@@ -15,10 +18,10 @@ function uninstall(name) {
for (var i = 0; i < items2.length; i++) {
assertFalse(items2[i].name == name);
}
- succeed();
+ assertTrue(event_fired);
});
});
- });
+ }));
}
var tests = [
diff --git a/chrome/test/data/extensions/management/install_event/background.html b/chrome/test/data/extensions/management/install_event/background.html
new file mode 100644
index 0000000..46f4d74
--- /dev/null
+++ b/chrome/test/data/extensions/management/install_event/background.html
@@ -0,0 +1 @@
+<script src="test.js"></script>
diff --git a/chrome/test/data/extensions/management/install_event/manifest.json b/chrome/test/data/extensions/management/install_event/manifest.json
new file mode 100644
index 0000000..79a5831
--- /dev/null
+++ b/chrome/test/data/extensions/management/install_event/manifest.json
@@ -0,0 +1,7 @@
+{
+ "name": "Install event test",
+ "version": "0.1",
+ "permissions": ["experimental"],
+ "background_page": "background.html"
+}
+
diff --git a/chrome/test/data/extensions/management/install_event/test.js b/chrome/test/data/extensions/management/install_event/test.js
new file mode 100644
index 0000000..09ef1c4
--- /dev/null
+++ b/chrome/test/data/extensions/management/install_event/test.js
@@ -0,0 +1,15 @@
+// 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.
+
+if (!chrome.management) {
+ chrome.management = chrome.experimental.management;
+}
+
+chrome.management.onInstalled.addListener(function(info) {
+ if (info.name == "enabled_extension") {
+ chrome.test.sendMessage("got_event");
+ }
+});
+
+chrome.test.sendMessage("ready");