Bug 1400256 - Serialise IPC messages with evaluate.toJSON. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Thu, 05 Oct 2017 17:50:34 +0100
changeset 683311 ae899d0c3701875596b7d708c92ab4899ce16b65
parent 683310 44c433bda0c6f9097aa52a5e509c10edf31c32f1
child 683312 e8e3450ce2047088c7354a885538a998648acab7
push id85331
push userbmo:ato@sny.no
push dateThu, 19 Oct 2017 14:55:23 +0000
reviewerswhimboo
bugs1400256
milestone58.0a1
Bug 1400256 - Serialise IPC messages with evaluate.toJSON. r?whimboo Instead of having commands serialising their own JSON-safe messages when communicating with the content frame script, this patch changes the AsyncMessageChannel to use evaluate.toJSON. MozReview-Commit-ID: LmAVGEjqMTB
testing/marionette/proxy.js
--- a/testing/marionette/proxy.js
+++ b/testing/marionette/proxy.js
@@ -8,16 +8,17 @@ const {classes: Cc, interfaces: Ci, util
 
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const {
   error,
   WebDriverError,
 } = Cu.import("chrome://marionette/content/error.js", {});
+Cu.import("chrome://marionette/content/evaluate.js");
 Cu.import("chrome://marionette/content/modal.js");
 
 this.EXPORTED_SYMBOLS = ["proxy"];
 
 const uuidgen = Cc["@mozilla.org/uuid-generator;1"]
     .getService(Ci.nsIUUIDGenerator);
 
 const logger = Log.repository.getLogger("Marionette");
@@ -121,53 +122,54 @@ proxy.AsyncMessageChannel = class {
     let uuid = uuidgen.generateUUID().toString();
     // TODO(ato): Bug 1242595
     this.activeMessageId = uuid;
 
     return new Promise((resolve, reject) => {
       let path = proxy.AsyncMessageChannel.makePath(uuid);
       let cb = msg => {
         this.activeMessageId = null;
+        let {data, type} = msg.json;
 
         switch (msg.json.type) {
           case proxy.AsyncMessageChannel.ReplyType.Ok:
           case proxy.AsyncMessageChannel.ReplyType.Value:
-            resolve(msg.json.data);
+            let payload = evaluate.fromJSON(data);
+            resolve(payload);
             break;
 
           case proxy.AsyncMessageChannel.ReplyType.Error:
-            let err = WebDriverError.fromJSON(msg.json.data);
+            let err = WebDriverError.fromJSON(data);
             reject(err);
             break;
 
           default:
-            throw new TypeError(
-                `Unknown async response type: ${msg.json.type}`);
+            throw new TypeError(`Unknown async response type: ${type}`);
         }
       };
 
       // The currently selected tab or window has been closed. No clean-up
       // is necessary to do because all loaded listeners are gone.
-      this.closeHandler = event => {
-        logger.debug(`Received DOM event ${event.type} for ${event.target}`);
+      this.closeHandler = ({type, target}) => {
+        logger.debug(`Received DOM event ${type} for ${target}`);
 
-        switch (event.type) {
+        switch (type) {
           case "TabClose":
           case "unload":
             this.removeHandlers();
             resolve();
             break;
         }
       };
 
       // A modal or tab modal dialog has been opened. To be able to handle it,
       // the active command has to be aborted. Therefore remove all handlers,
       // and cancel any ongoing requests in the listener.
       this.dialogueObserver_ = (subject, topic) => {
-        logger.debug(`Received observer notification "${topic}"`);
+        logger.debug(`Received observer notification ${topic}`);
 
         this.removeAllListeners_();
         // TODO(ato): It's not ideal to have listener specific behaviour here:
         this.sendAsync("cancelRequest");
 
         this.removeHandlers();
         resolve();
       };
@@ -254,27 +256,21 @@ proxy.AsyncMessageChannel = class {
     } else if (error.isError(obj)) {
       let err = error.wrap(obj);
       this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Error, err);
     } else {
       this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Value, obj);
     }
   }
 
-  sendReply_(uuid, type, data = undefined) {
+  sendReply_(uuid, type, payload = undefined) {
     const path = proxy.AsyncMessageChannel.makePath(uuid);
 
-    let payload;
-    if (data && typeof data.toJSON == "function") {
-      payload = data.toJSON();
-    } else {
-      payload = data;
-    }
-
-    const msg = {type, data: payload};
+    let data = evaluate.toJSON(payload);
+    const msg = {type, data};
 
     // here sendAsync is actually the content frame's
     // sendAsyncMessage(path, message) global
     this.sendAsync(path, msg);
   }
 
   /**
    * Produces a path, or a name, for the message listener handler that