fix(open): boot a stopped Android AVD named by --device before claiming it
Summary
open <app> --platform android --device <AVD> on a stopped AVD failed with DEVICE_NOT_FOUND, on main too. The maintainer's #4359 live runs found it. There were two causes:
openresolved devices running-only.- After a boot,
openkept the AVD name as the device id.
The fix:
openadmits stopped AVDs (androidAvdSelection: 'include-stopped') only when--devicenames a device. An unnamed open stays running-only, so a running phone still wins over a stopped AVD.- One owner,
resolveOpenTargetDeviceOptions, feeds all four open resolution sites. - Install's boot-then-rebind step is now shared as
bootStoppedLocalAndroidDevice.openruns it before the session claim and locks, so the session, claim and locks use theemulator-NNNNserial. - When
openorinstallboots a stopped AVD, readiness receives the request's Android serial allowlist but not--serial: the resolved AVD is the boot target. - One daemon owner,
core/device-readiness-input.ts, builds the sorted Android serial allowlist and the readiness input for boot, appstate, apps, doctor, the inventory request and the stopped-AVD boot. The per-file copies are deleted. - Behavior change, intended per maintainer review:
installof a stopped AVD now honors the Android serial allowlist. Before, it booted the AVD regardless. An emulator that comes up outside the allowlist ends inboot_timeout, asbootdoes. - One
--timeoutstartup deadline covers both the boot and open preparation. The supersededreadyDeployAppUseis removed.
23 files. This is not an audit item; it is tracked alongside #4368.
Validation
- Tested SHA
650c9bb. - Tests that fail without the fix:
- Router: the
openstopped-AVD selection case, the cold-AVD boot test, and unnamed open with a running phone plus a stopped AVD (selects the phone, noensureReady). - Claims: rollback of the booted-serial claim; an allowlist that excludes the booted serial (no claim); and
--serialnaming another device (the resolved AVD still boots). - Router: open of a stopped AVD under an allowlist sends inventory both
include-stoppedand the allowlist, and boots within it. The real Android inventory keeping a stopped AVD under an allowlist is covered byplatform-android/src/inventory.test.ts:25-66.
- Router: the
check:quickandcheck:fallow --base origin/mainpass.check:affected --run --head 650c9bb(exactCommit): format, lint, typecheck, layering, fallow and build pass.vitest-relatedfails only on 2apple-runnerchmod tests that fail when run as root (known baseline BASE-1). It selects them because a contracts comment changed, and that stops the gate beforeunit.check:unitrun directly at 650c9bb: all 17,968 vitest tests pass. The only failures are the 2 knownsmoke-daemon-cleantests, which fail because the container's PID 1 does not reap zombies.- Required live run, by the maintainer (not yet done). Use a cold AVD other than Pixel_7_CI:
- Confirm
adb devicesdoes not list the AVD. - Run
agent-device open com.android.settings --platform android --device <AVD> --json. Expect a boot, then Settings, with session device idemulator-NNNN. - Run
snapshot -i --json. ExpectandroidSnapshot.backend: android-helper. - Run
close --shutdown. - With a phone or a running emulator attached and a stopped AVD present, run
open com.android.settings --platform androidwithout--device. Expect the running device to be selected and no emulator to boot. - On a cold AVD, run
install <apk> --device <AVD>.
- Confirm
- Risk: device-facing. CI lanes own native coverage.
Generated by Claude Code
<a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1796964165&installation_model_id=447842&pr_number=4396&ref=codesmith_pr_footer&repository=callstack%2Fagent-device&return_to=https%3A%2F%2Fgithub.com%2Fcallstack%2Fagent-device%2Fpull%2F4396&signature=fc976f331a9a83ebca992aa23117721280d702cf34abf546af40d8e70be11624"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png" width="190" height="28">
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
<a href="https://www.cubic.dev/action/auto-fix/pr/callstack/agent-device/4396?returnTo=https%3A%2F%2Fgithub.com%2Fcallstack%2Fagent-device%2Fpull%2F4396&source=description" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img alt="Turn on auto-fix" src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg">
Generated by Claude Code