Bug 1515814 - Proxy these calls to the parent. r=asuth
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 21 Dec 2018 19:47:26 +0000
changeset 508853 64e898f29fd8a1f93fb0e5fb0ee1e897ff8daec6
parent 508852 1357e3b67ae3e711056a31b529296236f92f3607
child 508854 bfb1e23872cc2b88bab9f929e0ecf7b102e15614
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1515814
milestone66.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 1515814 - Proxy these calls to the parent. r=asuth These calls have to happen in the parent process to have any effect. I experimented with making ServiceWorkerCleanUp.jsm do the remoting itself but that didn't turn out to be worth the effort and it turns out all of the uses are currently in the parent process anyway. Differential Revision: https://phabricator.services.mozilla.com/D15160
testing/specialpowers/content/SpecialPowersObserver.jsm
testing/specialpowers/content/SpecialPowersObserverAPI.js
testing/specialpowers/content/specialpowers.js
testing/specialpowers/content/specialpowersAPI.js
--- a/testing/specialpowers/content/SpecialPowersObserver.jsm
+++ b/testing/specialpowers/content/SpecialPowersObserver.jsm
@@ -74,16 +74,18 @@ SpecialPowersObserver.prototype._loadFra
     this._messageManager.addMessageListener("SPLoadExtension", this);
     this._messageManager.addMessageListener("SPStartupExtension", this);
     this._messageManager.addMessageListener("SPUnloadExtension", this);
     this._messageManager.addMessageListener("SPExtensionMessage", this);
     this._messageManager.addMessageListener("SPCleanUpSTSData", this);
     this._messageManager.addMessageListener("SPRequestDumpCoverageCounters", this);
     this._messageManager.addMessageListener("SPRequestResetCoverageCounters", this);
     this._messageManager.addMessageListener("SPCheckServiceWorkers", this);
+    this._messageManager.addMessageListener("SPRemoveAllServiceWorkers", this);
+    this._messageManager.addMessageListener("SPRemoveServiceWorkerDataForExampleDomain", this);
 
     this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
     this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true);
     this._isFrameScriptLoaded = true;
     this._createdFiles = null;
   }
 };
 
@@ -167,16 +169,18 @@ SpecialPowersObserver.prototype.uninit =
     this._messageManager.removeMessageListener("SPLoadExtension", this);
     this._messageManager.removeMessageListener("SPStartupExtension", this);
     this._messageManager.removeMessageListener("SPUnloadExtension", this);
     this._messageManager.removeMessageListener("SPExtensionMessage", this);
     this._messageManager.removeMessageListener("SPCleanUpSTSData", this);
     this._messageManager.removeMessageListener("SPRequestDumpCoverageCounters", this);
     this._messageManager.removeMessageListener("SPRequestResetCoverageCounters", this);
     this._messageManager.removeMessageListener("SPCheckServiceWorkers", this);
+    this._messageManager.removeMessageListener("SPRemoveAllServiceWorkers", this);
+    this._messageManager.removeMessageListener("SPRemoveServiceWorkerDataForExampleDomain", this);
 
     this._messageManager.removeDelayedFrameScript(CHILD_LOGGER_SCRIPT);
     this._messageManager.removeDelayedFrameScript(CHILD_SCRIPT_API);
     this._isFrameScriptLoaded = false;
   }
 };
 
 SpecialPowersObserver.prototype._addProcessCrashObservers = function() {
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -7,16 +7,17 @@
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   ExtensionData: "resource://gre/modules/Extension.jsm",
   ExtensionTestCommon: "resource://testing-common/ExtensionTestCommon.jsm",
   NetUtil: "resource://gre/modules/NetUtil.jsm",
   Services: "resource://gre/modules/Services.jsm",
   PerTestCoverageUtils: "resource://testing-common/PerTestCoverageUtils.jsm",
+  ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
 });
 
 this.SpecialPowersError = function(aMsg) {
   Error.call(this);
   // let {stack} = new Error();
   this.message = aMsg;
   this.name = "SpecialPowersError";
 };
@@ -640,16 +641,30 @@ SpecialPowersObserverAPI.prototype = {
         let done = async () => {
           await extension._uninstallPromise;
           this._sendReply(aMessage, "SPExtensionMessage", {id, type: "extensionUnloaded", args: []});
         };
         extension.shutdown().then(done, done);
         return undefined;
       }
 
+      case "SPRemoveAllServiceWorkers": {
+        ServiceWorkerCleanUp.removeAll().then(() => {
+          this._sendReply(aMessage, "SPServiceWorkerCleanupComplete", { id: aMessage.data.id });
+        });
+        return undefined;
+      }
+
+      case "SPRemoveServiceWorkerDataForExampleDomain": {
+        ServiceWorkerCleanUp.removeFromHost("example.com").then(() => {
+          this._sendReply(aMessage, "SPServiceWorkerCleanupComplete", { id: aMessage.data.id });
+        });
+        return undefined;
+      }
+
       default:
         throw new SpecialPowersError(`Unrecognized Special Powers API: ${aMessage.name}`);
     }
 
     // We throw an exception before reaching this explicit return because
     // we should never be arriving here anyway.
     throw new SpecialPowersError("Unreached code"); // eslint-disable-line no-unreachable
     return undefined;
--- a/testing/specialpowers/content/specialpowers.js
+++ b/testing/specialpowers/content/specialpowers.js
@@ -21,16 +21,17 @@ function SpecialPowers(window, mm) {
   this.mm = mm;
 
   this.window = Cu.getWeakReference(window);
   this._windowID = window.windowUtils.currentInnerWindowID;
   this._encounteredCrashDumpFiles = [];
   this._unexpectedCrashDumpFiles = { };
   this._crashDumpDir = null;
   this._serviceWorkerRegistered = false;
+  this._serviceWorkerCleanUpRequests = new Map();
   this.DOMWindowUtils = bindDOMWindowUtils(window);
   Object.defineProperty(this, "Components", {
       configurable: true, enumerable: true, value: this.getFullComponents(),
   });
   this._pongHandlers = [];
   this._messageListener = this._messageReceived.bind(this);
   this._grandChildFrameMM = null;
   this._createFilesOnError = null;
@@ -52,30 +53,34 @@ function SpecialPowers(window, mm) {
                             "SpecialPowers.RemoveFiles",
                             "SPPingService",
                             "SPLoadExtension",
                             "SPProcessCrashManagerWait",
                             "SPStartupExtension",
                             "SPUnloadExtension",
                             "SPExtensionMessage",
                             "SPRequestDumpCoverageCounters",
-                            "SPRequestResetCoverageCounters"];
+                            "SPRequestResetCoverageCounters",
+                            "SPRemoveAllServiceWorkers",
+                            "SPRemoveServiceWorkerDataForExampleDomain"];
   mm.addMessageListener("SPPingService", this._messageListener);
   mm.addMessageListener("SPServiceWorkerRegistered", this._messageListener);
   mm.addMessageListener("SpecialPowers.FilesCreated", this._messageListener);
   mm.addMessageListener("SpecialPowers.FilesError", this._messageListener);
+  mm.addMessageListener("SPServiceWorkerCleanupComplete", this._messageListener);
   let self = this;
   Services.obs.addObserver(function onInnerWindowDestroyed(subject, topic, data) {
     var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
     if (self._windowID === id) {
       Services.obs.removeObserver(onInnerWindowDestroyed, "inner-window-destroyed");
       try {
         mm.removeMessageListener("SPPingService", self._messageListener);
         mm.removeMessageListener("SpecialPowers.FilesCreated", self._messageListener);
         mm.removeMessageListener("SpecialPowers.FilesError", self._messageListener);
+        mm.removeMessageListener("SPServiceWorkerCleanupComplete", self._messageListener);
       } catch (e) {
         // Ignore the exception which the message manager has been destroyed.
         if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE) {
           throw e;
         }
       }
     }
   }, "inner-window-destroyed");
@@ -163,16 +168,28 @@ SpecialPowers.prototype._messageReceived
     case "SpecialPowers.FilesError":
       var errorHandler = this._createFilesOnError;
       this._createFilesOnSuccess = null;
       this._createFilesOnError = null;
       if (errorHandler) {
         errorHandler(aMessage.data);
       }
       break;
+
+    case "SPServiceWorkerCleanupComplete": {
+      let id = aMessage.data.id;
+      // It's possible for us to receive requests for other SpecialPowers
+      // instances, ignore them.
+      if (this._serviceWorkerCleanUpRequests.has(id)) {
+        let resolve = this._serviceWorkerCleanUpRequests.get(id);
+        this._serviceWorkerCleanUpRequests.delete(id);
+        resolve();
+      }
+      break;
+    }
   }
 
   return true;
 };
 
 SpecialPowers.prototype.quit = function() {
   this.mm.sendAsyncMessage("SpecialPowers.Quit", {});
 };
@@ -257,16 +274,25 @@ SpecialPowers.prototype.isServiceWorkerR
     // call to the parent to make sure that it called unregister on all of its
     // service workers.
     return this._sendSyncMessage("SPCheckServiceWorkers")[0].hasWorkers;
   }
 
   return false;
 };
 
+SpecialPowers.prototype._removeServiceWorkerData = function(messageName) {
+  return new Promise(resolve => {
+    let id = Cc["@mozilla.org/uuid-generator;1"]
+               .getService(Ci.nsIUUIDGenerator).generateUUID().toString();
+    this._serviceWorkerCleanUpRequests.set(id, resolve);
+    this._sendAsyncMessage(messageName, { id });
+  });
+};
+
 // Attach our API to the window.
 function attachSpecialPowersToWindow(aWindow, mm) {
   try {
     if ((aWindow !== null) &&
         (aWindow !== undefined) &&
         (aWindow.wrappedJSObject) &&
         !(aWindow.wrappedJSObject.SpecialPowers)) {
       let sp = new SpecialPowers(aWindow, mm);
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -26,18 +26,16 @@ ChromeUtils.defineModuleGetter(this, "Mo
 ChromeUtils.defineModuleGetter(this, "MockPermissionPrompt",
                                "resource://specialpowers/MockPermissionPrompt.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
                                "resource://gre/modules/PrivateBrowsingUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "NetUtil",
                                "resource://gre/modules/NetUtil.jsm");
 ChromeUtils.defineModuleGetter(this, "AppConstants",
                                "resource://gre/modules/AppConstants.jsm");
-ChromeUtils.defineModuleGetter(this, "ServiceWorkerCleanUp",
-                               "resource://gre/modules/ServiceWorkerCleanUp.jsm");
 
 ChromeUtils.defineModuleGetter(this, "PerTestCoverageUtils",
   "resource://testing-common/PerTestCoverageUtils.jsm");
 
 // Allow stuff from this scope to be accessed from non-privileged scopes. This
 // would crash if used outside of automation.
 Cu.forcePermissiveCOWs();
 
@@ -1972,21 +1970,21 @@ SpecialPowersAPI.prototype = {
       "op": "notify",
       "observerTopic": topic,
       "observerData": data,
     };
     this._sendSyncMessage("SPObserverService", msg);
   },
 
   removeAllServiceWorkerData() {
-    return wrapIfUnwrapped(ServiceWorkerCleanUp.removeAll());
+    return wrapIfUnwrapped(this._removeServiceWorkerData("SPRemoveAllServiceWorkers"));
   },
 
   removeServiceWorkerDataForExampleDomain() {
-    return wrapIfUnwrapped(ServiceWorkerCleanUp.removeFromHost("example.com"));
+    return wrapIfUnwrapped(this._removeServiceWorkerData("SPRemoveServiceWorkerDataForExampleDomain"));
   },
 
   cleanUpSTSData(origin, flags) {
     return this._sendSyncMessage("SPCleanUpSTSData", {origin, flags: flags || 0});
   },
 
   requestDumpCoverageCounters(cb) {
     // We want to avoid a roundtrip between child and parent.