efc9911925
Design system Compose (kotlin/functions/ui, modulo Gradle `fn.compose:ui`):
- FnTokens + FnTheme con la paleta heredada al hex de cpp/DESIGN_SYSTEM.md
(Mantine v9 dark + indigo), identica a la web @fn_library y a las apps C++.
- 26 componentes Compose (Layout/Display/Inputs/Feedback/Data/Charts) +
FnTheme + FnTokens registrados en el registry (28 entradas kind=component
lang=kt domain=ui), descubribles via fn_search. Habilitan init_kotlin_app.
Recuperacion: el commit cb6d9e6 habia anadido `kotlin/functions/ui/` al
.gitignore, por eso el design system nunca se versiono y se perdio del working
tree. Des-ignorado; el .gitignore interno del modulo ya excluye
build/.gradle/local.properties. La gallery (apps/gallery_kt) se recupero del
sub-repo Gitea y sus 27 componentes se reconstruyeron con su MainActivity como
contrato exacto.
Toolbelt Android Linux-first (antes asumia WSL2 + Windows):
- adb_wsl 1.1.0, android_emulator_start 1.1.0, android_emulator_list 1.1.0:
resuelven adb/emulator nativos del SDK ($ANDROID_HOME), .exe solo fallback WSL2.
- android_emulator_start: fix `timeout adb_run wait-for-device` (timeout no puede
ejecutar una funcion del shell; ahora invoca el binario $ADB directamente).
- install_android_sdk 1.0.1: fix licencias bajo pipefail (SIGPIPE de `yes`) +
trap EXIT con variable unbound.
- docs/capabilities/android.md regenerado Linux-first + seccion design system.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
126 lines
5.0 KiB
Bash
126 lines
5.0 KiB
Bash
#!/usr/bin/env bash
|
|
# android_emulator_start — Arranca un AVD en background y espera a que bootee.
|
|
# Uso: android_emulator_start <avd_name> [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 <avd_name> [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
|