Skip to content

Fix emulator boot reliability: AVD detection order, offline skip, early exit#311

Closed
rmarinho wants to merge 1 commit intofeature/emulator-runnerfrom
dev/emulator-boot-fixes
Closed

Fix emulator boot reliability: AVD detection order, offline skip, early exit#311
rmarinho wants to merge 1 commit intofeature/emulator-runnerfrom
dev/emulator-boot-fixes

Conversation

@rmarinho
Copy link
Member

Summary

Three fixes for emulator boot reliability issues discovered while investigating dotnet/android#10965.

Related PR: dotnet/android#10969

Fixes

1. Swap AVD name detection order (AdbRunner.GetEmulatorAvdNameAsync)

adb -s <serial> emu avd name returns empty output on modern Android emulators (tested with emulator 36.4.10, adb v36). This causes AVD name matching to fail even when the correct emulator is running.

Fix: Use adb shell getprop ro.boot.qemu.avd_name first (reliable on all modern emulators, always set by the emulator kernel), fall back to emu avd name for older emulator versions.

2. Skip AVD name queries for offline emulators (AdbRunner.ListDevicesAsync)

ListDevicesAsync called GetEmulatorAvdNameAsync for ALL emulators including offline ones. Neither getprop nor emu avd name works on offline devices — they fail or timeout. During BootEmulatorAsync's polling loop, this causes unnecessary delays on every iteration as the emulator transitions from offline → online.

Fix: Only query AVD names for online emulators (Status == AdbDeviceStatus.Online).

3. Early process exit detection (EmulatorRunner.BootEmulatorAsync)

The boot polling loop had no check for emulatorProcess.HasExited. If the emulator fails immediately (e.g., insufficient disk space, missing AVD, bad config), the full 300s timeout is wasted before reporting failure.

On macOS, the emulator binary forks the real QEMU process and the parent exits with code 0 immediately. The previous code would have also failed here since any process exit would trigger timeout.

Fix: Check HasExited during polling. Non-zero exit codes fail fast with LaunchFailed. Exit code 0 (macOS fork) continues polling — the real emulator is running as a separate process.

Testing

…ly exit

Three fixes for emulator boot issues discovered while fixing dotnet/android#10965:

1. Swap AVD name detection order in GetEmulatorAvdNameAsync: use
   'getprop ro.boot.qemu.avd_name' first (reliable on modern emulators),
   fall back to 'emu avd name' (returns empty on emulator 36.4.10+).

2. Skip AVD name queries for offline emulators in ListDevicesAsync:
   neither getprop nor 'emu avd name' works on offline devices, causing
   unnecessary delays during the boot polling loop.

3. Add early process exit detection in BootEmulatorAsync: detect non-zero
   exit codes immediately instead of waiting for the full timeout. Handle
   macOS fork behavior where the emulator parent exits with code 0 while
   the real QEMU process continues running.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho
Copy link
Member Author

Splitting into two separate PRs: one targeting main (AdbRunner fixes) and one targeting feature/emulator-runner (EmulatorRunner fix).

@rmarinho rmarinho closed this Mar 18, 2026
@rmarinho rmarinho deleted the dev/emulator-boot-fixes branch March 18, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant