Bug 1153292 - part5: create ServiceWorkerActor;r=janx draft
authorJulian Descottes <jdescottes@mozilla.com>
Tue, 27 Sep 2016 20:52:50 +0200
changeset 420136 d27c8063dd690aded44ef3e9bf7ed4ddba838a89
parent 420135 83bcd044a79b616b202f87cc9a93182fc12b4c24
child 532729 30b15082ec84a1bde738cb10df0cae54698ed527
push id31104
push userjdescottes@mozilla.com
push dateMon, 03 Oct 2016 13:33:13 +0000
reviewersjanx
bugs1153292
milestone52.0a1
Bug 1153292 - part5: create ServiceWorkerActor;r=janx MozReview-Commit-ID: CdlqUHHW1O1
devtools/client/aboutdebugging/components/workers/panel.js
devtools/server/actors/worker.js
devtools/shared/specs/worker.js
--- a/devtools/client/aboutdebugging/components/workers/panel.js
+++ b/devtools/client/aboutdebugging/components/workers/panel.js
@@ -55,32 +55,23 @@ module.exports = createClass({
     client.removeListener("registration-changed", this.update);
   },
 
   update() {
     let workers = this.getInitialState().workers;
 
     getWorkerForms(this.props.client).then(forms => {
       forms.registrations.forEach(form => {
-        // - In e10s: only active registrations are available, but if the worker is in
-        // activating state it won't be available as the activeWorker. Registrations with
-        // no worker are actually registrations with a hidden activating worker.
-        // - In non-e10s: registrations always have at least one worker, if it is an
-        // active worker, the registration is active.
-        let hasWorker = form.activeWorker || form.waitingWorker || form.installingWorker;
-        let isE10s = Services.appinfo.browserTabsRemoteAutostart;
-        let active = form.activeWorker || (isE10s && !hasWorker);
-
         workers.service.push({
           icon: WorkerIcon,
           name: form.url,
           url: form.url,
           scope: form.scope,
           registrationActor: form.actor,
-          active
+          active: form.active
         });
       });
 
       forms.workers.forEach(form => {
         let worker = {
           icon: WorkerIcon,
           name: form.url,
           url: form.url,
@@ -94,27 +85,21 @@ module.exports = createClass({
               // have a scriptSpec, but its associated WorkerDebugger does.
               if (!registration.url) {
                 registration.name = registration.url = form.url;
               }
               registration.workerActor = form.actor;
             } else {
               // If a service worker registration could not be found, this means we are in
               // e10s, and registrations are not forwarded to other processes until they
-              // reach the activated state. Add a temporary registration to display it in
-              // aboutdebugging.
-              workers.service.push({
-                icon: WorkerIcon,
-                name: form.url,
-                url: form.url,
-                scope: form.scope,
-                registrationActor: null,
-                workerActor: form.actor,
-                active: false
-              });
+              // reach the activated state. Augment the worker as a registration worker to
+              // display it in aboutdebugging.
+              worker.scope = form.scope;
+              worker.active = false;
+              workers.service.push(worker);
             }
             break;
           case Ci.nsIWorkerDebugger.TYPE_SHARED:
             workers.shared.push(worker);
             break;
           default:
             workers.other.push(worker);
         }
--- a/devtools/server/actors/worker.js
+++ b/devtools/server/actors/worker.js
@@ -9,16 +9,17 @@ const { DebuggerServer } = require("devt
 const Services = require("Services");
 const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
 const protocol = require("devtools/shared/protocol");
 const { Arg, method, RetVal } = protocol;
 const {
   workerSpec,
   pushSubscriptionSpec,
   serviceWorkerRegistrationSpec,
+  serviceWorkerSpec,
 } = require("devtools/shared/specs/worker");
 
 loader.lazyRequireGetter(this, "ChromeUtils");
 loader.lazyRequireGetter(this, "events", "sdk/event/core");
 
 XPCOMUtils.defineLazyServiceGetter(
   this, "wdm",
   "@mozilla.org/dom/workers/workerdebuggermanager;1",
@@ -334,16 +335,39 @@ let PushSubscriptionActor = protocol.Act
   },
 
   destroy() {
     protocol.Actor.prototype.destroy.call(this);
     this._subscription = null;
   },
 });
 
+let ServiceWorkerActor = protocol.ActorClassWithSpec(serviceWorkerSpec, {
+  initialize(conn, worker) {
+    protocol.Actor.prototype.initialize.call(this, conn);
+    this._worker = worker;
+  },
+
+  form() {
+    if (!this._worker) {
+      return null;
+    }
+
+    return {
+      url: this._worker.scriptSpec,
+      state: this._worker.state,
+    };
+  },
+
+  destroy() {
+    protocol.Actor.prototype.destroy.call(this);
+    this._worker = null;
+  },
+});
+
 // Lazily load the service-worker-child.js process script only once.
 let _serviceWorkerProcessScriptLoaded = false;
 
 let ServiceWorkerRegistrationActor =
 protocol.ActorClassWithSpec(serviceWorkerRegistrationSpec, {
   /**
    * Create the ServiceWorkerRegistrationActor
    * @param DebuggerServerConnection conn
@@ -352,67 +376,79 @@ protocol.ActorClassWithSpec(serviceWorke
    *   The registration's information.
    */
   initialize(conn, registration) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this._conn = conn;
     this._registration = registration;
     this._pushSubscriptionActor = null;
     this._registration.addListener(this);
+
+    let {installingWorker, waitingWorker, activeWorker} = registration;
+    this._installingWorker = new ServiceWorkerActor(conn, installingWorker);
+    this._waitingWorker = new ServiceWorkerActor(conn, waitingWorker);
+    this._activeWorker = new ServiceWorkerActor(conn, activeWorker);
+
     Services.obs.addObserver(this, PushService.subscriptionModifiedTopic, false);
   },
 
-  get installingWorkerForm() {
-    return this._getWorkerForm(this._registration.installingWorker);
-  },
-
-  get activeWorkerForm() {
-    return this._getWorkerForm(this._registration.activeWorker);
-  },
+  onChange() {
+    this._installingWorker.destroy();
+    this._waitingWorker.destroy();
+    this._activeWorker.destroy();
 
-  get waitingWorkerForm() {
-    return this._getWorkerForm(this._registration.waitingWorker);
-  },
+    let {installingWorker, waitingWorker, activeWorker} = this._registration;
+    this._installingWorker = new ServiceWorkerActor(this._conn, installingWorker);
+    this._waitingWorker = new ServiceWorkerActor(this._conn, waitingWorker);
+    this._activeWorker = new ServiceWorkerActor(this._conn, activeWorker);
 
-  _getWorkerForm: function (worker) {
-    if (!worker) {
-      return null;
-    }
-
-    return { url: worker.scriptSpec, state: worker.state };
-  },
-
-  onChange: function () {
     events.emit(this, "registration-changed");
   },
 
   form(detail) {
     if (detail === "actorid") {
       return this.actorID;
     }
     let registration = this._registration;
+    let installingWorker = this._installingWorker.form();
+    let waitingWorker = this._waitingWorker.form();
+    let activeWorker = this._activeWorker.form();
+
+    let isE10s = Services.appinfo.browserTabsRemoteAutostart;
     return {
       actor: this.actorID,
       scope: registration.scope,
       url: registration.scriptSpec,
-      installingWorker: this.installingWorkerForm,
-      activeWorker: this.activeWorkerForm,
-      waitingWorker: this.waitingWorkerForm,
+      installingWorker,
+      waitingWorker,
+      activeWorker,
+      // - In e10s: only active registrations are available.
+      // - In non-e10s: registrations always have at least one worker, if the worker is
+      // active, the registration is active.
+      active: isE10s ? true : !!activeWorker
     };
   },
 
   destroy() {
     protocol.Actor.prototype.destroy.call(this);
     Services.obs.removeObserver(this, PushService.subscriptionModifiedTopic, false);
     this._registration.removeListener(this);
     this._registration = null;
     if (this._pushSubscriptionActor) {
       this._pushSubscriptionActor.destroy();
     }
     this._pushSubscriptionActor = null;
+
+    this._installingWorker.destroy();
+    this._waitingWorker.destroy();
+    this._activeWorker.destroy();
+
+    this._installingWorker = null;
+    this._waitingWorker = null;
+    this._activeWorker = null;
   },
 
   disconnect() {
     this.destroy();
   },
 
   /**
    * Standard observer interface to listen to push messages and changes.
--- a/devtools/shared/specs/worker.js
+++ b/devtools/shared/specs/worker.js
@@ -64,8 +64,15 @@ const serviceWorkerRegistrationSpec = ge
       response: {
         subscription: RetVal("nullable:pushSubscription")
       }
     },
   },
 });
 
 exports.serviceWorkerRegistrationSpec = serviceWorkerRegistrationSpec;
+
+const serviceWorkerSpec = generateActorSpec({
+  typeName: "serviceWorker",
+});
+
+exports.serviceWorkerSpec = serviceWorkerSpec;
+