Files
Europa/Nuvolari/tool/start_emulator.ps1
Alby96andClaude Opus 5 75c4c55f81 Add VS Code run-and-debug configurations for the Android emulator
F5 now builds, installs and attaches the debugger on the emulator, with the
emulator booted automatically first, so there is no manual setup step between
opening the project and stepping through code.

tool/start_emulator.ps1 backs the preLaunchTask and is idempotent: it returns in
about three seconds when a device is already attached, so re-launching the
debugger cannot stack emulator instances. It fails with a useful message when
the AVD is missing rather than hanging until a timeout.

Five configurations rather than one, because they answer different questions.
The profile-mode entry matters most for what comes next: debug builds run the
Dart VM unoptimised, so the radar animation always looks worse than it is, and
milestone 3's acceptance criterion is about whether it runs smoothly. The
Windows entry trades the map away for a launch that takes seconds, which is
worth it for pure UI work.

Verified on this machine: the script cold-boots the AVD and waits for
sys.boot_completed, and a second run exits immediately.

Also removes the broken pixel_7_-_api_35 AVD, which could not boot because its
system image was never installed. That returned 4.8 GB, taking free disk from
3.5 GB to 10.7 GB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 12:36:36 +02:00

86 lines
2.8 KiB
PowerShell

<#
.SYNOPSIS
Boots the Nuvolari Android emulator, unless one is already running.
.DESCRIPTION
Used as the preLaunchTask for the VS Code debug configurations, so pressing
F5 works from a cold machine without a separate manual step.
Idempotent on purpose: if a device is already attached the script returns
immediately, so re-launching the debugger does not stack emulator instances.
.PARAMETER Avd
Name of the AVD to boot. Defaults to the one this project sets up.
.PARAMETER TimeoutSeconds
How long to wait for the boot to complete. Quickboot snapshots are disabled
on this AVD to save disk, so a cold boot takes a minute or two.
.EXAMPLE
.\tool\start_emulator.ps1
#>
[CmdletBinding()]
param(
[string]$Avd = 'nuvolari',
[int]$TimeoutSeconds = 300
)
$ErrorActionPreference = 'Stop'
$sdk = if ($env:ANDROID_HOME) { $env:ANDROID_HOME }
elseif ($env:ANDROID_SDK_ROOT) { $env:ANDROID_SDK_ROOT }
else { 'C:\Android\Sdk' }
$adb = Join-Path $sdk 'platform-tools\adb.exe'
$emulator = Join-Path $sdk 'emulator\emulator.exe'
foreach ($tool in @($adb, $emulator)) {
if (-not (Test-Path $tool)) {
throw "Not found: $tool. Set ANDROID_HOME or install the Android SDK."
}
}
function Get-AttachedDevice {
# `adb devices` prints a header line, then "<id>\tdevice" for each ready
# device. Anything in another state (offline, unauthorized) does not count.
$lines = & $adb devices 2>$null | Select-Object -Skip 1
foreach ($line in $lines) {
if ($line -match '^(\S+)\s+device$') { return $Matches[1] }
}
return $null
}
$existing = Get-AttachedDevice
if ($existing) {
Write-Host "Device already attached: $existing" -ForegroundColor Green
exit 0
}
$available = & $emulator -list-avds 2>$null
if ($available -notcontains $Avd) {
throw "AVD '$Avd' does not exist. Available: $($available -join ', '). See docs/roadmap.md for how it was created."
}
Write-Host "Booting emulator '$Avd' (cold boot, snapshots are disabled)..." -ForegroundColor Cyan
# Detached, with its own window, so the debug session does not own its lifetime
# and stopping the debugger leaves the emulator up for the next run.
Start-Process -FilePath $emulator `
-ArgumentList @('-avd', $Avd, '-no-audio', '-no-boot-anim', '-gpu', 'host') `
-WindowStyle Minimized | Out-Null
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ((Get-Date) -lt $deadline) {
$device = Get-AttachedDevice
if ($device) {
$booted = (& $adb -s $device shell getprop sys.boot_completed 2>$null) -replace '\s', ''
if ($booted -eq '1') {
Write-Host "Emulator ready: $device" -ForegroundColor Green
exit 0
}
}
Start-Sleep -Seconds 3
}
throw "Emulator '$Avd' did not finish booting within $TimeoutSeconds seconds."