/** * Android tap-event capture via `adb shell getevent -l`. * * We stream input events from the connected emulator/device while a screen * recording is in progress, parse touch events into (x, y, t) tuples, and * write them as a sidecar JSON. A separate post-process step (overlay.ts) * renders rings on the recording at each tap timestamp. * * `getevent -p` is used once at startup to discover the touchscreen input * device and its ABS coordinate range — coordinates from `getevent` are in * raw input-device units, which we scale to screen pixels using the ratio * of `wm size` vs. the input device's max X/Y. */ import { type ChildProcess } from 'child_process'; export interface TapEvent { /** Pixel x relative to the captured frame. */ x: number; /** Pixel y relative to the captured frame. */ y: number; /** Seconds since recording start. */ t: number; } export interface TouchDeviceInfo { /** /dev/input/eventN path. */ path: string; /** Max raw value for ABS_MT_POSITION_X (0..max). */ maxX: number; /** Max raw value for ABS_MT_POSITION_Y (0..max). */ maxY: number; /** Display width in pixels (from `wm size`). */ screenWidth: number; /** Display height in pixels. */ screenHeight: number; } /** * Parse `adb shell wm size` output: * Physical size: 1080x2400 * Override size: 720x1600 (optional) * * Override takes precedence when present (it's what apps actually render at). */ export declare function parseWmSize(out: string): { width: number; height: number; } | null; /** * Parse `adb shell getevent -p` output and find the first device that * declares BTN_TOUCH (014a) and ABS_MT_POSITION_X/Y. Returns the device * path plus the raw coordinate ranges. * * Layout (one block per device): * * add device 3: /dev/input/event3 * name: "Touchscreen" * events: * KEY (0001): 014a * ABS (0003): 0030 0031 0035 0036 ... * input props: * ... * ABS_MT_POSITION_X : value 0, min 0, max 1080, fuzz 0, flat 0, resolution 0 * ABS_MT_POSITION_Y : value 0, min 0, max 2400, fuzz 0, flat 0, resolution 0 */ export declare function parseGetEventProbe(out: string): Array<{ path: string; maxX: number; maxY: number; hasBtnTouch: boolean; }>; /** * Run the necessary adb queries to discover the touchscreen device + scale. * Throws when no touchscreen device is found. */ export declare function findTouchDevice(deviceSerial: string): Promise; /** * Parse one chunk of `getevent -l` output, updating accumulated state in * place. Pure function so it's straightforward to unit-test. * * Lines look like: * /dev/input/event3: EV_ABS ABS_MT_POSITION_X 000003e8 * /dev/input/event3: EV_KEY BTN_TOUCH DOWN * /dev/input/event3: EV_KEY BTN_TOUCH UP */ export interface ParseState { curX: number | null; curY: number | null; downAtMs: number | null; } export declare function freshParseState(): ParseState; export declare function processGetEventChunk(text: string, state: ParseState, scaleX: number, scaleY: number, startMs: number, nowMs: number, bounds?: { maxX: number; maxY: number; screenWidth: number; screenHeight: number; }): TapEvent[]; /** * Spawn a `getevent -l` listener for the given input path. Returns the * child process plus a live array of tap events that the caller can read * after they await `done` (or kill the process and await close). * * `done` resolves once the proc 'close' event fires AND the trailing * buffered partial line has been processed — without it, taps in the final * milliseconds before SIGTERM are silently dropped. */ export declare function captureTapsLive(deviceSerial: string, info: TouchDeviceInfo, startMs: number): { proc: ChildProcess; taps: TapEvent[]; done: Promise; }; //# sourceMappingURL=androidTaps.d.ts.map