#!/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 (Linux-first; WSL fallback) if [[ -z "${ADB:-}" ]]; then _sdk="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}" if [[ -n "$_sdk" && -x "$_sdk/platform-tools/adb" ]]; then ADB="$_sdk/platform-tools/adb" elif command -v adb &>/dev/null; then ADB="$(command -v adb)" else ADB="${ANDROID_SDK_WIN:-/mnt/c/Users/$USER/AppData/Local/Android/Sdk}/platform-tools/adb.exe" fi unset _sdk 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 (Linux-first; WSL fallback) # --------------------------------------------------------------------------- if [[ -z "${EMULATOR:-}" ]]; then _sdk="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}" if [[ -n "$_sdk" && -x "$_sdk/emulator/emulator" ]]; then EMULATOR="$_sdk/emulator/emulator" elif command -v emulator &>/dev/null; then EMULATOR="$(command -v emulator)" elif grep -qiE "(microsoft|wsl)" /proc/version 2>/dev/null; then EMULATOR="${ANDROID_SDK_WIN:-/mnt/c/Users/$USER/AppData/Local/Android/Sdk}/emulator/emulator.exe" fi unset _sdk 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 [[ -z "${EMULATOR:-}" ]] || ! command -v "$EMULATOR" &>/dev/null; then echo "android_emulator_start: emulator no encontrado. Instala el SDK + paquete 'emulator', exporta ANDROID_HOME, o fija EMULATOR=." >&2 return 1 fi if [[ -z "${ADB:-}" ]] || ! command -v "$ADB" &>/dev/null; then echo "android_emulator_start: adb no encontrado. Instala platform-tools, exporta ANDROID_HOME, o fija ADB=." >&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. # Usamos el binario "$ADB" directamente (no la funcion adb_run): `timeout` # ejecuta un comando externo y no puede ver funciones del shell, asi que # `timeout ... adb_run` fallaba siempre con "command not found". local wait_timeout=$(( timeout_s / 2 )) if ! timeout "$wait_timeout" "$ADB" 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