123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /* 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";
- var {Constructor: CC, classes: Cc, interfaces: Ci, utils: Cu} = Components;
- var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
- const ServerSocket = CC("@mozilla.org/network/server-socket;1", "nsIServerSocket", "initSpecialConnection");
- Cu.import("resource://gre/modules/Log.jsm");
- Cu.import("resource://gre/modules/Preferences.jsm");
- Cu.import("resource://gre/modules/Services.jsm");
- Cu.import("chrome://marionette/content/dispatcher.js");
- Cu.import("chrome://marionette/content/driver.js");
- Cu.import("chrome://marionette/content/element.js");
- Cu.import("chrome://marionette/content/simpletest.js");
- // Bug 1083711: Load transport.js as an SDK module instead of subscript
- loader.loadSubScript("resource://devtools/shared/transport/transport.js");
- const logger = Log.repository.getLogger("Marionette");
- this.EXPORTED_SYMBOLS = ["MarionetteServer"];
- const CONTENT_LISTENER_PREF = "marionette.contentListener";
- const MANAGE_OFFLINE_STATUS_PREF = "network.gonk.manage-offline-status";
- /**
- * Bootstraps Marionette and handles incoming client connections.
- *
- * Once started, it opens a TCP socket sporting the debugger transport
- * protocol on the provided port. For every new client a Dispatcher is
- * created.
- *
- * @param {number} port
- * Port for server to listen to.
- * @param {boolean} forceLocal
- * Listen only to connections from loopback if true. If false,
- * accept all connections.
- */
- this.MarionetteServer = function (port, forceLocal) {
- this.port = port;
- this.forceLocal = forceLocal;
- this.conns = {};
- this.nextConnId = 0;
- this.alive = false;
- this._acceptConnections = false;
- };
- /**
- * Function produces a GeckoDriver.
- *
- * Determines application nameto initialise the driver with.
- *
- * @return {GeckoDriver}
- * A driver instance.
- */
- MarionetteServer.prototype.driverFactory = function() {
- let appName = isMulet() ? "B2G" : Services.appinfo.name;
- let bypassOffline = false;
- Preferences.set(CONTENT_LISTENER_PREF, false);
- if (bypassOffline) {
- logger.debug("Bypassing offline status");
- Preferences.set(MANAGE_OFFLINE_STATUS_PREF, false);
- Services.io.manageOfflineStatus = false;
- Services.io.offline = false;
- }
- return new GeckoDriver(appName, this);
- };
- MarionetteServer.prototype.__defineSetter__("acceptConnections", function (value) {
- if (!value) {
- logger.info("New connections will no longer be accepted");
- } else {
- logger.info("New connections are accepted again");
- }
- this._acceptConnections = value;
- });
- MarionetteServer.prototype.start = function() {
- if (this.alive) {
- return;
- }
- let flags = Ci.nsIServerSocket.KeepWhenOffline;
- if (this.forceLocal) {
- flags |= Ci.nsIServerSocket.LoopbackOnly;
- }
- this.listener = new ServerSocket(this.port, flags, 1);
- this.listener.asyncListen(this);
- this.alive = true;
- this._acceptConnections = true;
- };
- MarionetteServer.prototype.stop = function() {
- if (!this.alive) {
- return;
- }
- this.closeListener();
- this.alive = false;
- this._acceptConnections = false;
- };
- MarionetteServer.prototype.closeListener = function() {
- this.listener.close();
- this.listener = null;
- };
- MarionetteServer.prototype.onSocketAccepted = function (
- serverSocket, clientSocket) {
- if (!this._acceptConnections) {
- logger.warn("New connections are currently not accepted");
- return;
- }
- let input = clientSocket.openInputStream(0, 0, 0);
- let output = clientSocket.openOutputStream(0, 0, 0);
- let transport = new DebuggerTransport(input, output);
- let connId = "conn" + this.nextConnId++;
- let dispatcher = new Dispatcher(connId, transport, this.driverFactory.bind(this));
- dispatcher.onclose = this.onConnectionClosed.bind(this);
- this.conns[connId] = dispatcher;
- logger.debug(`Accepted connection ${connId} from ${clientSocket.host}:${clientSocket.port}`);
- dispatcher.sayHello();
- transport.ready();
- };
- MarionetteServer.prototype.onConnectionClosed = function (conn) {
- let id = conn.connId;
- delete this.conns[id];
- logger.debug(`Closed connection ${id}`);
- };
- function isMulet() {
- return Preferences.get("b2g.is_mulet", false);
- }
|