Bug 1000814 - Cleanup marionette transport.js from DevTools specifics. r=jryans draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Wed, 11 Jul 2018 07:07:58 -0700
changeset 817211 227e6c519f62cdd59e59bb788cc0e118f55d9455
parent 815516 ffb7b5015fc331bdc4c5e6ab52b9de669faa8864
child 817212 3e3b4be1b441810a1c6858d6899413857e48b545
push id115987
push userbmo:poirot.alex@gmail.com
push dateThu, 12 Jul 2018 07:12:00 +0000
reviewersjryans
bugs1000814
milestone63.0a1
Bug 1000814 - Cleanup marionette transport.js from DevTools specifics. r=jryans MozReview-Commit-ID: 5aKwtYeuVs1
testing/marionette/transport.js
--- a/testing/marionette/transport.js
+++ b/testing/marionette/transport.js
@@ -1,35 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-/* global Pipe, ScriptableInputStream, uneval */
+/* global Pipe, ScriptableInputStream */
 
 const CC = Components.Constructor;
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/EventEmitter.jsm");
 const {StreamUtils} =
     ChromeUtils.import("chrome://marionette/content/stream-utils.js", {});
 const {Packet, JSONPacket, BulkPacket} =
     ChromeUtils.import("chrome://marionette/content/packets.js", {});
 
-const defer = function() {
-  let deferred = {
-    promise: new Promise((resolve, reject) => {
-      deferred.resolve = resolve;
-      deferred.reject = reject;
-    }),
-  };
-  return deferred;
-};
-
 const executeSoon = function(func) {
   Services.tm.dispatchToMainThread(func);
 };
 
 const flags = {wantVerbose: false, wantLogging: false};
 
 const dumpv =
   flags.wantVerbose ?
@@ -526,401 +516,8 @@ DebuggerTransport.prototype = {
   _destroyIncoming() {
     if (this._incoming) {
       this._incoming.destroy();
     }
     this._incomingHeader = "";
     this._incoming = null;
   },
 };
-
-/**
- * An adapter that handles data transfers between the debugger client
- * and server when they both run in the same process. It presents the
- * same API as DebuggerTransport, but instead of transmitting serialized
- * messages across a connection it merely calls the packet dispatcher of
- * the other side.
- *
- * @param {LocalDebuggerTransport} other
- *     The other endpoint for this debugger connection.
- *
- * @see {DebuggerTransport}
- */
-function LocalDebuggerTransport(other) {
-  EventEmitter.decorate(this);
-
-  this.other = other;
-  this.hooks = null;
-
-  // A packet number, shared between this and this.other. This isn't
-  // used by the protocol at all, but it makes the packet traces a lot
-  // easier to follow.
-  this._serial = this.other ? this.other._serial : {count: 0};
-  this.close = this.close.bind(this);
-}
-
-LocalDebuggerTransport.prototype = {
-  /**
-   * Transmit a message by directly calling the onPacket handler of the other
-   * endpoint.
-   */
-  send(packet) {
-    this.emit("send", packet);
-
-    let serial = this._serial.count++;
-    if (flags.wantLogging) {
-      // Check 'from' first, as 'echo' packets have both.
-      if (packet.from) {
-        dumpv("Packet " + serial + " sent from " + uneval(packet.from));
-      } else if (packet.to) {
-        dumpv("Packet " + serial + " sent to " + uneval(packet.to));
-      }
-    }
-    this._deepFreeze(packet);
-    let other = this.other;
-    if (other) {
-      executeSoon(() => {
-        // Avoid the cost of JSON.stringify() when logging is disabled.
-        if (flags.wantLogging) {
-          dumpv(`Received packet ${serial}: ` +
-              JSON.stringify(packet, null, 2));
-        }
-        if (other.hooks) {
-          other.emit("packet", packet);
-          other.hooks.onPacket(packet);
-        }
-      });
-    }
-  },
-
-  /**
-   * Send a streaming bulk packet directly to the onBulkPacket handler
-   * of the other endpoint.
-   *
-   * This case is much simpler than the full DebuggerTransport, since
-   * there is no primary stream we have to worry about managing while
-   * we hand it off to others temporarily.  Instead, we can just make a
-   * single use pipe and be done with it.
-   */
-  startBulkSend({actor, type, length}) {
-    this.emit("startbulksend", {actor, type, length});
-
-    let serial = this._serial.count++;
-
-    dumpv("Sent bulk packet " + serial + " for actor " + actor);
-    if (!this.other) {
-      let error = new Error("startBulkSend: other side of transport missing");
-      return Promise.reject(error);
-    }
-
-    let pipe = new Pipe(true, true, 0, 0, null);
-
-    executeSoon(() => {
-      dumpv("Received bulk packet " + serial);
-      if (!this.other.hooks) {
-        return;
-      }
-
-      // Receiver
-      let deferred = defer();
-      let packet = {
-        actor,
-        type,
-        length,
-        copyTo: (output) => {
-          let copying =
-          StreamUtils.copyStream(pipe.inputStream, output, length);
-          deferred.resolve(copying);
-          return copying;
-        },
-        stream: pipe.inputStream,
-        done: deferred,
-      };
-
-      this.other.emit("bulkpacket", packet);
-      this.other.hooks.onBulkPacket(packet);
-
-      // Await the result of reading from the stream
-      deferred.promise.then(() => pipe.inputStream.close(), this.close);
-    });
-
-    // Sender
-    let sendDeferred = defer();
-
-    // The remote transport is not capable of resolving immediately here,
-    // so we shouldn't be able to either.
-    executeSoon(() => {
-      let copyDeferred = defer();
-
-      sendDeferred.resolve({
-        copyFrom: (input) => {
-          let copying =
-          StreamUtils.copyStream(input, pipe.outputStream, length);
-          copyDeferred.resolve(copying);
-          return copying;
-        },
-        stream: pipe.outputStream,
-        done: copyDeferred,
-      });
-
-      // Await the result of writing to the stream
-      copyDeferred.promise.then(() => pipe.outputStream.close(), this.close);
-    });
-
-    return sendDeferred.promise;
-  },
-
-  /**
-   * Close the transport.
-   */
-  close() {
-    this.emit("close");
-
-    if (this.other) {
-      // Remove the reference to the other endpoint before calling close(), to
-      // avoid infinite recursion.
-      let other = this.other;
-      this.other = null;
-      other.close();
-    }
-    if (this.hooks) {
-      try {
-        this.hooks.onClosed();
-      } catch (ex) {
-        console.error(ex);
-      }
-      this.hooks = null;
-    }
-  },
-
-  /**
-   * An empty method for emulating the DebuggerTransport API.
-   */
-  ready() {},
-
-  /**
-   * Helper function that makes an object fully immutable.
-   */
-  _deepFreeze(object) {
-    Object.freeze(object);
-    for (let prop in object) {
-      // Freeze the properties that are objects, not on the prototype,
-      // and not already frozen.  Note that this might leave an unfrozen
-      // reference somewhere in the object if there is an already frozen
-      // object containing an unfrozen object.
-      if (object.hasOwnProperty(prop) && typeof object === "object" &&
-          !Object.isFrozen(object)) {
-        this._deepFreeze(object[prop]);
-      }
-    }
-  },
-};
-
-/**
- * A transport for the debugging protocol that uses nsIMessageManagers to
- * exchange packets with servers running in child processes.
- *
- * In the parent process, <var>mm</var> should be the nsIMessageSender
- * for the child process. In a child process, |mm| should be the child
- * process message manager, which sends packets to the parent.
- *
- * <var>prefix</var> is a string included in the message names, to
- * distinguish multiple servers running in the same child process.
- *
- * This transport exchanges messages named <tt>debug:PREFIX:packet</tt>,
- * where <tt>PREFIX</tt> is <var>prefix</var>, whose data is the protocol
- * packet.
- */
-function ChildDebuggerTransport(mm, prefix) {
-  EventEmitter.decorate(this);
-
-  this._mm = mm;
-  this._messageName = "debug:" + prefix + ":packet";
-}
-
-/*
- * To avoid confusion, we use 'message' to mean something that
- * nsIMessageSender conveys, and 'packet' to mean a remote debugging
- * protocol packet.
- */
-ChildDebuggerTransport.prototype = {
-  constructor: ChildDebuggerTransport,
-
-  hooks: null,
-
-  _addListener() {
-    this._mm.addMessageListener(this._messageName, this);
-  },
-
-  _removeListener() {
-    try {
-      this._mm.removeMessageListener(this._messageName, this);
-    } catch (e) {
-      if (e.result != Cr.NS_ERROR_NULL_POINTER) {
-        throw e;
-      }
-      // In some cases, especially when using messageManagers in non-e10s
-      // mode, we reach this point with a dead messageManager which only
-      // throws errors but does not seem to indicate in any other way that
-      // it is dead.
-    }
-  },
-
-  ready() {
-    this._addListener();
-  },
-
-  close() {
-    this._removeListener();
-    this.emit("close");
-    this.hooks.onClosed();
-  },
-
-  receiveMessage({data}) {
-    this.emit("packet", data);
-    this.hooks.onPacket(data);
-  },
-
-  send(packet) {
-    this.emit("send", packet);
-    try {
-      this._mm.sendAsyncMessage(this._messageName, packet);
-    } catch (e) {
-      if (e.result != Cr.NS_ERROR_NULL_POINTER) {
-        throw e;
-      }
-      // In some cases, especially when using messageManagers in non-e10s
-      // mode, we reach this point with a dead messageManager which only
-      // throws errors but does not seem to indicate in any other way that
-      // it is dead.
-    }
-  },
-
-  startBulkSend() {
-    throw new Error("Can't send bulk data to child processes.");
-  },
-
-  swapBrowser(mm) {
-    this._removeListener();
-    this._mm = mm;
-    this._addListener();
-  },
-};
-
-// WorkerDebuggerTransport is defined differently depending on whether we are
-// on the main thread or a worker thread. In the former case, we are required
-// by the devtools loader, and isWorker will be false. Otherwise, we are
-// required by the worker loader, and isWorker will be true.
-//
-// Each worker debugger supports only a single connection to the main thread.
-// However, its theoretically possible for multiple servers to connect to the
-// same worker. Consequently, each transport has a connection id, to allow
-// messages from multiple connections to be multiplexed on a single channel.
-
-if (!this.isWorker) {
-  // Main thread
-  (function() {
-    /**
-     * A transport that uses a WorkerDebugger to send packets from the main
-     * thread to a worker thread.
-     *
-     * @class WorkerDebuggerTransport
-     */
-    function WorkerDebuggerTransport(dbg, id) {
-      this._dbg = dbg;
-      this._id = id;
-      this.onMessage = this._onMessage.bind(this);
-    }
-
-    WorkerDebuggerTransport.prototype = {
-      constructor: WorkerDebuggerTransport,
-
-      ready() {
-        this._dbg.addListener(this);
-      },
-
-      close() {
-        this._dbg.removeListener(this);
-        if (this.hooks) {
-          this.hooks.onClosed();
-        }
-      },
-
-      send(packet) {
-        this._dbg.postMessage(JSON.stringify({
-          type: "message",
-          id: this._id,
-          message: packet,
-        }));
-      },
-
-      startBulkSend() {
-        throw new Error("Can't send bulk data from worker threads!");
-      },
-
-      _onMessage(message) {
-        let packet = JSON.parse(message);
-        if (packet.type !== "message" || packet.id !== this._id) {
-          return;
-        }
-
-        if (this.hooks) {
-          this.hooks.onPacket(packet.message);
-        }
-      },
-    };
-
-  }).call(this);
-} else {
-  // Worker thread
-  (function() {
-    /**
-     * A transport that uses a WorkerDebuggerGlobalScope to send packets
-     * from a worker thread to the main thread.
-     *
-     * @class WorkerDebuggerTransportThread
-     */
-    function WorkerDebuggerTransport(scope, id) {
-      this._scope = scope;
-      this._id = id;
-      this._onMessage = this._onMessage.bind(this);
-    }
-
-    WorkerDebuggerTransport.prototype = {
-      constructor: WorkerDebuggerTransport,
-
-      ready() {
-        this._scope.addEventListener("message", this._onMessage);
-      },
-
-      close() {
-        this._scope.removeEventListener("message", this._onMessage);
-        if (this.hooks) {
-          this.hooks.onClosed();
-        }
-      },
-
-      send(packet) {
-        this._scope.postMessage(JSON.stringify({
-          type: "message",
-          id: this._id,
-          message: packet,
-        }));
-      },
-
-      startBulkSend() {
-        throw new Error("Can't send bulk data from worker threads!");
-      },
-
-      _onMessage(event) {
-        let packet = JSON.parse(event.data);
-        if (packet.type !== "message" || packet.id !== this._id) {
-          return;
-        }
-
-        if (this.hooks) {
-          this.hooks.onPacket(packet.message);
-        }
-      },
-    };
-
-  }).call(this);
-}