#!/usr/bin/env bash # Start the Taler Android AVD. **Default = headless** (no host window). # Guest GLES still runs via SwiftShader so uiautomator / screenshots work. # # Usage: # ./start-android-emulator.sh # headless, background # ./start-android-emulator.sh --wait # headless + wait for boot # ./start-android-emulator.sh --windowed # show emulator window # EMULATOR_HEADLESS=0 ./start-android-emulator.sh # EMULATOR_GPU=host WINDOWED=1 ./start-android-emulator.sh # # Env: EMULATOR_AVD EMULATOR_MEMORY EMULATOR_CORES EMULATOR_GPU # EMULATOR_HEADLESS EMULATOR_LOG EMULATOR_BOOT_TIMEOUT EMULATOR_EXTRA_ARGS # set -euo pipefail ROOT=$(cd "$(dirname "$0")" && pwd) # shellcheck source=lib_android_env.sh . "$ROOT/lib_android_env.sh" WAIT=0 for a in "$@"; do case "$a" in --wait) WAIT=1 ;; --windowed| --gui) EMULATOR_HEADLESS=0; export EMULATOR_HEADLESS ;; --headless) EMULATOR_HEADLESS=1; export EMULATOR_HEADLESS ;; -h|--help) sed -n '2,18p' "$0" exit 0 ;; esac done command -v emulator >/dev/null || { echo "emulator not found (ANDROID_HOME=$ANDROID_HOME)" >&2 exit 2 } command -v adb >/dev/null || { echo "adb not found" >&2 exit 2 } # Already booted? if serial=$(android_adb_serial); [ -n "$serial" ]; then boot=$(adb -s "$serial" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true) if [ "$boot" = "1" ]; then echo "already running: $serial (boot_completed=1) — headless default still applies to *new* starts" exit 0 fi fi # Avoid pkill patterns that match this wrapper's argv (self-kill). mapfile -t EMU_ARGS < <(android_emulator_args "$EMULATOR_AVD") echo "starting: emulator ${EMU_ARGS[*]}" echo " headless=$EMULATOR_HEADLESS gpu=$EMULATOR_GPU log=$EMULATOR_LOG" if [ "${EMULATOR_HEADLESS}" = "1" ]; then export QT_QPA_PLATFORM="${QT_QPA_PLATFORM:-offscreen}" # Do not require DISPLAY unset DISPLAY || true fi mkdir -p "$(dirname "$EMULATOR_LOG")" # Background; do not use pkill -f emulator from callers matching full cmdline nohup emulator "${EMU_ARGS[@]}" >"$EMULATOR_LOG" 2>&1 & echo "emulator pid=$! log=$EMULATOR_LOG" if [ "$WAIT" != "1" ]; then echo "not waiting (pass --wait for boot). adb devices when ready." exit 0 fi echo "waiting for boot (timeout ${EMULATOR_BOOT_TIMEOUT}s)…" deadline=$((SECONDS + EMULATOR_BOOT_TIMEOUT)) serial="" while (( SECONDS < deadline )); do adb wait-for-device 2>/dev/null || true serial=$(android_adb_serial || true) if [ -n "$serial" ]; then boot=$(adb -s "$serial" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true) if [ "$boot" = "1" ]; then echo "BOOT_OK serial=$serial headless=$EMULATOR_HEADLESS gpu=$EMULATOR_GPU" exit 0 fi fi sleep 2 done echo "boot timeout — last log:" >&2 tail -30 "$EMULATOR_LOG" >&2 || true exit 3