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>
12 KiB
Capability: android
Toolbelt Android Linux-first (con fallback WSL2 legacy). Cubre: ADB (adb_wsl resuelve el adb nativo del SDK), AVD emulator management (list/start/stop/wait, geo-fix), APK lifecycle (android_apk_install, android_app_clear, android_app_launch, android_uninstall), Capacitor build pipelines (capacitor_build_apk, deploy_capacitor_to_emulator), build Gradle nativo (gradle_*, init_kotlin_app, run_kotlin_app_tests), logcat streaming. Usa el SDK nativo en ~/android-sdk (via install_android_sdk); el adb/emulator de Windows solo se usa como fallback cuando se detecta WSL2.
Design system Compose: las apps Kotlin nativas (init_kotlin_app) heredan FnTheme + FnTokens del módulo kotlin/functions/ui (fn.compose:ui), con la paleta exacta de Mantine v9 dark + indigo (misma que web @fn_library y C++ fn_tokens).
Funciones
| ID | Firma | Que hace |
|---|---|---|
adb_wsl_bash_infra |
source adb_wsl.sh [ADB=<path>] [ANDROID_HOME=<sdk_root>] |
Wrapper sourceable para resolver e invocar adb. Linux-first: usa el adb nativo del Android SDK ($ANDROID_HOME) o del PATH; fallback a adb.exe solo si detecta WSL2. Expone adb_run, adb_devices, adb_pick_serial, adb_s, adb_wait_boot. |
android_apk_install_bash_infra |
android_apk_install([--serial S], apk_path: string, package_name?: string, activity_name?: string) -> void |
Instala APK en device/emulador via adb y opcionalmente lanza la app. Multi-emulator via --serial. |
android_app_clear_bash_infra |
android_app_clear([--serial <S>], package: string) -> void |
Wipe app data + cache via pm clear. App keeps installed but factory-state. Multi-emulator via --serial. |
android_app_info_bash_infra |
android_app_info([--serial <S>], package, [--json]) -> stdout |
Inspect installed app: version, target SDK, activities via dumpsys package. |
android_app_kill_bash_infra |
android_app_kill([--serial <S>], package: string) -> void |
Force-stop running app via am force-stop. Multi-emulator via --serial. |
android_app_launch_bash_infra |
android_app_launch([--serial <S>], package: string, [activity: string]) -> void |
Launch app activity via am start. Multi-emulator via --serial. |
android_app_uninstall_bash_infra |
android_app_uninstall([--serial <S>] package [--keep-data]) -> void |
Uninstall app via adb uninstall. Optionally keep data with --keep-data. |
android_emu_battery_bash_infra |
android_emu_battery([--serial <S>], level: int, [--charging <true|false>]) -> void |
Simulate battery state on emulator (level + charging). Emulator-only. |
android_emu_geo_fix_bash_infra |
android_emu_geo_fix([--serial <S>], longitude: string, latitude: string, [altitude: string]) -> void |
Fake GPS location on Android emulator via emu geo fix. Emulator-only (not physical devices). |
android_emu_rotate_bash_infra |
android_emu_rotate([--serial <S>] [portrait|landscape|0|90|180|270]) |
Rotate emulator screen. Empty=toggle, or fixed orientation. Locks autorotate. |
android_emulator_list_bash_infra |
android_emulator_list([--json]) |
Lista los AVDs disponibles. Linux-first: usa el emulator nativo del Android SDK ($ANDROID_HOME); fallback a emulator.exe solo bajo WSL2. |
android_emulator_start_bash_infra |
android_emulator_start(avd_name: string, timeout_s: int) -> string |
Arranca un AVD Android en background y espera a que termine de bootear. Linux-first: resuelve el emulator/adb nativos del SDK; fallback a binarios .exe solo bajo WSL2. Idempotente: si ya hay un emulador corriendo, imprime 'already running' y su serial sin lanzar otro. |
android_emulator_stop_bash_infra |
android_emulator_stop(serial?: string) -> void |
Para uno o todos los emuladores Android via adb emu kill. Si serial esta vacio, detecta todos los emulator-* activos y los para. Idempotente: exit 0 aunque no haya nada que matar. |
android_input_keyevent_bash_infra |
android_input_keyevent([--serial <S>] key: string) |
Send key event via adb shell input keyevent. Accepts aliases (BACK, HOME, POWER, ENTER, MENU, RECENT_APPS, VOLUME_UP, VOLUME_DOWN), raw numeric codes, or explicit KEYCODE_* names. |
android_input_swipe_bash_infra |
android_input_swipe([--serial <S>], x1: int, y1: int, x2: int, y2: int, [duration_ms: int]) |
Send swipe gesture between two points with duration. |
android_input_tap_bash_infra |
android_input_tap([--serial <S>], x: int, y: int) -> void |
Send tap gesture at screen coordinates via adb shell input tap. |
android_input_text_bash_infra |
android_input_text([--serial <S>], text: string) -> void |
Type text in focused field via adb shell input text. Spaces handled. |
android_logcat_bash_infra |
android_logcat([--serial <S>] [--package <name>] [--level <V|D|I|W|E|F>] [--lines <N>] [--clear]) |
Lee logcat del device/emulador, opcionalmente filtrado por package y nivel. Multi-emulator via --serial. |
android_pull_bash_infra |
android_pull [--serial <S>] remote_path local_path |
Pull file/dir from Android device to WSL via adb pull. |
android_push_bash_infra |
android_push([--serial <S>], local_path: string, remote_path: string) -> void |
Push file/dir from WSL to Android device via adb push. |
android_screen_record_bash_infra |
android_screen_record([--serial <S>] [--duration <s>] [--bit-rate <bps>] [--size <WxH>] output_path: string) -> void |
Record screen video via adb screenrecord, pulls to local path. |
android_screenshot_bash_infra |
android_screenshot([--serial <S>], output_path: string) -> void |
Capture screen as PNG via adb exec-out screencap -p. |
android_shell_bash_infra |
android_shell([--serial <S>], cmd ...args) |
Execute arbitrary shell command on Android device. Multi-emulator via --serial. |
capacitor_build_apk_bash_pipelines |
capacitor_build_apk(web_app_dir: string, [app_id: string], [app_name: string]) -> void |
Pipeline que convierte una web app en un APK de Android usando Capacitor. Valida el entorno (ANDROID_HOME, Java 17+), construye el bundle web si no existe dist/, inicializa Capacitor si no está configurado, añade la plataforma Android, sincroniza y compila el APK con Gradle. El APK final queda en el directorio raíz de la web app. |
deploy_capacitor_to_emulator_bash_pipelines |
deploy_capacitor_to_emulator(app_dir: string, avd_name?: string, package_name?: string) -> void |
Pipeline end-to-end: build Capacitor APK + arranca AVD + instala + opcionalmente lanza la app. Valida que el AVD existe, construye el APK con capacitor_build_apk, arranca el emulador de forma idempotente, instala el APK y lanza la app si se da package_name. Imprime comando logcat sugerido al final. |
fn_theme_kt_ui |
@Composable fun FnTheme(darkMode: Boolean = true, content: @Composable () -> Unit) |
Provider raiz del design system Compose del registry (@fn_compose). Envuelve MaterialTheme con un ColorScheme derivado de FnColors (Mantine v9 dark + indigo). Dark por defecto, mirror de FnMantineProvider (web) y fn::run_app ThemeMode::FnDark (C++). Toda app del registry envuelve su contenido en FnTheme. |
fn_tokens_kt_ui |
object FnTokens { colors; spacing; radius; typography; shadows } |
Design tokens del design system Compose del registry (@fn_compose). Paleta heredada exacta (mismos hex) de cpp/DESIGN_SYSTEM.md / Mantine v9 dark + indigo: FnColors, FnSpacing (Dp), FnRadius (Dp), FnTypography (sp + weights), FnShadows (Dp). Fuente unica de valores visuales para apps Android del registry. |
gradle_assemble_debug_bash_infra |
gradle_assemble_debug(project_dir: string, module: string) -> string |
Build APK debug de un modulo Android via gradlew assembleDebug. |
gradle_clean_bash_infra |
gradle_clean(project_dir: string) -> int |
Limpia build artifacts de un proyecto Android (gradle clean + rm .gradle + rm build). |
gradle_instrumented_test_bash_infra |
gradle_instrumented_test(project_dir: string, module: string) -> int |
Corre instrumented tests Compose en emulador/device Android conectado. |
gradle_run_bash_infra |
gradle_run(project_dir: string, task...: string) -> int |
Wrapper canonico para invocar gradlew Android en WSL2 con JDK 17 + ANDROID_HOME validados. |
gradle_screenshot_test_bash_infra |
gradle_screenshot_test(project_dir: string, module: string, flag: string) -> int |
Corre screenshot tests Roborazzi de Composables (JVM, no necesita emulador). |
gradle_unit_test_bash_infra |
gradle_unit_test(project_dir: string, module: string, --variant <name>: string) -> int |
Corre unit tests JVM de un modulo Android (no requiere emulador). |
init_kotlin_app_bash_pipelines |
init_kotlin_app(name: string, [--project <p>] [--desc <s>] [--tags <csv>] [--package <id>]) -> void |
Scaffolder canonico de app Android Kotlin Compose con FnTheme + Roborazzi tests + e2e_checks declarados. Mirror exacto del patron init_cpp_app para el stack Kotlin. |
install_android_sdk_bash_infra |
install_android_sdk() -> void |
Descarga e instala Android SDK command-line tools y JDK 17 localmente (sin root/sudo) en $ANDROID_SDK_DIR (default: $HOME/android-sdk). Idempotente: detecta instalacion existente y sale sin hacer nada. Genera env.sh con JAVA_HOME, ANDROID_HOME y PATH listos para hacer source. |
nominatim_reverse_geocode_kt_infra |
fun nominatimReverseGeocode(lat: Double, lon: Double, lang: String = "es"): GeocodedLocation |
Reverse geocoding usando Nominatim (OpenStreetMap). Convierte coordenadas lat/lon a una dirección estructurada (calle, ciudad, país, etc.) para Android/Kotlin sin dependencias externas. |
ollama_chat_kt_infra |
fun ollamaChat(messages: List<Map<String, String>>, model: String = "llama3.1:8b", baseUrl: String = "http://localhost:11434", temperature: Double = 0.7, maxTokens: Int = 1024): OllamaChatResponse |
Envía una solicitud de chat completion a un servidor Ollama local. Retorna el contenido generado junto a métricas de duración y tokens evaluados. |
overpass_nearby_pois_kt_infra |
fun overpassNearbyPois(lat: Double, lon: Double, radiusM: Int = 500, categories: List<String>? = null): List<POI> |
Consulta la Overpass API (OpenStreetMap) para obtener POIs cercanos a una coordenada. Soporta 16 categorias mapeadas a tags OSM (amenity, tourism, historic, leisure, shop). Sin dependencias externas: solo Android SDK (HttpURLConnection + org.json). |
run_kotlin_app_tests_bash_pipelines |
run_kotlin_app_tests(project_dir: string, avd_name?: string, --skip-emulator?, --no-stop?) -> int |
Pipeline e2e completo de testing app Kotlin: unit JVM + screenshot Roborazzi + build APK + instrumented Compose en emulador. |
Ejemplo canonico
Arrancar emulator + deploy Capacitor + logcat
./fn run android_emulator_list
./fn run android_emulator_start --avd Pixel_7_API_34 --wait
./fn run deploy_capacitor_to_emulator \
--app-dir ~/projects/myapp \
--avd Pixel_7_API_34 \
--package com.example.myapp
./fn run adb_wsl -- logcat -v time | grep -E "(myapp|FATAL|AndroidRuntime)"
APK install/uninstall manual
./fn run android_apk_install --apk ~/myapp.apk --device emulator-5554
./fn run android_app_launch --package com.example.myapp
./fn run android_app_clear --package com.example.myapp # limpia datos sin uninstall
Fronteras
- NO compila APK desde Gradle nativo. Solo Capacitor build. Para Gradle puro, ver issue 0076 (
gradle_run). - NO instala Android SDK. Asume
ANDROID_HOMEapuntando al SDK Windows accessible via WSL. - NO maneja iOS. Solo Android. Para iOS, ver issue 0072h (gamedev roadmap).
- NO depura nativo NDK. Para LLDB-stage debugging, attach manual via Android Studio.