Loading libraries/adb-daemon-webusb/src/device.ts +4 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import { import type { ExactReadable } from "@yume-chan/struct"; import { EmptyUint8Array } from "@yume-chan/struct"; import { DeviceBusyError as _DeviceBusyError } from "./error.js"; import type { UsbInterfaceFilter, UsbInterfaceIdentifier } from "./utils.js"; import { findUsbEndpoints, getSerialNumber, isErrorName } from "./utils.js"; Loading Loading @@ -254,6 +255,8 @@ export class AdbDaemonWebUsbConnection } export class AdbDaemonWebUsbDevice implements AdbDaemonDevice { static DeviceBusyError = _DeviceBusyError; #interface: UsbInterfaceIdentifier; #usbManager: USB; Loading Loading @@ -348,11 +351,5 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice { } export namespace AdbDaemonWebUsbDevice { export class DeviceBusyError extends Error { constructor(cause?: Error) { super("The device is already in used by another program", { cause, }); } } export type DeviceBusyError = _DeviceBusyError; } libraries/adb-daemon-webusb/src/error.ts 0 → 100644 +7 −0 Original line number Diff line number Diff line export class DeviceBusyError extends Error { constructor(cause?: Error) { super("The device is already in used by another program", { cause, }); } } libraries/adb-daemon-webusb/src/manager.ts +3 −3 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ export class AdbDaemonWebUsbDeviceManager { * * May be `undefined` if current runtime does not support WebUSB. */ static readonly BROWSER = typeof globalThis.navigator !== "undefined" && !!globalThis.navigator.usb static readonly BROWSER = /* #__PURE__ */ (() => { typeof globalThis.navigator !== "undefined" && globalThis.navigator.usb ? new AdbDaemonWebUsbDeviceManager(globalThis.navigator.usb) : undefined; })(); #usbManager: USB; Loading libraries/adb/src/server/client.ts +20 −136 Original line number Diff line number Diff line Loading @@ -15,16 +15,27 @@ import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "../adb.js"; import { AdbBanner } from "../banner.js"; import type { DeviceObserver as DeviceObserverBase } from "../device-observer.js"; import type { AdbFeature } from "../features.js"; import { hexToNumber, sequenceEqual } from "../utils/index.js"; import { hexToNumber } from "../utils/index.js"; import { MDnsCommands, WirelessCommands, AlreadyConnectedError as _AlreadyConnectedError, NetworkError as _NetworkError, UnauthorizedError as _UnauthorizedError, } from "./commands/index.js"; import { AdbServerDeviceObserverOwner } from "./observer.js"; import { AdbServerStream, FAIL } from "./stream.js"; import { AdbServerStream } from "./stream.js"; import { AdbServerTransport } from "./transport.js"; /** * Client for the ADB Server. */ export class AdbServerClient { static NetworkError = _NetworkError; static UnauthorizedError = _UnauthorizedError; static AlreadyConnectedError = _AlreadyConnectedError; static parseDeviceList(value: string): AdbServerClient.Device[] { const devices: AdbServerClient.Device[] = []; for (const line of value.split("\n")) { Loading Loading @@ -99,8 +110,8 @@ export class AdbServerClient { readonly connector: AdbServerClient.ServerConnector; readonly wireless = new AdbServerClient.WirelessCommands(this); readonly mDns = new AdbServerClient.MDnsCommands(this); readonly wireless = new WirelessCommands(this); readonly mDns = new MDnsCommands(this); #observerOwner = new AdbServerDeviceObserverOwner(this); constructor(connector: AdbServerClient.ServerConnector) { Loading Loading @@ -537,138 +548,11 @@ export namespace AdbServerClient { transportId: bigint; } export class NetworkError extends Error { constructor(message: string) { super(message); this.name = "NetworkError"; } } export class UnauthorizedError extends Error { constructor(message: string) { super(message); this.name = "UnauthorizedError"; } } export class AlreadyConnectedError extends Error { constructor(message: string) { super(message); this.name = "AlreadyConnectedError"; } } export class WirelessCommands { #client: AdbServerClient; constructor(client: AdbServerClient) { this.#client = client; } /** * `adb pair <password> <address>` */ async pair(address: string, password: string): Promise<void> { const connection = await this.#client.createConnection( `host:pair:${password}:${address}`, ); try { const response = await connection.readExactly(4); // `response` is either `FAIL`, or 4 hex digits for length of the string if (sequenceEqual(response, FAIL)) { throw new Error(await connection.readString()); } const length = hexToNumber(response); // Ignore the string as it's always `Successful ...` await connection.readExactly(length); } finally { await connection.dispose(); } } /** * `adb connect <address>` */ async connect(address: string): Promise<void> { const connection = await this.#client.createConnection( `host:connect:${address}`, ); try { const response = await connection.readString(); switch (response) { case `already connected to ${address}`: throw new AdbServerClient.AlreadyConnectedError( response, ); case `failed to connect to ${address}`: // `adb pair` mode not authorized case `failed to authenticate to ${address}`: // `adb tcpip` mode not authorized throw new AdbServerClient.UnauthorizedError(response); case `connected to ${address}`: return; default: throw new AdbServerClient.NetworkError(response); } } finally { await connection.dispose(); } } /** * `adb disconnect <address>` */ async disconnect(address: string): Promise<void> { const connection = await this.#client.createConnection( `host:disconnect:${address}`, ); try { await connection.readString(); } finally { await connection.dispose(); } } } export class MDnsCommands { #client: AdbServerClient; constructor(client: AdbServerClient) { this.#client = client; } async check() { const connection = await this.#client.createConnection("host:mdns:check"); try { const response = await connection.readString(); return !response.startsWith("ERROR:"); } finally { await connection.dispose(); } } async getServices() { const connection = await this.#client.createConnection("host:mdns:services"); try { const response = await connection.readString(); return response .split("\n") .filter(Boolean) .map((line) => { const parts = line.split("\t"); return { name: parts[0]!, service: parts[1]!, address: parts[2]!, }; }); } finally { await connection.dispose(); } } } export interface DeviceObserver extends DeviceObserverBase<Device> { onError: Event<Error>; } export type NetworkError = _NetworkError; export type UnauthorizedError = _UnauthorizedError; export type AlreadyConnectedError = _AlreadyConnectedError; } libraries/adb/src/server/commands/index.ts 0 → 100644 +2 −0 Original line number Diff line number Diff line export * from "./m-dns.js"; export * from "./wireless.js"; Loading
libraries/adb-daemon-webusb/src/device.ts +4 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import { import type { ExactReadable } from "@yume-chan/struct"; import { EmptyUint8Array } from "@yume-chan/struct"; import { DeviceBusyError as _DeviceBusyError } from "./error.js"; import type { UsbInterfaceFilter, UsbInterfaceIdentifier } from "./utils.js"; import { findUsbEndpoints, getSerialNumber, isErrorName } from "./utils.js"; Loading Loading @@ -254,6 +255,8 @@ export class AdbDaemonWebUsbConnection } export class AdbDaemonWebUsbDevice implements AdbDaemonDevice { static DeviceBusyError = _DeviceBusyError; #interface: UsbInterfaceIdentifier; #usbManager: USB; Loading Loading @@ -348,11 +351,5 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice { } export namespace AdbDaemonWebUsbDevice { export class DeviceBusyError extends Error { constructor(cause?: Error) { super("The device is already in used by another program", { cause, }); } } export type DeviceBusyError = _DeviceBusyError; }
libraries/adb-daemon-webusb/src/error.ts 0 → 100644 +7 −0 Original line number Diff line number Diff line export class DeviceBusyError extends Error { constructor(cause?: Error) { super("The device is already in used by another program", { cause, }); } }
libraries/adb-daemon-webusb/src/manager.ts +3 −3 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ export class AdbDaemonWebUsbDeviceManager { * * May be `undefined` if current runtime does not support WebUSB. */ static readonly BROWSER = typeof globalThis.navigator !== "undefined" && !!globalThis.navigator.usb static readonly BROWSER = /* #__PURE__ */ (() => { typeof globalThis.navigator !== "undefined" && globalThis.navigator.usb ? new AdbDaemonWebUsbDeviceManager(globalThis.navigator.usb) : undefined; })(); #usbManager: USB; Loading
libraries/adb/src/server/client.ts +20 −136 Original line number Diff line number Diff line Loading @@ -15,16 +15,27 @@ import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "../adb.js"; import { AdbBanner } from "../banner.js"; import type { DeviceObserver as DeviceObserverBase } from "../device-observer.js"; import type { AdbFeature } from "../features.js"; import { hexToNumber, sequenceEqual } from "../utils/index.js"; import { hexToNumber } from "../utils/index.js"; import { MDnsCommands, WirelessCommands, AlreadyConnectedError as _AlreadyConnectedError, NetworkError as _NetworkError, UnauthorizedError as _UnauthorizedError, } from "./commands/index.js"; import { AdbServerDeviceObserverOwner } from "./observer.js"; import { AdbServerStream, FAIL } from "./stream.js"; import { AdbServerStream } from "./stream.js"; import { AdbServerTransport } from "./transport.js"; /** * Client for the ADB Server. */ export class AdbServerClient { static NetworkError = _NetworkError; static UnauthorizedError = _UnauthorizedError; static AlreadyConnectedError = _AlreadyConnectedError; static parseDeviceList(value: string): AdbServerClient.Device[] { const devices: AdbServerClient.Device[] = []; for (const line of value.split("\n")) { Loading Loading @@ -99,8 +110,8 @@ export class AdbServerClient { readonly connector: AdbServerClient.ServerConnector; readonly wireless = new AdbServerClient.WirelessCommands(this); readonly mDns = new AdbServerClient.MDnsCommands(this); readonly wireless = new WirelessCommands(this); readonly mDns = new MDnsCommands(this); #observerOwner = new AdbServerDeviceObserverOwner(this); constructor(connector: AdbServerClient.ServerConnector) { Loading Loading @@ -537,138 +548,11 @@ export namespace AdbServerClient { transportId: bigint; } export class NetworkError extends Error { constructor(message: string) { super(message); this.name = "NetworkError"; } } export class UnauthorizedError extends Error { constructor(message: string) { super(message); this.name = "UnauthorizedError"; } } export class AlreadyConnectedError extends Error { constructor(message: string) { super(message); this.name = "AlreadyConnectedError"; } } export class WirelessCommands { #client: AdbServerClient; constructor(client: AdbServerClient) { this.#client = client; } /** * `adb pair <password> <address>` */ async pair(address: string, password: string): Promise<void> { const connection = await this.#client.createConnection( `host:pair:${password}:${address}`, ); try { const response = await connection.readExactly(4); // `response` is either `FAIL`, or 4 hex digits for length of the string if (sequenceEqual(response, FAIL)) { throw new Error(await connection.readString()); } const length = hexToNumber(response); // Ignore the string as it's always `Successful ...` await connection.readExactly(length); } finally { await connection.dispose(); } } /** * `adb connect <address>` */ async connect(address: string): Promise<void> { const connection = await this.#client.createConnection( `host:connect:${address}`, ); try { const response = await connection.readString(); switch (response) { case `already connected to ${address}`: throw new AdbServerClient.AlreadyConnectedError( response, ); case `failed to connect to ${address}`: // `adb pair` mode not authorized case `failed to authenticate to ${address}`: // `adb tcpip` mode not authorized throw new AdbServerClient.UnauthorizedError(response); case `connected to ${address}`: return; default: throw new AdbServerClient.NetworkError(response); } } finally { await connection.dispose(); } } /** * `adb disconnect <address>` */ async disconnect(address: string): Promise<void> { const connection = await this.#client.createConnection( `host:disconnect:${address}`, ); try { await connection.readString(); } finally { await connection.dispose(); } } } export class MDnsCommands { #client: AdbServerClient; constructor(client: AdbServerClient) { this.#client = client; } async check() { const connection = await this.#client.createConnection("host:mdns:check"); try { const response = await connection.readString(); return !response.startsWith("ERROR:"); } finally { await connection.dispose(); } } async getServices() { const connection = await this.#client.createConnection("host:mdns:services"); try { const response = await connection.readString(); return response .split("\n") .filter(Boolean) .map((line) => { const parts = line.split("\t"); return { name: parts[0]!, service: parts[1]!, address: parts[2]!, }; }); } finally { await connection.dispose(); } } } export interface DeviceObserver extends DeviceObserverBase<Device> { onError: Event<Error>; } export type NetworkError = _NetworkError; export type UnauthorizedError = _UnauthorizedError; export type AlreadyConnectedError = _AlreadyConnectedError; }
libraries/adb/src/server/commands/index.ts 0 → 100644 +2 −0 Original line number Diff line number Diff line export * from "./m-dns.js"; export * from "./wireless.js";