UNPKG

@yume-chan/adb

Version:

TypeScript implementation of Android Debug Bridge (ADB) protocol.

108 lines (89 loc) 3 kB
import { PromiseResolver } from "@yume-chan/async"; import type { AdbIncomingSocketHandler, AdbSocket, AdbTransport, } from "../adb.js"; import type { AdbBanner } from "../banner.js"; import { AdbFeature } from "../features.js"; import type { AdbServerClient } from "./client.js"; export const ADB_SERVER_DEFAULT_FEATURES = /* #__PURE__ */ (() => [ AdbFeature.ShellV2, AdbFeature.Cmd, AdbFeature.StatV2, AdbFeature.ListV2, AdbFeature.FixedPushMkdir, "apex", AdbFeature.Abb, // only tells the client the symlink timestamp issue in `adb push --sync` has been fixed. // No special handling required. "fixed_push_symlink_timestamp", AdbFeature.AbbExec, "remount_shell", "track_app", AdbFeature.SendReceiveV2, "sendrecv_v2_brotli", "sendrecv_v2_lz4", "sendrecv_v2_zstd", "sendrecv_v2_dry_run_send", ] as AdbFeature[])(); export class AdbServerTransport implements AdbTransport { #client: AdbServerClient; readonly serial: string; readonly transportId: bigint; readonly maxPayloadSize: number = 1 * 1024 * 1024; readonly banner: AdbBanner; #sockets: AdbSocket[] = []; #closed = new PromiseResolver<void>(); #disconnected: Promise<void>; get disconnected() { return this.#disconnected; } get clientFeatures() { // No need to get host features (features supported by ADB server) // Because we create all ADB packets ourselves return ADB_SERVER_DEFAULT_FEATURES; } // eslint-disable-next-line @typescript-eslint/max-params constructor( client: AdbServerClient, serial: string, banner: AdbBanner, transportId: bigint, disconnected: Promise<void>, ) { this.#client = client; this.serial = serial; this.banner = banner; this.transportId = transportId; this.#disconnected = Promise.race([this.#closed.promise, disconnected]); } async connect(service: string): Promise<AdbSocket> { const socket = await this.#client.createDeviceConnection( { transportId: this.transportId }, service, ); this.#sockets.push(socket); return socket; } async addReverseTunnel( handler: AdbIncomingSocketHandler, address?: string, ): Promise<string> { return await this.#client.connector.addReverseTunnel(handler, address); } async removeReverseTunnel(address: string): Promise<void> { await this.#client.connector.removeReverseTunnel(address); } async clearReverseTunnels(): Promise<void> { await this.#client.connector.clearReverseTunnels(); } async close(): Promise<void> { for (const socket of this.#sockets) { await socket.close(); } this.#sockets.length = 0; this.#closed.resolve(); } }