/** * Identify the Android processes holding a given TCP port LISTEN socket. * * Used at deploy time to detect the orphan-app scenario: a previously- * launched app is still bound to its debugging/RPC port (e.g. Bevy BRP * 15702, React Native Metro 8081, Flutter DDS), so the freshly-deployed * app silently fails to rebind and clients end up talking to (and * waiting on) the previous instance. */ export interface PortListener { uid: number; inode: number; } /** * Parse one or more concatenated `/proc/net/tcp` / `/proc/net/tcp6` dumps * and return all LISTEN sockets (state code `0A`) bound to `port`. * * IPv4 and IPv6 lines look like: * sl local_address rem_address st ... uid timeout inode ... * * - `local_address` is `:` (port hex is 4 chars in tcp4 * and tcp6; address width differs but we only care about the port). * - `st` is the connection state; `0A` is LISTEN. */ export declare function parsePortListenersFromProcNet(procNet: string, port: number): PortListener[]; /** * Parse the output of `adb shell pm list packages -U` into a uid → package * map. Lines look like `package:net.monoloco.keyboarddemo uid:10186`. */ export declare function parsePmListPackagesU(output: string): Map; /** * A function that runs `adb [args...]` on the connected device and returns * stdout. Indirected through this interface so the port-owner logic can be * unit-tested without spawning real adb processes. */ export type AdbCommandRunner = (args: string[]) => Promise; export interface PortOwner extends PortListener { /** Package name owning the uid, or null if the snapshot didn't capture it. */ packageName: string | null; } /** * Identify every Android package currently holding a LISTEN socket on * `port`. Reads both `/proc/net/tcp` and `/proc/net/tcp6` (LISTEN sockets * appear in whichever family the app bound) and joins against * `pm list packages -U`. */ export declare function findPortOwners(port: number, adb: AdbCommandRunner): Promise; export interface PortConflictReport { /** Owners we force-stopped. */ stopped: Array<{ packageName: string; uid: number; }>; /** Owners we couldn't act on (no known package for the uid). */ skipped: Array<{ uid: number; packageName: string | null; }>; } /** * If any process other than `targetPackage` is holding `port`, force-stop * it so the deploy target can bind cleanly. The deploy target itself is * left alone because the existing install step will re-launch it. */ export declare function resolvePortConflicts(options: { port: number; targetPackage: string; adb: AdbCommandRunner; }): Promise; //# sourceMappingURL=port-owners.d.ts.map