tor-browser

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

adb-client.js (3418B)


      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 /*
      6 * A module to track device changes
      7 * Adapted from adb.js at
      8 * https://github.com/mozilla/adbhelper/tree/f44386c2d8cb7635a7d2c5a51191c89b886f8327
      9 */
     10 
     11 "use strict";
     12 
     13 const {
     14  AdbSocket,
     15 } = require("resource://devtools/client/shared/remote-debugging/adb/adb-socket.js");
     16 const { dumpn } = require("resource://devtools/shared/DevToolsUtils.js");
     17 
     18 const OKAY = 0x59414b4f;
     19 const FAIL = 0x4c494146;
     20 
     21 // Return buffer, which differs between Gecko versions
     22 function getBuffer(packet) {
     23  return packet.buffer ? packet.buffer : packet;
     24 }
     25 
     26 /**
     27 * Decode an adb packet into a JS object with length (number) and data (string)
     28 * properties.
     29 *
     30 * @param packet
     31 *     The packet to get the content from.
     32 * @param
     33 *     ignoreResponse True if this packet has no OKAY/FAIL.
     34 * @return
     35 *     A js object with the following properties:
     36 *     - length (number): length of the decoded data
     37 *     - data (string): the decoded data as a string. Can be multiline (\n)
     38 */
     39 function unpackPacket(packet, ignoreResponse) {
     40  const buffer = getBuffer(packet);
     41  dumpn("Len buffer: " + buffer.byteLength);
     42  if (buffer.byteLength === 4 && !ignoreResponse) {
     43    dumpn("Packet empty");
     44    return { length: 0, data: "" };
     45  }
     46  let index = 0;
     47  let totalLength = 0;
     48  const decodedText = [];
     49 
     50  // Prepare a decoder.
     51  const decoder = new TextDecoder();
     52 
     53  // Loop over all lines in the packet
     54  while (index < buffer.byteLength) {
     55    // Set the index to 4 if we need to skip the response bytes.
     56    index += ignoreResponse ? 0 : 4;
     57 
     58    // Read the packet line length.
     59    const lengthView = new Uint8Array(buffer, index, 4);
     60    const length = parseInt(decoder.decode(lengthView), 16);
     61 
     62    // Move the index after the last size byte.
     63    index += 4;
     64 
     65    // Read the packet line content and append it to the decodedText array.
     66    const text = new Uint8Array(buffer, index, length);
     67    decodedText.push(decoder.decode(text));
     68 
     69    // Move the index after the last read byte for this packet line.
     70    index += length;
     71    // Note: totalLength is only used for logging purposes.
     72    totalLength += length;
     73  }
     74  return { length: totalLength, data: decodedText.join("\n") };
     75 }
     76 
     77 // Checks if the response is expected (defaults to OKAY).
     78 // @return true if response equals expected.
     79 function checkResponse(packet, expected = OKAY) {
     80  const buffer = getBuffer(packet);
     81  const view = new Uint32Array(buffer, 0, 1);
     82  if (view[0] == FAIL) {
     83    dumpn("Response: FAIL");
     84  }
     85  dumpn("view[0] = " + view[0]);
     86  return view[0] == expected;
     87 }
     88 
     89 // @param aCommand A protocol-level command as described in
     90 //  http://androidxref.com/4.0.4/xref/system/core/adb/OVERVIEW.TXT and
     91 //  http://androidxref.com/4.0.4/xref/system/core/adb/SERVICES.TXT
     92 // @return A 8 bit typed array.
     93 function createRequest(command) {
     94  let length = command.length.toString(16).toUpperCase();
     95  while (length.length < 4) {
     96    length = "0" + length;
     97  }
     98 
     99  const encoder = new TextEncoder();
    100  dumpn("Created request: " + length + command);
    101  return encoder.encode(length + command);
    102 }
    103 
    104 function connect() {
    105  return new AdbSocket();
    106 }
    107 
    108 const client = {
    109  getBuffer,
    110  unpackPacket,
    111  checkResponse,
    112  createRequest,
    113  connect,
    114 };
    115 
    116 module.exports = client;