--- a/toolkit/components/extensions/ext-runtime.js
+++ b/toolkit/components/extensions/ext-runtime.js
@@ -9,25 +9,38 @@ Cu.import("resource://gre/modules/Extens
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Extension",
"resource://gre/modules/Extension.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionManagement",
"resource://gre/modules/ExtensionManagement.jsm");
var {
- ignoreEvent,
SingletonEventManager,
} = ExtensionUtils;
extensions.registerSchemaAPI("runtime", "addon_parent", context => {
let {extension} = context;
return {
runtime: {
- onStartup: ignoreEvent(context, "runtime.onStartup"),
+ onStartup: new SingletonEventManager(context, "runtime.onStartup", fire => {
+ if (context.incognito) {
+ // This event should not fire if we are operating in a private profile.
+ return () => {};
+ }
+ let listener = () => {
+ if (extension.startupReason === "APP_STARTUP") {
+ fire();
+ }
+ };
+ extension.on("startup", listener);
+ return () => {
+ extension.off("startup", listener);
+ };
+ }).api(),
onInstalled: new SingletonEventManager(context, "runtime.onInstalled", fire => {
let listener = () => {
switch (extension.startupReason) {
case "APP_STARTUP":
if (Extension.browserUpdated) {
fire({reason: "browser_update"});
}
rename from toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled.js
rename to toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
--- a/toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
@@ -34,16 +34,59 @@ function awaitEvent(eventName) {
resolve(...args);
}
};
Management.on(eventName, listener);
});
}
+function background() {
+ let onInstalledDetails = null;
+ let onStartupFired = false;
+
+ browser.runtime.onInstalled.addListener(details => {
+ onInstalledDetails = details;
+ });
+
+ browser.runtime.onStartup.addListener(() => {
+ onStartupFired = true;
+ });
+
+ browser.test.onMessage.addListener(message => {
+ if (message === "get-on-installed-details") {
+ onInstalledDetails = onInstalledDetails || {fired: false};
+ browser.test.sendMessage("on-installed-details", onInstalledDetails);
+ } else if (message === "did-on-startup-fire") {
+ browser.test.sendMessage("on-startup-fired", onStartupFired);
+ } else if (message === "reload-extension") {
+ browser.runtime.reload();
+ }
+ });
+
+ browser.runtime.onUpdateAvailable.addListener(details => {
+ browser.test.sendMessage("reloading");
+ browser.runtime.reload();
+ });
+}
+
+function* expectEvents(extension, {onStartupFired, onInstalledFired, onInstalledReason}) {
+ extension.sendMessage("get-on-installed-details");
+ let details = yield extension.awaitMessage("on-installed-details");
+ if (onInstalledFired) {
+ equal(details.reason, onInstalledReason, "runtime.onInstalled fired with the correct reason");
+ } else {
+ equal(details.fired, onInstalledFired, "runtime.onInstalled should not have fired");
+ }
+
+ extension.sendMessage("did-on-startup-fire");
+ let fired = yield extension.awaitMessage("on-startup-fired");
+ equal(fired, onStartupFired, `Expected runtime.onStartup to ${onStartupFired ? "" : "not "} fire`);
+}
+
add_task(function* test_should_fire_on_addon_update() {
const EXTENSION_ID = "test_runtime_on_installed_addon_update@tests.mozilla.org";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
// The test extension uses an insecure update url.
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
@@ -56,26 +99,17 @@ add_task(function* test_should_fire_on_a
"version": "1.0",
"applications": {
"gecko": {
"id": EXTENSION_ID,
"update_url": `http://localhost:${port}/test_update.json`,
},
},
},
- background() {
- browser.runtime.onUpdateAvailable.addListener(details => {
- browser.test.sendMessage("reloading");
- browser.runtime.reload();
- });
-
- browser.runtime.onInstalled.addListener(details => {
- browser.test.sendMessage("installed", details);
- });
- },
+ background,
});
testServer.registerPathHandler("/test_update.json", (request, response) => {
response.write(`{
"addons": {
"${EXTENSION_ID}": {
"updates": [
{
@@ -92,30 +126,30 @@ add_task(function* test_should_fire_on_a
manifest: {
version: "2.0",
applications: {
gecko: {
id: EXTENSION_ID,
},
},
},
- background() {
- browser.runtime.onInstalled.addListener(details => {
- browser.test.sendMessage("installed", details);
- });
- },
+ background,
});
testServer.registerFile("/addons/test_runtime_on_installed-2.0.xpi", webExtensionFile);
yield promiseStartupManager();
yield extension.startup();
- let details = yield extension.awaitMessage("installed");
- equal(details.reason, "install", "runtime.onInstalled fired with the correct reason");
+
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: true,
+ onInstalledReason: "install",
+ });
let addon = yield promiseAddonByID(EXTENSION_ID);
equal(addon.version, "1.0", "The installed addon has the correct version");
let update = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
let promiseInstalled = promiseAddonEvent("onInstalled");
@@ -126,18 +160,21 @@ add_task(function* test_should_fire_on_a
let startupPromise = awaitEvent("ready");
let [updated_addon] = yield promiseInstalled;
equal(updated_addon.version, "2.0", "The updated addon has the correct version");
extension.extension = yield startupPromise;
extension.attachListeners();
- details = yield extension.awaitMessage("installed");
- equal(details.reason, "update", "runtime.onInstalled fired with the correct reason");
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: true,
+ onInstalledReason: "update",
+ });
yield extension.unload();
yield updated_addon.uninstall();
yield promiseShutdownManager();
});
add_task(function* test_should_fire_on_browser_update() {
@@ -150,75 +187,71 @@ add_task(function* test_should_fire_on_b
manifest: {
"version": "1.0",
"applications": {
"gecko": {
"id": EXTENSION_ID,
},
},
},
- background() {
- let onInstalledDetails = null;
-
- browser.runtime.onInstalled.addListener(details => {
- onInstalledDetails = details;
- });
-
- browser.test.onMessage.addListener(message => {
- if (message == "get-on-installed-details") {
- browser.test.sendMessage("on-installed-details", onInstalledDetails);
- }
- });
- },
+ background,
});
yield extension.startup();
- extension.sendMessage("get-on-installed-details");
- let details = yield extension.awaitMessage("on-installed-details");
- equal(details.reason, "install", "runtime.onInstalled fired with the correct reason");
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: true,
+ onInstalledReason: "install",
+ });
let startupPromise = awaitEvent("ready");
yield promiseRestartManager("1");
extension.extension = yield startupPromise;
extension.attachListeners();
- extension.sendMessage("get-on-installed-details");
- details = yield extension.awaitMessage("on-installed-details");
- equal(details, null, "runtime.onInstalled should not have fired");
+ yield expectEvents(extension, {
+ onStartupFired: true,
+ onInstalledFired: false,
+ });
// Update the browser.
startupPromise = awaitEvent("ready");
yield promiseRestartManager("2");
extension.extension = yield startupPromise;
extension.attachListeners();
- extension.sendMessage("get-on-installed-details");
- details = yield extension.awaitMessage("on-installed-details");
- equal(details.reason, "browser_update", "runtime.onInstalled fired with the correct reason");
+ yield expectEvents(extension, {
+ onStartupFired: true,
+ onInstalledFired: true,
+ onInstalledReason: "browser_update",
+ });
// Restart the browser.
startupPromise = awaitEvent("ready");
yield promiseRestartManager("2");
extension.extension = yield startupPromise;
extension.attachListeners();
- extension.sendMessage("get-on-installed-details");
- details = yield extension.awaitMessage("on-installed-details");
- equal(details, null, "runtime.onInstalled should not have fired");
+ yield expectEvents(extension, {
+ onStartupFired: true,
+ onInstalledFired: false,
+ });
// Update the browser again.
startupPromise = awaitEvent("ready");
yield promiseRestartManager("3");
extension.extension = yield startupPromise;
extension.attachListeners();
- extension.sendMessage("get-on-installed-details");
- details = yield extension.awaitMessage("on-installed-details");
- equal(details.reason, "browser_update", "runtime.onInstalled fired with the correct reason");
+ yield expectEvents(extension, {
+ onStartupFired: true,
+ onInstalledFired: true,
+ onInstalledReason: "browser_update",
+ });
yield extension.unload();
yield promiseShutdownManager();
});
add_task(function* test_should_not_fire_on_reload() {
const EXTENSION_ID = "test_runtime_on_installed_reload@tests.mozilla.org";
@@ -230,47 +263,36 @@ add_task(function* test_should_not_fire_
manifest: {
"version": "1.0",
"applications": {
"gecko": {
"id": EXTENSION_ID,
},
},
},
- background() {
- let onInstalledDetails = null;
-
- browser.runtime.onInstalled.addListener(details => {
- onInstalledDetails = details;
- });
-
- browser.test.onMessage.addListener(message => {
- if (message == "reload-extension") {
- browser.runtime.reload();
- } else if (message == "get-on-installed-details") {
- browser.test.sendMessage("on-installed-details", onInstalledDetails);
- }
- });
- },
+ background,
});
yield extension.startup();
- extension.sendMessage("get-on-installed-details");
- let details = yield extension.awaitMessage("on-installed-details");
- equal(details.reason, "install", "runtime.onInstalled fired with the correct reason");
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: true,
+ onInstalledReason: "install",
+ });
let startupPromise = awaitEvent("ready");
extension.sendMessage("reload-extension");
extension.extension = yield startupPromise;
extension.attachListeners();
- extension.sendMessage("get-on-installed-details");
- details = yield extension.awaitMessage("on-installed-details");
- equal(details, null, "runtime.onInstalled should not have fired");
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: false,
+ });
yield extension.unload();
yield promiseShutdownManager();
});
add_task(function* test_should_not_fire_on_restart() {
const EXTENSION_ID = "test_runtime_on_installed_restart@tests.mozilla.org";
@@ -281,44 +303,35 @@ add_task(function* test_should_not_fire_
manifest: {
"version": "1.0",
"applications": {
"gecko": {
"id": EXTENSION_ID,
},
},
},
- background() {
- let onInstalledDetails = null;
-
- browser.runtime.onInstalled.addListener(details => {
- onInstalledDetails = details;
- });
-
- browser.test.onMessage.addListener(message => {
- if (message == "get-on-installed-details") {
- browser.test.sendMessage("on-installed-details", onInstalledDetails);
- }
- });
- },
+ background,
});
yield extension.startup();
- extension.sendMessage("get-on-installed-details");
- let details = yield extension.awaitMessage("on-installed-details");
- equal(details.reason, "install", "runtime.onInstalled fired with the correct reason");
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: true,
+ onInstalledReason: "install",
+ });
let addon = yield promiseAddonByID(EXTENSION_ID);
addon.userDisabled = true;
let startupPromise = awaitEvent("ready");
addon.userDisabled = false;
extension.extension = yield startupPromise;
extension.attachListeners();
- extension.sendMessage("get-on-installed-details");
- details = yield extension.awaitMessage("on-installed-details");
- equal(details, null, "runtime.onInstalled should not have fired");
+ yield expectEvents(extension, {
+ onStartupFired: false,
+ onInstalledFired: false,
+ });
yield extension.markUnloaded();
yield promiseShutdownManager();
});