diff --git a/.vscode/settings.json b/.vscode/settings.json index 25d94e28..511bc772 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "ADB's", "adbd", + "addrs", "allowlist", "arraybuffer", "autorun", diff --git a/README.md b/README.md index ae6776a3..a8824be1 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ In this mode, this library talks to a Google ADB server, which is either running ## Compatibility -| Connection | Chromium-based Browsers | Firefox | Node.js | -| ----------------------------------------- | ------------------------------ | --------- | ----------------------------- | -| USB cable | Supported using [WebUSB] API | No | Supported using `usb` package | -| Wireless through [WebSocket] 1 | Supported | Supported | Possible using `ws` package | +| Connection | Chromium-based Browsers | Firefox | Node.js | +| ----------------------------------------- | -------------------------------- | --------- | ----------------------------- | +| USB cable | Supported using [WebUSB] API | No | Supported using `usb` package | +| Wireless through [WebSocket] 1 | Supported | Supported | Possible using `ws` package | | Wireless through TCP | Waiting for [Direct Sockets] API | No | Possible using `net` module | [webusb]: https://wicg.github.io/webusb/ diff --git a/apps/demo/src/pages/tcpip.tsx b/apps/demo/src/pages/tcpip.tsx index 48e46258..927c2666 100644 --- a/apps/demo/src/pages/tcpip.tsx +++ b/apps/demo/src/pages/tcpip.tsx @@ -77,30 +77,19 @@ class TcpIpState { return; } - const serviceListenAddresses = await GLOBAL_STATE.adb.getProp( - "service.adb.listen_addrs" - ); - const servicePort = await GLOBAL_STATE.adb.getProp( - "service.adb.tcp.port" - ); - const persistPort = await GLOBAL_STATE.adb.getProp( - "persist.adb.tcp.port" - ); + const { serviceListenAddresses, servicePort, persistPort } = + await GLOBAL_STATE.adb.tcpip.getListenAddresses(); if (signal.aborted) { return; } runInAction(() => { - this.serviceListenAddresses = - serviceListenAddresses !== "" - ? serviceListenAddresses.split(",") - : undefined; + this.serviceListenAddresses = serviceListenAddresses; if (servicePort) { - this.servicePortEnabled = - !serviceListenAddresses && servicePort !== "0"; - this.servicePort = servicePort; + this.servicePortEnabled = !serviceListenAddresses; + this.servicePort = servicePort.toString(); } else { this.servicePortEnabled = false; this.servicePort = "5555"; @@ -109,7 +98,7 @@ class TcpIpState { if (persistPort) { this.persistPortEnabled = !serviceListenAddresses && !servicePort; - this.persistPort = persistPort; + this.persistPort = persistPort.toString(); } else { this.persistPortEnabled = false; this.persistPort = undefined; @@ -124,7 +113,7 @@ class TcpIpState { if (state.servicePortEnabled) { await GLOBAL_STATE.adb.tcpip.setPort( - Number.parseInt(state.servicePort, 10) + Number.parseInt(state.servicePort, 10), ); } else { await GLOBAL_STATE.adb.tcpip.disable(); @@ -153,7 +142,7 @@ const TcpIp: NextPage = () => { state.servicePortEnabled = !!value; }); }, - [] + [], ); const handleServicePortChange = useCallback( @@ -163,7 +152,7 @@ const TcpIp: NextPage = () => { } runInAction(() => (state.servicePort = value)); }, - [] + [], ); return ( diff --git a/common/changes/@yume-chan/adb/main_2023-08-25-16-30.json b/common/changes/@yume-chan/adb/main_2023-08-25-16-30.json new file mode 100644 index 00000000..92086ee0 --- /dev/null +++ b/common/changes/@yume-chan/adb/main_2023-08-25-16-30.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@yume-chan/adb", + "comment": "Add `getListenAddresses` method to `AdbTcpIpCommand` class for retrieving current ADB over WiFi state", + "type": "none" + } + ], + "packageName": "@yume-chan/adb" +} \ No newline at end of file diff --git a/libraries/adb/src/commands/tcpip.ts b/libraries/adb/src/commands/tcpip.ts index e91def10..387480bb 100644 --- a/libraries/adb/src/commands/tcpip.ts +++ b/libraries/adb/src/commands/tcpip.ts @@ -1,6 +1,47 @@ import { AdbCommandBase } from "./base.js"; +/** + * ADB daemon checks for the following properties in the order of + * + * * `serviceListenAddresses` (`service.adb.listen_addrs`) + * * `servicePort` (`service.adb.tcp.port`) + * * `persistPort` (`persist.adb.tcp.port`) + * + * Once it finds a non-empty value, it will use it and ignore the rest. + * + * `serviceListenAddresses` and `persistPort` are fixed at build time, + * only `servicePort` can be changed using `setPort` and `disable`. + * This means if either `serviceListenAddresses` or `persistPort` is non-empty, + * ADB over WiFi is always enabled. + */ +export interface AdbTcpIpListenAddresses { + serviceListenAddresses: string[]; + servicePort: number | undefined; + persistPort: number | undefined; +} + export class AdbTcpIpCommand extends AdbCommandBase { + #parsePort(value: string): number | undefined { + if (!value || value === "0") { + return undefined; + } + return Number.parseInt(value, 10); + } + + async getListenAddresses(): Promise { + const serviceListenAddresses = await this.adb.getProp( + "service.adb.listen_addrs", + ); + const servicePort = await this.adb.getProp("service.adb.tcp.port"); + const persistPort = await this.adb.getProp("persist.adb.tcp.port"); + + return { + serviceListenAddresses: serviceListenAddresses.split(","), + servicePort: this.#parsePort(servicePort), + persistPort: this.#parsePort(persistPort), + }; + } + async setPort(port: number): Promise { if (port <= 0) { throw new Error(`Invalid port ${port}`);