#!/usr/bin/env bash # Start Android emulator in headless mode with logging set -euo pipefail export ANDROID_HOME="$HOME/Android/Sdk" export ANDROID_SDK_ROOT="$ANDROID_HOME" export PATH="$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools:$HOME/flutter/bin:$PATH" AVD_NAME="Pixel_7_API_35" EMU_LOG="/tmp/emulator.log" BOOT_LOG="/tmp/emulator-boot.log" # Kill any existing emulator if adb devices 2>/dev/null | grep -q "emulator"; then echo "[$(date)] Killing existing emulator..." | tee -a "$BOOT_LOG" adb emu kill 2>/dev/null || true sleep 2 fi # Kill any stale emulator processes pkill -f "qemu-system-x86_64" 2>/dev/null || true sleep 1 # Clear old logs > "$EMU_LOG" > "$BOOT_LOG" echo "[$(date)] Starting emulator: $AVD_NAME" | tee -a "$BOOT_LOG" echo "[$(date)] Emulator log: $EMU_LOG" | tee -a "$BOOT_LOG" echo "[$(date)] Boot log: $BOOT_LOG" | tee -a "$BOOT_LOG" # Start emulator in background with: # - KVM hardware acceleration (auto-detected) # - swiftshader for GPU (headless-compatible) # - no audio/window for CI/headless use # - no snapshot for clean boot nohup emulator -avd "$AVD_NAME" \ -no-audio \ -no-window \ -gpu swiftshader_indirect \ -no-snapshot-save \ -no-metrics \ -wipe-data \ > "$EMU_LOG" 2>&1 & EMU_PID=$! echo "[$(date)] Emulator PID: $EMU_PID" | tee -a "$BOOT_LOG" # Wait for boot to complete (timeout 120s) echo "[$(date)] Waiting for device to come online..." | tee -a "$BOOT_LOG" TIMEOUT=120 ELAPSED=0 # First wait for adb to see the device while ! adb devices 2>/dev/null | grep -q "emulator"; do if [ $ELAPSED -ge $TIMEOUT ]; then echo "[$(date)] TIMEOUT: Device never appeared in adb" | tee -a "$BOOT_LOG" echo "[$(date)] Last emulator log lines:" | tee -a "$BOOT_LOG" tail -20 "$EMU_LOG" | tee -a "$BOOT_LOG" exit 1 fi sleep 2 ELAPSED=$((ELAPSED + 2)) echo "[$(date)] Waiting for adb device... (${ELAPSED}s)" >> "$BOOT_LOG" done echo "[$(date)] Device visible in adb, waiting for boot completion..." | tee -a "$BOOT_LOG" # Now wait for boot_completed while [ "$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" != "1" ]; do if [ $ELAPSED -ge $TIMEOUT ]; then echo "[$(date)] TIMEOUT: Boot did not complete within ${TIMEOUT}s" | tee -a "$BOOT_LOG" echo "[$(date)] Boot animation state: $(adb shell getprop init.svc.bootanim 2>/dev/null)" | tee -a "$BOOT_LOG" echo "[$(date)] Last emulator log lines:" | tee -a "$BOOT_LOG" tail -20 "$EMU_LOG" | tee -a "$BOOT_LOG" exit 1 fi sleep 2 ELAPSED=$((ELAPSED + 2)) echo "[$(date)] Waiting for boot... (${ELAPSED}s)" >> "$BOOT_LOG" done echo "[$(date)] Emulator booted successfully in ${ELAPSED}s!" | tee -a "$BOOT_LOG" echo "[$(date)] Device: $(adb devices | grep emulator)" | tee -a "$BOOT_LOG" adb shell getprop ro.build.version.sdk 2>/dev/null | xargs -I{} echo "[$(date)] API level: {}" | tee -a "$BOOT_LOG"