/** * GoogleEmulatorProvider — lifecycle for Google's Android Emulator (the AVD stack). * * Adopt-or-launch, the managed-Chrome lesson applied to qemu: * * - ADOPT a running emulator of the requested AVD before launching one: a boot costs * 15s+ and a second instance of the same AVD refuses the lock. * - The launched emulator is DETACHED and outlives us (`unref`, stdio ignored): the * device is a background appliance, not a child of one CLI invocation. * - The spawn 'error' handler is mandatory: an unhandled 'error' event is an uncaught * exception, and the boot poll must stop immediately on a child that never started. * - Headless means `-no-window -gpu host`. The gpu flag is not cosmetic: mirasim's * simulator measured software rasterisation at 684% idle CPU vs 33% with `-gpu host`. * - Boot = a NEW serial appears in `adb devices` AND `sys.boot_completed` is 1. The * new serial is matched back to the requested AVD by `ro.boot.qemu.avd_name`, so two * concurrent boots cannot cross wires. */ import { type ExecFn } from "../adb.ts"; import type { EmulatorProvider, EmulatorStartOptions, RunningEmulator } from "./provider.ts"; /** Spawn seam for tests: same shape as node's spawn, detachment handled by the caller. */ export type SpawnFn = (file: string, args: string[]) => { unref(): void; once(event: "exit" | "error", fn: (arg?: unknown) => void): unknown; }; export interface GoogleEmulatorProviderOptions { exec?: ExecFn; spawn?: SpawnFn; adbPath?: string; emulatorPath?: string; } export declare class GoogleEmulatorProvider implements EmulatorProvider { readonly id = "google"; private readonly exec; private readonly spawnFn; private adbPath; private emulatorPath; constructor(opts?: GoogleEmulatorProviderOptions); private adb; private emulator; listAvds(): Promise; listRunning(): Promise; private avdName; start(opts: EmulatorStartOptions): Promise; stop(serial: string): Promise; saveSnapshot(serial: string, name: string): Promise; loadSnapshot(serial: string, name: string): Promise; private emuSnapshot; }