#!/usr/bin/env bash # android_emulator_start — Arranca un AVD en background y espera a que bootee. # Uso: android_emulator_start [timeout_s] set -euo pipefail # --------------------------------------------------------------------------- # Source adb_wsl si está disponible (provee ADB, adb_run, adb_wait_boot) # --------------------------------------------------------------------------- _ADB_WSL_SH="$(dirname "${BASH_SOURCE[0]}")/adb_wsl.sh" if [[ -f "$_ADB_WSL_SH" ]]; then # shellcheck source=adb_wsl.sh source "$_ADB_WSL_SH" else # Fallback inline: resolver ADB if [[ -z "${ADB:-}" ]]; then _sdk_root="${ANDROID_SDK_WIN:-/mnt/c/Users/lucas/AppData/Local/Android/Sdk}" ADB="${_sdk_root}/platform-tools/adb.exe" unset _sdk_root fi adb_run() { "$ADB" "$@"; } adb_wait_boot() { local timeout_s="${1:-120}" local elapsed=0 interval=3 val while (( elapsed < timeout_s )); do val=$(adb_run shell getprop sys.boot_completed 2>/dev/null | tr -d '[:space:]') [[ "$val" == "1" ]] && return 0 sleep "$interval" (( elapsed += interval )) done echo "android_emulator_start: timeout ${timeout_s}s esperando boot." >&2 return 1 } fi # --------------------------------------------------------------------------- # Resolver EMULATOR # --------------------------------------------------------------------------- if [[ -z "${EMULATOR:-}" ]]; then _sdk_root="${ANDROID_SDK_WIN:-/mnt/c/Users/lucas/AppData/Local/Android/Sdk}" EMULATOR="${_sdk_root}/emulator/emulator.exe" unset _sdk_root fi # --------------------------------------------------------------------------- # android_emulator_start [timeout_s] # --------------------------------------------------------------------------- android_emulator_start() { local AVD="${1:?android_emulator_start requiere el nombre del AVD como primer argumento}" local timeout_s="${2:-180}" # Validaciones de entorno if [[ ! -f "$EMULATOR" ]]; then echo "android_emulator_start: emulator.exe no encontrado en '$EMULATOR'. Fija EMULATOR= o ANDROID_SDK_WIN=." >&2 return 1 fi if [[ ! -f "$ADB" ]]; then echo "android_emulator_start: adb.exe no encontrado en '$ADB'. Fija ADB= o ANDROID_SDK_WIN=." >&2 return 1 fi # Idempotencia: si ya hay un emulador corriendo, salir sin lanzar otro if adb_run devices 2>/dev/null | grep -q "emulator-"; then echo "already running" # Imprimir el serial existente adb_run devices 2>/dev/null | grep "emulator-" | awk '{print $1}' | head -n1 return 0 fi local log_file="/tmp/emulator_${AVD}.log" local pid_file="/tmp/emulator_${AVD}.pid" # Lanzar emulador en background "$EMULATOR" -avd "$AVD" -no-boot-anim -no-snapshot-load >"$log_file" 2>&1 & local emu_pid=$! echo "$emu_pid" > "$pid_file" # Esperar a que el dispositivo aparezca en adb local wait_timeout=$(( timeout_s / 2 )) if ! timeout "$wait_timeout" adb_run wait-for-device 2>/dev/null; then echo "android_emulator_start: timeout esperando que el dispositivo aparezca en adb (${wait_timeout}s)." >&2 return 1 fi # Verificar que el proceso del emulador sigue vivo if ! kill -0 "$emu_pid" 2>/dev/null; then echo "android_emulator_start: el proceso del emulador (PID $emu_pid) murió antes de completar el boot." >&2 echo " Log: $log_file" >&2 return 1 fi # Esperar boot completo (sys.boot_completed=1) local boot_timeout=$(( timeout_s - wait_timeout )) if ! adb_wait_boot "$boot_timeout"; then echo "android_emulator_start: timeout ${timeout_s}s esperando boot completo del AVD '$AVD'." >&2 echo " Log: $log_file" >&2 return 1 fi # Obtener serial del dispositivo emulado local serial serial=$(adb_run devices 2>/dev/null | grep "emulator-" | awk '{print $1}' | head -n1) echo "$serial" return 0 } # Ejecutar si se invoca directamente (no sourceado) if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then android_emulator_start "$@" fi