daef7ea190
Helper functions (matrix-mas capability group): - mas_client_register_bash_infra: register/sync OAuth clients via mas-cli - mas_syn2mas_migration_bash_infra: dry-run + apply user migration to MAS - synapse_msc3861_enable_go_infra: edit homeserver.yaml MSC3861 block (with diff) - wellknown_oidc_patch_go_infra: patch well-known JSON with msc2965.authentication - synapse_login_flows_check_go_infra: health-check post-migration login flows Flows + issues for custom Matrix clients (PC + Android): - 0010 matrix-client-pc: Wails + React+Mantine (issues 0147-0153) - 0011 matrix-client-android: Kotlin + Compose (issues 0154-0161) - 0162 enable MAS as auth provider (Synapse delegate) — EXECUTED on VPS - 0163 custom admin panel propio (sustituye synapse-admin) Production state (organic-machine.com): - Synapse migrated SQLite -> Postgres - MSC3861 active, password_config disabled - 21 users + 41 access_tokens migrated via syn2mas - 4 MAS clients registered (element, matrix_pc, matrix_android, admin_panel) - synapse-admin container removed + Coolify route deleted - well-known patched with org.matrix.msc2965.authentication Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
166 lines
9.3 KiB
Markdown
166 lines
9.3 KiB
Markdown
---
|
|
name: matrix-client-android
|
|
id: 0011
|
|
status: pending
|
|
created: 2026-05-24
|
|
updated: 2026-05-24
|
|
priority: high
|
|
risk: medium
|
|
related_issues: [0154, 0155, 0156, 0157, 0158, 0159, 0160, 0161, 0162, 0163]
|
|
related_flows: [0009, 0010]
|
|
apps: [matrix_client_android]
|
|
projects: [element_agents]
|
|
vaults: []
|
|
capability_groups: [matrix-client, livekit-calls, e2ee, widgets, android-native]
|
|
trigger: manual
|
|
schedule: ""
|
|
expected_runtime_s: 0
|
|
tags: [matrix, element, android, kotlin, compose, livekit, e2ee, widgets, agents, fcm, push]
|
|
---
|
|
|
|
## Goal
|
|
|
|
Cliente Matrix Android nativo (Kotlin + Jetpack Compose) que comparte contrato con el cliente PC (flow 0010) pero usa SDKs nativos para calidad superior: `matrix-rust-sdk` Kotlin bindings (E2EE rust, mejor), `livekit-android` (codecs HW, audio focus, AEC), FCM push directo via `sygnal`, foreground service para calls en background. Replica capacidades de Element Android + abre mini-webapps embebidas (Matrix Widget API v2 dentro de WebView) gestionadas por agentes del project `element_agents`.
|
|
|
|
## Pre-requisitos
|
|
|
|
- Stack Synapse + MAS + LiveKit ya activo en `organic-machine.com` (flow 0010 compartido).
|
|
- Container `sygnal` corriendo en VPS (anadir si no existe — issue 0159 lo cubre).
|
|
- Firebase project con FCM activado + service account JSON. Hosting gratuito.
|
|
- Android Studio Iguana+, NDK r26+, Kotlin 1.9+.
|
|
- `init_kotlin_app_bash_pipelines` (ya existe, ver issues 0073/0074/0075/0078 completados) para scaffold inicial.
|
|
- Device fisico o emulator Android 9+ (API 28+) para test.
|
|
- Capability del usuario operador: instalar APK debug + microphone/camera/notification grants.
|
|
|
|
## Funciones del registry recomendadas
|
|
|
|
| Rol | Funcion candidata | Estado |
|
|
|---|---|---|
|
|
| Kotlin app scaffold | `init_kotlin_app_bash_pipelines` | OK (reusar) |
|
|
| Matrix rust-sdk wrapper (Kotlin) | `matrix_client_kotlin_infra` | FALTA: facade sobre `matrix-rust-sdk` Kotlin bindings |
|
|
| LiveKit Android wrapper | `livekit_call_kotlin_infra` | FALTA: wrapper `io.livekit:livekit-android` |
|
|
| FCM token register | `fcm_register_kotlin_infra` | FALTA: registrar device en sygnal via Synapse pusher API |
|
|
| Sygnal pusher add | `sygnal_pusher_add_go_infra` | FALTA: Go helper para configurar push gateway |
|
|
| Compose Room list | `RoomListScreen_kotlin_ui` | FALTA |
|
|
| Compose Timeline | `TimelineScreen_kotlin_ui` | FALTA |
|
|
| Compose Composer | `Composer_kotlin_ui` | FALTA |
|
|
| Compose CallScreen | `CallScreen_kotlin_ui` | FALTA |
|
|
| Compose WidgetHost | `WidgetHost_kotlin_ui` | FALTA: WebView + JS bridge Widget API |
|
|
| Foreground service call | `CallForegroundService_kotlin_infra` | FALTA |
|
|
| ICE permissions helper | `permissions_request_kotlin_core` | FALTA: mic/cam/notif/foreground service grants |
|
|
| Local DB Room | reusar `androidx.room` directo | OK |
|
|
|
|
## Apps tocadas
|
|
|
|
- `projects/element_agents/apps/matrix_client_android` (nueva — Kotlin+Compose).
|
|
- `projects/element_agents/apps/element_matrix_chat` (anadir sygnal container — issue 0159).
|
|
- `projects/element_agents/apps/agents_and_robots` (consumidor agent panels).
|
|
|
|
## Projects relacionados
|
|
|
|
- `element_agents`.
|
|
|
|
## Vaults / storage
|
|
|
|
- Local Android: `/data/data/com.fnregistry.matrix_client_android/databases/` (room DB encriptada via SQLCipher).
|
|
- Crypto store de matrix-rust-sdk: gestionado por el SDK en `files/matrix/<userId>/`.
|
|
|
|
## Capability groups consultados
|
|
|
|
- `matrix-client` (compartido con flow 0010).
|
|
- `livekit-calls` (compartido).
|
|
- `e2ee` (compartido).
|
|
- `widgets` (compartido — contrato Widget API igual).
|
|
- `android-native` (a crear: foreground service, FCM, MediaSession para calls).
|
|
|
|
## Flow
|
|
|
|
1. **0154 — Scaffold Kotlin + Compose + login MAS.** App `matrix_client_android/` con `init_kotlin_app`, Material 3 + tema propio acorde a `frontend_theming.md` (paleta equivalente). Login MAS OIDC via Chrome Custom Tabs. Tokens persistidos en EncryptedSharedPreferences.
|
|
2. **0155 — Rooms list + Timeline.** Compose UI con `LazyColumn` virtualizado, sync via `matrix-rust-sdk` (corrutinas). Pagination, optimistic UI, swipe-to-react.
|
|
3. **0156 — Composer.** Markdown, replies, edits, reactions, media (camara + galeria + voice msg con `MediaRecorder` opus).
|
|
4. **0157 — E2EE rust-sdk.** Cross-signing setup, SAS verification (emoji), recovery passphrase, key backup. UI dialog verificacion.
|
|
5. **0158 — Calls LiveKit Android nativo.** `livekit-android` SDK con codecs HW (H.264/VP9 hardware decoder), audio focus, echo cancellation, noise suppression. PiP mode Android nativo.
|
|
6. **0159 — Push FCM via sygnal.** Anadir container `sygnal` al stack `element_matrix_chat`. Registrar FCM token via Synapse Pusher API. Handle push payload -> open room / wake up para incoming call.
|
|
7. **0160 — Mini-webapps en WebView.** `WebView` con `WebViewClient` + JS bridge implementando Matrix Widget API v2. Sandbox via `setAllowFileAccess(false)`, `setAllowContentAccess(false)`, CSP estricta. Mismo contrato widgets que cliente PC.
|
|
8. **0161 — Foreground service para calls + lifecycle.** `CallForegroundService` con notification ongoing, audio routing (speaker/earpiece/bluetooth), MediaSession para controls en lockscreen, wakelock controlado.
|
|
|
|
## Acceptance
|
|
|
|
- [ ] APK debug instala + arranca en Android 9+ (API 28).
|
|
- [ ] Login MAS via Chrome Custom Tabs, token persistido en EncryptedSharedPreferences.
|
|
- [ ] Sync incremental funciona; reconexion automatica tras avion mode toggle.
|
|
- [ ] E2EE: mensaje enviado desde PC (Wails) se descifra en Android (y al reves).
|
|
- [ ] Call 1:1 con video+audio nativos, calidad superior a WebView.
|
|
- [ ] Push FCM despierta app para incoming msg / call.
|
|
- [ ] Widget de prueba se carga en WebView sandbox con bridge funcional.
|
|
- [ ] Foreground service mantiene call viva con app en background + pantalla bloqueada.
|
|
|
|
## Definition of Done
|
|
|
|
### Mecanica (pre-requisito)
|
|
|
|
- `./gradlew assembleDebug` verde.
|
|
- `./gradlew test` verde.
|
|
- `./gradlew connectedAndroidTest` verde en emulator API 31+ (instrumented).
|
|
- `app.md` con `uses_functions` declarando dependencias del registry.
|
|
|
|
### Cobertura de comportamiento
|
|
|
|
| Escenario | Tipo | Comando / evidencia | Resultado esperado |
|
|
|---|---|---|---|
|
|
| Golden: login + E2EE msg | instrumented | `./gradlew connectedAndroidTest --tests *LoginE2EE*` | msg descifrado en <2s, shield green |
|
|
| Edge: avion mode 30s | instrumented | `./gradlew connectedAndroidTest --tests *Reconnect*` | sync resume, sin perder msgs |
|
|
| Edge: 1000 msgs en room | benchmark | `./gradlew :app:benchmark` | scroll a 60fps, RAM <300MB |
|
|
| Edge: incoming call, pantalla apagada | manual + screencast | apagar pantalla + recibir call desde PC | notif full-screen + ring, accept funciona |
|
|
| Error: FCM token rotation | instrumented | `./gradlew connectedAndroidTest --tests *FCMRotation*` | re-register automatico en sygnal |
|
|
| Error: WebView widget malicioso | instrumented | `./gradlew connectedAndroidTest --tests *WidgetSandbox*` | bloqueado, no escape |
|
|
| Battery: call 30min | manual + dumpsys batterystats | call 30min | drain <15%, sin OOM |
|
|
|
|
### Vida util validada (>=7 dias uso real)
|
|
|
|
| Metrica | Umbral | Donde se observa | Ventana |
|
|
|---|---|---|---|
|
|
| Crashes (ANRs/forced close) | `0` | `adb logcat -e FATAL` + Play Console (si publicado) | 7 dias |
|
|
| Push latency (msg enviado -> notif visible) | `p95 < 3s` | log custom en app + sygnal | 7 dias |
|
|
| Call drops in-pocket (lockscreen) | `< 5%` | counter app | 7 dias |
|
|
| Battery drain idle | `< 2%/h` | dumpsys batterystats | 7 dias |
|
|
| Uso real diario | `>= 5 dias/semana` | last_active en local DB | 7 dias |
|
|
|
|
### Anti-criterios
|
|
|
|
- NO marcar done si E2EE silent-falla.
|
|
- NO marcar done si call con pantalla bloqueada se corta a los <5min (battery optimization mata el service).
|
|
- NO marcar done si WebView de widget permite acceso a `file://` o cookies del browser host.
|
|
- NO marcar done si la app solo funciona en el device del operador y peta en Android < 11.
|
|
- NO marcar done sin probar en Android 9 (legacy, muchos dispositivos antiguos siguen vivos).
|
|
|
|
## Notas
|
|
|
|
**Onboarding rapido:**
|
|
1. `cd projects/element_agents/apps/matrix_client_android`
|
|
2. `./gradlew assembleDebug && adb install -r app/build/outputs/apk/debug/app-debug.apk`
|
|
3. Para hot-reload UI: `./gradlew :app:installDebug` + Android Studio Compose preview.
|
|
4. Para test push: enviar msg desde Element Web a la cuenta del Android; debe llegar notif via FCM en <3s.
|
|
|
|
**Decisiones clave:**
|
|
- `matrix-rust-sdk` Kotlin bindings > matrix-android-sdk2 (deprecated). Rust-sdk es el futuro oficial de matrix.org.
|
|
- `livekit-android` nativo > WebRTC.org directo. SDK oficial mantiene mejor performance + features.
|
|
- Jetpack Compose > XML views. Encaja mejor con reactive model + menos boilerplate.
|
|
- EncryptedSharedPreferences para tokens MAS. NO usar SharedPreferences plain.
|
|
- Material 3 con tema propio (paleta similar a Mantine accent del cliente PC para coherencia visual).
|
|
|
|
**Camino futuro (post-DoD):**
|
|
- Wear OS companion app (notifs + quick reply).
|
|
- Android Auto integration (read msgs voice + reply voice).
|
|
- Conversation shortcuts API (Android 11+) para que cada room aparezca en share sheet.
|
|
- Bubble notifications (Android 11+) para conversaciones favoritas.
|
|
|
|
**Compartido con flow 0010:**
|
|
- Contrato `m.widget` y Widget API v2 IDENTICO. Mismo widget html funciona en ambos.
|
|
- Contrato `m.agent.metadata` para detectar rooms de agentes IDENTICO.
|
|
- Cuando flow 0009 (mesh) este vivo, ambos clientes hablan a `device_agent` igual.
|
|
|
|
## Capability growth log
|
|
|
|
- v0.1.0 (2026-05-24) — baseline.
|