tor-browser

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

adb-runtime.js (4022B)


      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
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  prepareTCPConnection,
      9 } = require("resource://devtools/client/shared/remote-debugging/adb/commands/index.js");
     10 const {
     11  shell,
     12 } = require("resource://devtools/client/shared/remote-debugging/adb/commands/index.js");
     13 
     14 class AdbRuntime {
     15  constructor(adbDevice, socketPath) {
     16    this._adbDevice = adbDevice;
     17    this._socketPath = socketPath;
     18    // Set a default version name in case versionName cannot be parsed.
     19    this._versionName = "";
     20  }
     21 
     22  async init() {
     23    const packageName = this._packageName();
     24    const query = `dumpsys package ${packageName} | grep versionName`;
     25    const versionNameString = await shell(this._adbDevice.id, query);
     26 
     27    // The versionName can have different formats depending on the channel
     28    // - `versionName=Nightly 191016 06:01\n` on Nightly
     29    // - `versionName=2.1.0\n` on Release
     30    // We use a very flexible regular expression to accommodate for those
     31    // different formats.
     32    const matches = versionNameString.match(/versionName=(.*)\n/);
     33    if (matches?.[1]) {
     34      this._versionName = matches[1];
     35    }
     36  }
     37 
     38  get id() {
     39    return this._adbDevice.id + "|" + this._socketPath;
     40  }
     41 
     42  get isFenix() {
     43    // Firefox Release uses "org.mozilla.firefox"
     44    // Firefox Beta uses "org.mozilla.firefox_beta"
     45    // Firefox Nightly uses "org.mozilla.fenix"
     46    const isFirefox =
     47      this._packageName().includes("org.mozilla.firefox") ||
     48      this._packageName().includes("org.mozilla.fenix");
     49 
     50    if (!isFirefox) {
     51      return false;
     52    }
     53 
     54    // Firefox Release (based on Fenix) is not released in all regions yet, so
     55    // we should still check for Fennec using the version number.
     56    // Note that Fennec's versionName followed Firefox versions (eg "68.11.0").
     57    // We can find the main version number in it. Fenix on the other hand has
     58    // version names such as "Nightly 200730 06:21".
     59    const mainVersion = Number(this.versionName.split(".")[0]);
     60    const isFennec = mainVersion === 68;
     61 
     62    // Application is Fenix if this is a Firefox application with a version
     63    // different from the Fennec version.
     64    return !isFennec;
     65  }
     66 
     67  get deviceId() {
     68    return this._adbDevice.id;
     69  }
     70 
     71  get deviceName() {
     72    return this._adbDevice.name;
     73  }
     74 
     75  get versionName() {
     76    return this._versionName;
     77  }
     78 
     79  get shortName() {
     80    const packageName = this._packageName();
     81 
     82    switch (packageName) {
     83      case "org.mozilla.firefox":
     84        if (!this.isFenix) {
     85          // Old Fennec release
     86          return "Firefox (Fennec)";
     87        }
     88        // Official Firefox app, based on Fenix
     89        return "Firefox";
     90      case "org.mozilla.firefox_beta":
     91        // Official Firefox Beta app, based on Fenix
     92        return "Firefox Beta";
     93      case "org.mozilla.fenix":
     94      case "org.mozilla.fenix.nightly":
     95        // Official Firefox Nightly app, based on Fenix
     96        return "Firefox Nightly";
     97      default:
     98        // Unknown package name
     99        return `Firefox (${packageName})`;
    100    }
    101  }
    102 
    103  get socketPath() {
    104    return this._socketPath;
    105  }
    106 
    107  get name() {
    108    return `${this.shortName} on Android (${this.deviceName})`;
    109  }
    110 
    111  connect(connection) {
    112    return prepareTCPConnection(this.deviceId, this._socketPath).then(port => {
    113      connection.host = "localhost";
    114      connection.port = port;
    115      connection.connect();
    116    });
    117  }
    118 
    119  _packageName() {
    120    // If using abstract socket address, it is "@org.mozilla.firefox/..."
    121    // If using path base socket, it is "/data/data/<package>...""
    122    // Until Fennec 62 only supports path based UNIX domain socket, but
    123    // Fennec 63+ supports both path based and abstract socket.
    124    return this._socketPath.startsWith("@")
    125      ? this._socketPath.substr(1).split("/")[0]
    126      : this._socketPath.split("/")[3];
    127  }
    128 }
    129 exports.AdbRuntime = AdbRuntime;