Bug 1372750 Pass startup/shutdown reasons to embedded webextensions draft
authorAndrew Swan <aswan@mozilla.com>
Thu, 15 Jun 2017 17:00:22 -0700
changeset 595688 c115345f6e53b6be93e2b7ae6fa11547d076054b
parent 594852 ac2d0008d149be9bd183dd1fb3a127997bf3f14e
child 633776 ba1449eb5c35f0b1b8738542d4f9182772b0e19c
push id64415
push useraswan@mozilla.com
push dateFri, 16 Jun 2017 17:26:32 +0000
bugs1372750
milestone56.0a1
Bug 1372750 Pass startup/shutdown reasons to embedded webextensions MozReview-Commit-ID: 3oJHM83Jbb0
toolkit/components/extensions/LegacyExtensionsUtils.jsm
toolkit/components/extensions/test/xpcshell/test_ext_startup_cache.js
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/toolkit/components/extensions/LegacyExtensionsUtils.jsm
+++ b/toolkit/components/extensions/LegacyExtensionsUtils.jsm
@@ -118,33 +118,36 @@ class EmbeddedExtension {
 
     // Setup status flag.
     this.started = false;
   }
 
   /**
    * Start the embedded webextension.
    *
+   * @param {number} reason
+   *        The startupReason to pass to the Extension constructor
+   *
    * @returns {Promise<LegacyContextAPI>} A promise which resolve to the API exposed to the
    *   legacy context.
    */
-  startup() {
+  startup(reason) {
     if (this.started) {
       return Promise.reject(new Error("This embedded extension has already been started"));
     }
 
     // Setup the startup promise.
     this.startupPromise = new Promise((resolve, reject) => {
       let embeddedExtensionURI = Services.io.newURI("webextension/", null, this.resourceURI);
 
       // This is the instance of the WebExtension embedded in the hybrid add-on.
       this.extension = new Extension({
         id: this.addonId,
         resourceURI: embeddedExtensionURI,
-      });
+      }, reason);
 
       // This callback is register to the "startup" event, emitted by the Extension instance
       // after the extension manifest.json has been loaded without any errors, but before
       // starting any of the defined contexts (which give the legacy part a chance to subscribe
       // runtime.onMessage/onConnect listener before the background page has been loaded).
       const onBeforeStarted = () => {
         this.extension.off("startup", onBeforeStarted);
 
@@ -187,31 +190,34 @@ class EmbeddedExtension {
     });
 
     return this.startupPromise;
   }
 
   /**
    * Shuts down the embedded webextension.
    *
+   * @param {number} reason
+   *        The shutdownReason to pass to Extension.shutdown()
+   *
    * @returns {Promise<void>} a promise that is resolved when the shutdown has been done
    */
-  shutdown() {
+  shutdown(reason) {
     EmbeddedExtensionManager.untrackEmbeddedExtension(this);
 
     // If there is a pending startup,  wait to be completed and then shutdown.
     if (this.startupPromise) {
       return this.startupPromise.then(() => {
-        this.extension.shutdown();
+        this.extension.shutdown(reason);
       });
     }
 
     // Run shutdown now if the embedded webextension has been correctly started
     if (this.extension && this.started && !this.extension.hasShutdown) {
-      this.extension.shutdown();
+      this.extension.shutdown(reason);
     }
 
     return Promise.resolve();
   }
 }
 
 // Keep track on the created EmbeddedExtension instances and destroy
 // them when their container addon is going to be disabled or uninstalled.
--- a/toolkit/components/extensions/test/xpcshell/test_ext_startup_cache.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_startup_cache.js
@@ -4,25 +4,23 @@
 
 Cu.import("resource://gre/modules/Preferences.jsm");
 
 AddonTestUtils.init(this);
 AddonTestUtils.overrideCertDB();
 
 AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
 
-const ADDON_ID = "test-startup-cache@xpcshell.mozilla.org";
-
 function makeExtension(opts) {
   return {
     useAddonManager: "permanent",
 
     manifest: {
       "version": opts.version,
-      "applications": {"gecko": {"id": ADDON_ID}},
+      "applications": {"gecko": {"id": opts.id}},
 
       "name": "__MSG_name__",
 
       "default_locale": "en_US",
     },
 
     files: {
       "_locales/en_US/messages.json": {
@@ -44,67 +42,74 @@ function makeExtension(opts) {
         if (msg === "get-manifest") {
           browser.test.sendMessage("manifest", browser.runtime.getManifest());
         }
       });
     },
   };
 }
 
-add_task(async function() {
+add_task(async function setup() {
   Preferences.set("extensions.logging.enabled", false);
   await AddonTestUtils.promiseStartupManager();
+});
 
-  let extension = ExtensionTestUtils.loadExtension(
-    makeExtension({version: "1.0"}));
+for (let embedded of [false, true]) {
+  add_task(async function() {
+    const ID = embedded ? "test-startup-cache-embedded@xpcshell.mozilla.org"
+             : "test-startup-cache@xpcshell.mozilla.org";
 
-  function getManifest() {
-    extension.sendMessage("get-manifest");
-    return extension.awaitMessage("manifest");
-  }
+    let extension = ExtensionTestUtils.loadExtension(
+      makeExtension({embedded, version: "1.0", id: ID}));
+
+    function getManifest() {
+      extension.sendMessage("get-manifest");
+      return extension.awaitMessage("manifest");
+    }
 
 
-  await extension.startup();
-
-  equal(extension.version, "1.0", "Expected extension version");
-  let manifest = await getManifest();
-  equal(manifest.name, "en-US 1.0", "Got expected manifest name");
-
+    await extension.startup();
 
-  do_print("Restart and re-check");
-  await AddonTestUtils.promiseRestartManager();
-  await extension.awaitStartup();
-
-  equal(extension.version, "1.0", "Expected extension version");
-  manifest = await getManifest();
-  equal(manifest.name, "en-US 1.0", "Got expected manifest name");
+    equal(extension.version, "1.0", "Expected extension version");
+    let manifest = await getManifest();
+    equal(manifest.name, "en-US 1.0", "Got expected manifest name");
 
 
-  do_print("Change locale to 'fr' and restart");
-  Preferences.set("general.useragent.locale", "fr");
-  await AddonTestUtils.promiseRestartManager();
-  await extension.awaitStartup();
+    do_print("Restart and re-check");
+    await AddonTestUtils.promiseRestartManager();
+    await extension.awaitStartup();
+
+    equal(extension.version, "1.0", "Expected extension version");
+    manifest = await getManifest();
+    equal(manifest.name, "en-US 1.0", "Got expected manifest name");
+
 
-  equal(extension.version, "1.0", "Expected extension version");
-  manifest = await getManifest();
-  equal(manifest.name, "fr 1.0", "Got expected manifest name");
+    do_print("Change locale to 'fr' and restart");
+    Preferences.set("general.useragent.locale", "fr");
+    await AddonTestUtils.promiseRestartManager();
+    await extension.awaitStartup();
+
+    equal(extension.version, "1.0", "Expected extension version");
+    manifest = await getManifest();
+    equal(manifest.name, "fr 1.0", "Got expected manifest name");
 
 
-  do_print("Update to version 1.1");
-  await extension.upgrade(makeExtension({version: "1.1"}));
+    do_print("Update to version 1.1");
+    await extension.upgrade(makeExtension({embedded, version: "1.1", id: ID}));
 
-  equal(extension.version, "1.1", "Expected extension version");
-  manifest = await getManifest();
-  equal(manifest.name, "fr 1.1", "Got expected manifest name");
+    equal(extension.version, "1.1", "Expected extension version");
+    manifest = await getManifest();
+    equal(manifest.name, "fr 1.1", "Got expected manifest name");
 
 
-  do_print("Change locale to 'en-US' and restart");
-  Preferences.set("general.useragent.locale", "en-US");
-  await AddonTestUtils.promiseRestartManager();
-  await extension.awaitStartup();
+    do_print("Change locale to 'en-US' and restart");
+    Preferences.set("general.useragent.locale", "en-US");
+    await AddonTestUtils.promiseRestartManager();
+    await extension.awaitStartup();
 
-  equal(extension.version, "1.1", "Expected extension version");
-  manifest = await getManifest();
-  equal(manifest.name, "en-US 1.1", "Got expected manifest name");
+    equal(extension.version, "1.1", "Expected extension version");
+    manifest = await getManifest();
+    equal(manifest.name, "en-US 1.1", "Got expected manifest name");
 
 
-  await extension.unload();
-});
+    await extension.unload();
+  });
+}
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -4428,20 +4428,20 @@ this.XPIProvider = {
           params[key] = aExtraParams[key];
         }
       }
 
       if (aAddon.hasEmbeddedWebExtension) {
         if (aMethod == "startup") {
           const webExtension = LegacyExtensionsUtils.getEmbeddedExtensionFor(params);
           params.webExtension = {
-            startup: () => webExtension.startup(),
+            startup: () => webExtension.startup(aReason),
           };
         } else if (aMethod == "shutdown") {
-          LegacyExtensionsUtils.getEmbeddedExtensionFor(params).shutdown();
+          LegacyExtensionsUtils.getEmbeddedExtensionFor(params).shutdown(aReason);
         }
       }
 
       if (!method) {
         logger.warn("Add-on " + aAddon.id + " is missing bootstrap method " + aMethod);
       } else {
         logger.debug("Calling bootstrap method " + aMethod + " on " + aAddon.id + " version " +
                      aAddon.version);