tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GeckoViewRemoteDebugger.sys.mjs (4070B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs";
      6 
      7 const lazy = {};
      8 
      9 ChromeUtils.defineLazyGetter(lazy, "require", () => {
     10  const { require } = ChromeUtils.importESModule(
     11    "resource://devtools/shared/loader/Loader.sys.mjs",
     12    // Ensure loading all DevTools modules in the dedicated "devtools" global
     13    // so that it can safely debug all the privileged modules running from the shared system global.
     14    { global: "devtools" }
     15  );
     16  return require;
     17 });
     18 
     19 ChromeUtils.defineLazyGetter(lazy, "DevToolsServer", () => {
     20  const { DevToolsServer } = lazy.require("devtools/server/devtools-server");
     21  return DevToolsServer;
     22 });
     23 
     24 ChromeUtils.defineLazyGetter(lazy, "SocketListener", () => {
     25  const { SocketListener } = lazy.require("devtools/shared/security/socket");
     26  return SocketListener;
     27 });
     28 
     29 const { debug, warn } = GeckoViewUtils.initLogging("RemoteDebugger");
     30 
     31 export var GeckoViewRemoteDebugger = {
     32  observe(aSubject, aTopic, aData) {
     33    if (aTopic !== "nsPref:changed") {
     34      return;
     35    }
     36 
     37    if (Services.prefs.getBoolPref(aData, false)) {
     38      this.onEnable();
     39    } else {
     40      this.onDisable();
     41    }
     42  },
     43 
     44  onInit() {
     45    debug`onInit`;
     46    this._isEnabled = false;
     47    this._usbDebugger = new USBRemoteDebugger();
     48  },
     49 
     50  onEnable() {
     51    if (this._isEnabled) {
     52      return;
     53    }
     54 
     55    debug`onEnable`;
     56    lazy.DevToolsServer.init();
     57    lazy.DevToolsServer.registerAllActors();
     58    const { createRootActor } = lazy.require(
     59      "resource://gre/modules/dbg-browser-actors.js"
     60    );
     61    lazy.DevToolsServer.setRootActor(createRootActor);
     62    lazy.DevToolsServer.allowChromeProcess = true;
     63    lazy.DevToolsServer.chromeWindowType = "navigator:geckoview";
     64    // Force the Server to stay alive even if there are no connections at the moment.
     65    lazy.DevToolsServer.keepAlive = true;
     66 
     67    // Socket address for USB remote debugger expects
     68    // @{package_name}/firefox-debugger-socket format.
     69    // In /proc/net/unix, it will be outputed as
     70    // @org.mozilla.geckoview_example/firefox-debugger-socket
     71    //
     72    // If package name isn't available, it will be "@firefox-debugger-socket".
     73 
     74    let packageName = Services.env.get("MOZ_ANDROID_PACKAGE_NAME");
     75    if (packageName) {
     76      packageName = packageName + "/";
     77    } else {
     78      warn`Missing env MOZ_ANDROID_PACKAGE_NAME. Unable to get package name`;
     79    }
     80 
     81    this._isEnabled = true;
     82    this._usbDebugger.stop();
     83 
     84    const portOrPath = packageName + "firefox-debugger-socket";
     85    this._usbDebugger.start(portOrPath);
     86  },
     87 
     88  onDisable() {
     89    if (!this._isEnabled) {
     90      return;
     91    }
     92 
     93    debug`onDisable`;
     94    this._isEnabled = false;
     95    this._usbDebugger.stop();
     96  },
     97 };
     98 
     99 class USBRemoteDebugger {
    100  start(aPortOrPath) {
    101    try {
    102      const AuthenticatorType =
    103        lazy.DevToolsServer.Authenticators.get("PROMPT");
    104      const authenticator = new AuthenticatorType.Server();
    105      authenticator.allowConnection = this.allowConnection.bind(this);
    106      const socketOptions = {
    107        authenticator,
    108        portOrPath: aPortOrPath,
    109      };
    110      this._listener = new lazy.SocketListener(
    111        lazy.DevToolsServer,
    112        socketOptions
    113      );
    114      this._listener.open();
    115      debug`USB remote debugger - listening on ${aPortOrPath}`;
    116    } catch (e) {
    117      warn`Unable to start USB debugger server: ${e}`;
    118    }
    119  }
    120 
    121  stop() {
    122    if (!this._listener) {
    123      return;
    124    }
    125 
    126    try {
    127      this._listener.close();
    128      this._listener = null;
    129    } catch (e) {
    130      warn`Unable to stop USB debugger server: ${e}`;
    131    }
    132  }
    133 
    134  allowConnection(aSession) {
    135    if (!this._listener) {
    136      return lazy.DevToolsServer.AuthenticationResult.DENY;
    137    }
    138 
    139    if (aSession.server.port) {
    140      return lazy.DevToolsServer.AuthenticationResult.DENY;
    141    }
    142    return lazy.DevToolsServer.AuthenticationResult.ALLOW;
    143  }
    144 }