Bug 1153292 - part5: aboutdebugging: rely on activeWorker to decide if registration is activated;r=janx draft
authorJulian Descottes <jdescottes@mozilla.com>
Tue, 06 Sep 2016 16:34:42 +0200
changeset 411116 25b2133a213c106e98743e7ffe743006dbb04b33
parent 411115 4cd51dbfb06cbc6011941ad900a4c9fbd767a6c0
child 411117 80427528dd5d44468194a2e03d2e94a4769f8547
push id28840
push userjdescottes@mozilla.com
push dateWed, 07 Sep 2016 16:50:43 +0000
reviewersjanx
bugs1153292
milestone51.0a1
Bug 1153292 - part5: aboutdebugging: rely on activeWorker to decide if registration is activated;r=janx MozReview-Commit-ID: 2NkeIDJZb5X
devtools/client/aboutdebugging/components/workers/panel.js
devtools/client/aboutdebugging/components/workers/service-worker-target.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
@@ -37,37 +37,50 @@ module.exports = createClass({
     };
   },
 
   componentDidMount() {
     let client = this.props.client;
     client.addListener("workerListChanged", this.update);
     client.addListener("serviceWorkerRegistrationListChanged", this.update);
     client.addListener("processListChanged", this.update);
+    client.addListener("registration-changed", this.update);
+
     this.update();
   },
 
   componentWillUnmount() {
     let client = this.props.client;
     client.removeListener("processListChanged", this.update);
     client.removeListener("serviceWorkerRegistrationListChanged", this.update);
     client.removeListener("workerListChanged", this.update);
+    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
+          registrationActor: form.actor,
+          active
         });
       });
 
       forms.workers.forEach(form => {
         let worker = {
           icon: WorkerIcon,
           name: form.url,
           url: form.url,
@@ -89,17 +102,18 @@ module.exports = createClass({
               // 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
+                workerActor: form.actor,
+                active: false
               });
             }
             break;
           case Ci.nsIWorkerDebugger.TYPE_SHARED:
             workers.shared.push(worker);
             break;
           default:
             workers.other.push(worker);
--- a/devtools/client/aboutdebugging/components/workers/service-worker-target.js
+++ b/devtools/client/aboutdebugging/components/workers/service-worker-target.js
@@ -25,20 +25,20 @@ module.exports = createClass({
 
   componentDidMount() {
     let { client } = this.props;
     client.addListener("push-subscription-modified", this.onPushSubscriptionModified);
     this.updatePushSubscription();
   },
 
   componentDidUpdate(oldProps, oldState) {
-    let oldRegistrationActor = oldProps.target && oldProps.target.registrationActor;
-    let registrationActor = this.props.target && this.props.target.registrationActor;
+    let wasActive = oldProps.target.active;
+    let isActive = this.props.target.active;
 
-    if (!oldRegistrationActor && registrationActor) {
+    if (!wasActive && isActive) {
       // If the component was created without a registrationActor, updatePushSubscription
       // was not called in componentDidMount, and if the subscription is already attached
       // to the registration when the registration becomes accessible to about:debugging
       // the "push-subscription-modified" event will not be triggered.
       this.updatePushSubscription();
     }
   },
 
@@ -116,26 +116,26 @@ module.exports = createClass({
   },
 
   isRunning() {
     // We know the target is running if it has a worker actor.
     return !!this.props.target.workerActor;
   },
 
   isActive() {
-    return !!this.props.target.registrationActor;
+    return this.props.target.active;
   },
 
   getServiceWorkerStatus() {
     if (this.isActive() && this.isRunning()) {
       return "running";
     } else if (this.isActive()) {
       return "stopped";
     }
-    // We cannot get service worker registrations unless the service worker is in
+    // We cannot get service worker registrations unless the registration is in
     // ACTIVE state. Unable to know the actual state ("installing", "waiting"), we
     // display a custom state "registering" for now. See Bug 1153292.
     return "registering";
   },
 
   renderButtons() {
     let pushButton = dom.button({
       className: "push-button",
--- a/devtools/server/actors/worker.js
+++ b/devtools/server/actors/worker.js
@@ -351,34 +351,63 @@ protocol.ActorClassWithSpec(serviceWorke
    * @param ServiceWorkerRegistrationInfo registration
    *   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);
     Services.obs.addObserver(this, PushService.subscriptionModifiedTopic, false);
   },
 
+  get installingWorkerForm() {
+    return this._getWorkerForm(this._registration.installingWorker);
+  },
+
+  get activeWorkerForm() {
+    return this._getWorkerForm(this._registration.activeWorker);
+  },
+
+  get waitingWorkerForm() {
+    return this._getWorkerForm(this._registration.waitingWorker);
+  },
+
+  _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;
     return {
       actor: this.actorID,
       scope: registration.scope,
-      url: registration.scriptSpec
+      url: registration.scriptSpec,
+      installingWorker: this.installingWorkerForm,
+      activeWorker: this.activeWorkerForm,
+      waitingWorker: this.waitingWorkerForm,
     };
   },
 
   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;
   },
 
   disconnect() {
--- a/devtools/shared/specs/worker.js
+++ b/devtools/shared/specs/worker.js
@@ -39,16 +39,19 @@ const pushSubscriptionSpec = generateAct
 exports.pushSubscriptionSpec = pushSubscriptionSpec;
 
 const serviceWorkerRegistrationSpec = generateActorSpec({
   typeName: "serviceWorkerRegistration",
 
   events: {
     "push-subscription-modified": {
       type: "push-subscription-modified"
+    },
+    "registration-changed": {
+      type: "registration-changed"
     }
   },
 
   methods: {
     start: {
       request: {},
       response: RetVal("json")
     },