Bug 1354590 - Add 'temporary' flag to runtime.onInstalled details. r=aswan,zombie
authorTushar Saini (:shatur) <tushar.saini1285@gmail.com>
Sun, 14 May 2017 10:54:11 +0530
changeset 358471 830cc1aae18f2d023ba97ee4bb4a5d6ef8a31aa5
parent 358470 25a7e2672c993af842b587af899548139a3f17e7
child 358472 6a2dedb044054624ee630622e5f5632efdd2b4a6
push id31827
push usercbook@mozilla.com
push dateTue, 16 May 2017 10:34:19 +0000
treeherdermozilla-central@49365d675cbb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan, zombie
bugs1354590
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1354590 - Add 'temporary' flag to runtime.onInstalled details. r=aswan,zombie MozReview-Commit-ID: IbQno1ZL7KV
toolkit/components/extensions/ext-runtime.js
toolkit/components/extensions/schemas/runtime.json
toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/toolkit/components/extensions/ext-runtime.js
+++ b/toolkit/components/extensions/ext-runtime.js
@@ -28,28 +28,34 @@ this.runtime = class extends ExtensionAP
           };
           extension.on("startup", listener);
           return () => {
             extension.off("startup", listener);
           };
         }).api(),
 
         onInstalled: new SingletonEventManager(context, "runtime.onInstalled", fire => {
+          let temporary = !!extension.addonData.temporarilyInstalled;
+
           let listener = () => {
             switch (extension.startupReason) {
               case "APP_STARTUP":
                 if (AddonManagerPrivate.browserUpdated) {
-                  fire.sync({reason: "browser_update"});
+                  fire.sync({reason: "browser_update", temporary});
                 }
                 break;
               case "ADDON_INSTALL":
-                fire.sync({reason: "install"});
+                fire.sync({reason: "install", temporary});
                 break;
               case "ADDON_UPGRADE":
-                fire.sync({reason: "update", previousVersion: extension.addonData.oldVersion});
+                fire.sync({
+                  reason: "update",
+                  previousVersion: extension.addonData.oldVersion,
+                  temporary,
+                });
                 break;
             }
           };
           extension.on("startup", listener);
           return () => {
             extension.off("startup", listener);
           };
         }).api(),
--- a/toolkit/components/extensions/schemas/runtime.json
+++ b/toolkit/components/extensions/schemas/runtime.json
@@ -470,16 +470,20 @@
                 "$ref": "OnInstalledReason",
                 "description": "The reason that this event is being dispatched."
               },
               "previousVersion": {
                 "type": "string",
                 "optional": true,
                 "description": "Indicates the previous version of the extension, which has just been updated. This is present only if 'reason' is 'update'."
               },
+              "temporary": {
+                "type": "boolean",
+                "description": "Indicates whether the addon is installed as a temporary extension."
+              },
               "id": {
                 "type": "string",
                 "optional": true,
                 "unsupported": true,
                 "description": "Indicates the ID of the imported shared module extension which updated. This is present only if 'reason' is 'shared_module_update'."
               }
             }
           }
--- a/toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
@@ -52,21 +52,22 @@ function background() {
   });
 
   browser.runtime.onUpdateAvailable.addListener(details => {
     browser.test.sendMessage("reloading");
     browser.runtime.reload();
   });
 }
 
-async function expectEvents(extension, {onStartupFired, onInstalledFired, onInstalledReason, onInstalledPrevious}) {
+async function expectEvents(extension, {onStartupFired, onInstalledFired, onInstalledReason, onInstalledTemporary, onInstalledPrevious}) {
   extension.sendMessage("get-on-installed-details");
   let details = await extension.awaitMessage("on-installed-details");
   if (onInstalledFired) {
     equal(details.reason, onInstalledReason, "runtime.onInstalled fired with the correct reason");
+    equal(details.temporary, onInstalledTemporary, "runtime.onInstalled fired with the correct temporary flag");
     if (onInstalledPrevious) {
       equal(details.previousVersion, onInstalledPrevious, "runtime.onInstalled after update with correct previousVersion");
     }
   } else {
     equal(details.fired, onInstalledFired, "runtime.onInstalled should not have fired");
   }
 
   extension.sendMessage("did-on-startup-fire");
@@ -132,16 +133,17 @@ add_task(async function test_should_fire
 
   testServer.registerFile("/addons/test_runtime_on_installed-2.0.xpi", webExtensionFile);
 
   await extension.startup();
 
   await expectEvents(extension, {
     onStartupFired: false,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "install",
   });
 
   let addon = await AddonManager.getAddonByID(EXTENSION_ID);
   equal(addon.version, "1.0", "The installed addon has the correct version");
 
   let update = await promiseFindAddonUpdates(addon);
   let install = update.updateAvailable;
@@ -154,16 +156,17 @@ add_task(async function test_should_fire
   let [updated_addon] = await promiseInstalled;
   equal(updated_addon.version, "2.0", "The updated addon has the correct version");
 
   await extension.awaitStartup();
 
   await expectEvents(extension, {
     onStartupFired: false,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "update",
     onInstalledPrevious: "1.0",
   });
 
   await extension.unload();
 
   await promiseShutdownManager();
 });
@@ -186,16 +189,17 @@ add_task(async function test_should_fire
     background,
   });
 
   await extension.startup();
 
   await expectEvents(extension, {
     onStartupFired: false,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "install",
   });
 
   await promiseRestartManager("1");
 
   await extension.awaitStartup();
 
   await expectEvents(extension, {
@@ -205,16 +209,17 @@ add_task(async function test_should_fire
 
   // Update the browser.
   await promiseRestartManager("2");
   await extension.awaitStartup();
 
   await expectEvents(extension, {
     onStartupFired: true,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "browser_update",
   });
 
   // Restart the browser.
   await promiseRestartManager("2");
   await extension.awaitStartup();
 
   await expectEvents(extension, {
@@ -224,16 +229,17 @@ add_task(async function test_should_fire
 
   // Update the browser again.
   await promiseRestartManager("3");
   await extension.awaitStartup();
 
   await expectEvents(extension, {
     onStartupFired: true,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "browser_update",
   });
 
   await extension.unload();
 
   await promiseShutdownManager();
 });
 
@@ -255,16 +261,17 @@ add_task(async function test_should_not_
     background,
   });
 
   await extension.startup();
 
   await expectEvents(extension, {
     onStartupFired: false,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "install",
   });
 
   extension.sendMessage("reload-extension");
   extension.setRestarting();
   await extension.awaitStartup();
 
   await expectEvents(extension, {
@@ -294,16 +301,17 @@ add_task(async function test_should_not_
     background,
   });
 
   await extension.startup();
 
   await expectEvents(extension, {
     onStartupFired: false,
     onInstalledFired: true,
+    onInstalledTemporary: false,
     onInstalledReason: "install",
   });
 
   let addon = await AddonManager.getAddonByID(EXTENSION_ID);
   addon.userDisabled = true;
 
   addon.userDisabled = false;
   await extension.awaitStartup();
@@ -311,8 +319,39 @@ add_task(async function test_should_not_
   await expectEvents(extension, {
     onStartupFired: false,
     onInstalledFired: false,
   });
 
   await extension.markUnloaded();
   await promiseShutdownManager();
 });
+
+add_task(async function test_temporary_installation() {
+  const EXTENSION_ID = "test_runtime_on_installed_addon_temporary@tests.mozilla.org";
+
+  await promiseStartupManager();
+
+  let extension = ExtensionTestUtils.loadExtension({
+    useAddonManager: "temporary",
+    manifest: {
+      "version": "1.0",
+      "applications": {
+        "gecko": {
+          "id": EXTENSION_ID,
+        },
+      },
+    },
+    background,
+  });
+
+  await extension.startup();
+
+  await expectEvents(extension, {
+    onStartupFired: false,
+    onInstalledFired: true,
+    onInstalledReason: "install",
+    onInstalledTemporary: true,
+  });
+
+  await extension.unload();
+  await promiseShutdownManager();
+});
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -4463,16 +4463,17 @@ this.XPIProvider = {
       throw new Error("Only restartless (bootstrap) add-ons"
                     + " can be installed from sources:", addon.id);
     }
     let installReason = BOOTSTRAP_REASONS.ADDON_INSTALL;
     let oldAddon = await new Promise(
                    resolve => XPIDatabase.getVisibleAddonForID(addon.id, resolve));
 
     let extraParams = {};
+    extraParams.temporarilyInstalled = aInstallLocation === TemporaryInstallLocation;
     if (oldAddon) {
       if (!oldAddon.bootstrap) {
         logger.warn("Non-restartless Add-on is already installed", addon.id);
         throw new Error("Non-restartless add-on with ID "
                         + oldAddon.id + " is already installed");
       } else {
         logger.warn("Addon with ID " + oldAddon.id + " already installed,"
                     + " older version will be disabled");