Bug 1561122: Cleanup SpecialPowers.loadExtension after JSWindowActor migration. r=aswan
authorKris Maglione <maglione.k@gmail.com>
Mon, 24 Jun 2019 16:48:51 -0700
changeset 544126 b42748878b6e8cd676ab9e0f9fc963b89423cf24
parent 544125 266160ca8e9d27918623f096cde1a6f998e8900c
child 544127 3115db154c45ee1b5b2187d25772d9ddfbebe0c0
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1561122
milestone69.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 1561122: Cleanup SpecialPowers.loadExtension after JSWindowActor migration. r=aswan Differential Revision: https://phabricator.services.mozilla.com/D35731
testing/specialpowers/content/SpecialPowersAPI.jsm
testing/specialpowers/content/SpecialPowersAPIParent.jsm
toolkit/components/extensions/MessageChannel.jsm
--- a/testing/specialpowers/content/SpecialPowersAPI.jsm
+++ b/testing/specialpowers/content/SpecialPowersAPI.jsm
@@ -1544,69 +1544,57 @@ class SpecialPowersAPI extends JSWindowA
       });
     }
 
     // Note, this is not the addon is as used by the AddonManager etc,
     // this is just an identifier used for specialpowers messaging
     // between this content process and the chrome process.
     let id = this._nextExtensionID++;
 
-    let resolveStartup, resolveUnload, rejectStartup;
-    let startupPromise = new Promise((resolve, reject) => {
-      resolveStartup = resolve;
-      rejectStartup = reject;
-    });
-    let unloadPromise = new Promise(resolve => { resolveUnload = resolve; });
-
-    startupPromise.catch(() => {
-      this._extensionListeners.delete(listener);
-    });
 
     handler = Cu.waiveXrays(handler);
     ext = Cu.waiveXrays(ext);
 
     let sp = this;
     let state = "uninitialized";
     let extension = {
       get state() { return state; },
 
       startup() {
         state = "pending";
-        sp.sendAsyncMessage("SPStartupExtension", {id});
-        return startupPromise;
+        return sp.sendQuery("SPStartupExtension", {id}).then(
+          () => {
+            state = "running";
+          }, () => {
+            state = "failed";
+            sp._extensionListeners.delete(listener);
+            return Promise.reject("startup failed");
+          });
       },
 
       unload() {
         state = "unloading";
-        sp.sendAsyncMessage("SPUnloadExtension", {id});
-        return unloadPromise;
+        return sp.sendQuery("SPUnloadExtension", {id}).finally(() => {
+          sp._extensionListeners.delete(listener);
+          state = "unloaded";
+        });
       },
 
       sendMessage(...args) {
         sp.sendAsyncMessage("SPExtensionMessage", {id, args});
       },
     };
 
     this.sendAsyncMessage("SPLoadExtension", {ext, id});
 
     let listener = (msg) => {
       if (msg.data.id == id) {
-        if (msg.data.type == "extensionStarted") {
-          state = "running";
-          resolveStartup();
-        } else if (msg.data.type == "extensionSetId") {
+        if (msg.data.type == "extensionSetId") {
           extension.id = msg.data.args[0];
           extension.uuid = msg.data.args[1];
-        } else if (msg.data.type == "extensionFailed") {
-          state = "failed";
-          rejectStartup("startup failed");
-        } else if (msg.data.type == "extensionUnloaded") {
-          this._extensionListeners.delete(listener);
-          state = "unloaded";
-          resolveUnload();
         } else if (msg.data.type in handler) {
           handler[msg.data.type](...Cu.cloneInto(msg.data.args, this.contentWindow));
         } else {
           dump(`Unexpected: ${msg.data.type}\n`);
         }
       }
     };
 
--- a/testing/specialpowers/content/SpecialPowersAPIParent.jsm
+++ b/testing/specialpowers/content/SpecialPowersAPIParent.jsm
@@ -705,17 +705,17 @@ class SpecialPowersAPIParent extends JSW
           // is a MockExtension.
           this.sendAsyncMessage("SPExtensionMessage", {id, type: "extensionSetId", args: [ext.id, ext.uuid]});
         });
 
         // Make sure the extension passes the packaging checks when
         // they're run on a bare archive rather than a running instance,
         // as the add-on manager runs them.
         let extensionData = new ExtensionData(extension.rootURI);
-        extensionData.loadManifest().then(
+        return extensionData.loadManifest().then(
           () => {
             return extensionData.initAllLocales().then(() => {
               if (extensionData.errors.length) {
                 return Promise.reject("Extension contains packaging errors");
               }
               return undefined;
             });
           },
@@ -725,43 +725,37 @@ class SpecialPowersAPIParent extends JSW
             // case.
           }
         ).then(async () => {
           // browser tests do not call startup in ExtensionXPCShellUtils or MockExtension,
           // in that case we have an ID here and we need to set the override.
           if (extension.id) {
             await ExtensionTestCommon.setIncognitoOverride(extension);
           }
-          return extension.startup();
-        }).then(() => {
-          this.sendAsyncMessage("SPExtensionMessage", {id, type: "extensionStarted", args: []});
-        }).catch(e => {
-          dump(`Extension startup failed: ${e}\n${e.stack}`);
-          this.sendAsyncMessage("SPExtensionMessage", {id, type: "extensionFailed", args: []});
+          return extension.startup().then(() => {}, e => {
+            dump(`Extension startup failed: ${e}\n${e.stack}`);
+            throw e;
+          });
         });
-        return undefined;
       }
 
       case "SPExtensionMessage": {
         let id = aMessage.data.id;
         let extension = this._extensions.get(id);
         extension.testMessage(...aMessage.data.args);
         return undefined;
       }
 
       case "SPUnloadExtension": {
         let id = aMessage.data.id;
         let extension = this._extensions.get(id);
         this._extensions.delete(id);
-        let done = async () => {
-          await extension._uninstallPromise;
-          this.sendAsyncMessage("SPExtensionMessage", {id, type: "extensionUnloaded", args: []});
-        };
-        extension.shutdown().then(done, done);
-        return undefined;
+        return extension.shutdown().then(() => {
+          return extension._uninstallPromise;
+        });
       }
 
       case "Spawn": {
         let {browsingContext, task, args, caller} = aMessage.data;
 
         let spParent = browsingContext.currentWindowGlobal.getActor("SpecialPowers");
 
         let taskId = nextTaskID++;
--- a/toolkit/components/extensions/MessageChannel.jsm
+++ b/toolkit/components/extensions/MessageChannel.jsm
@@ -378,17 +378,17 @@ class ResponseManager extends FilteringM
    *
    * @param {string} messageName
    *     The internal message name for which to unregister the handler.
    * @param {object} handler
    *     The handler object to unregister.
    */
   removeHandler(messageName, handler) {
     if (DEBUG && this.handlers.get(messageName) !== handler) {
-      throw new Error(`Attempting to remove unexpected response handler for ${messageName}`);
+      Cu.reportError(`Attempting to remove unexpected response handler for ${messageName}`);
     }
     this.handlers.delete(messageName);
   }
 }
 
 /**
  * Manages mappings of message managers to their corresponding message
  * brokers. Brokers are lazily created for each message manager the