a3f75d61ec
Reorganizacion de dev/issues en subcarpetas (completed/, cpp/, gamedev/, kanban/, trading/, imagegen/, matrix/) y cambios acumulados en cmd/fn/pyrunner, .claude/commands y settings. Trabajo de otro LLM/sesion, commiteado a peticion del usuario para desbloquear el working tree. Excluido logs/ardour_mcp_server.log (ruido).
90 lines
4.6 KiB
Markdown
90 lines
4.6 KiB
Markdown
---
|
|
id: "0161"
|
|
title: "matrix-client-android foreground service: calls + lifecycle + lockscreen"
|
|
status: pendiente
|
|
priority: alta
|
|
created: 2026-05-24
|
|
related_flows: ["0011"]
|
|
related_issues: ["0158", "0160"]
|
|
dependencies: ["0158"]
|
|
tags: [matrix, android, foreground-service, lifecycle, mediasession, wakelock]
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
`CallForegroundService` que mantiene call activa con app en background o pantalla bloqueada. Notification ongoing visible mientras dura la call. `MediaSession` para integrar con lockscreen controls + Bluetooth Car (mute, hangup desde audio device). Wakelock controlado para evitar drain excesivo. Notificaciones full-screen intent para incoming calls (despiertan pantalla).
|
|
|
|
## Tareas
|
|
|
|
1. `CallForegroundService` (`android.app.Service`):
|
|
- `START_FOREGROUND_SERVICE` con type `MEDIA_PROJECTION` o `PHONE_CALL` (Android 14+ requiere type explicito).
|
|
- `Notification.Builder` channel `calls` con:
|
|
- Custom view con caller name, duration, mute/hangup buttons.
|
|
- `setOngoing(true)`.
|
|
- `setCategory(CATEGORY_CALL)`.
|
|
- Lifecycle: `START_STICKY` para reiniciar si OS lo mata (raro con foreground).
|
|
2. `MediaSession` integration:
|
|
- `MediaSessionCompat` con play/pause/stop actions mapeados a mute/unmute/hangup.
|
|
- Bluetooth Car media controls.
|
|
- Lockscreen controls visibles si dispositivo lo soporta.
|
|
3. Wakelock:
|
|
- `PowerManager.PARTIAL_WAKE_LOCK` durante call activa.
|
|
- `WAKE_LOCK_KEY = "matrix_client:call"` para audit en `dumpsys power`.
|
|
- Liberar inmediato al hangup.
|
|
- Proximity wakelock (`PROXIMITY_SCREEN_OFF_WAKE_LOCK`) si call solo audio + telefono pegado a oreja.
|
|
4. Incoming call full-screen intent:
|
|
- `Notification` con `setFullScreenIntent(pendingIntent, true)`.
|
|
- Activity `IncomingCallActivity` con `showWhenLocked(true)` + `turnScreenOn(true)`.
|
|
- Compose UI fullscreen con accept/decline.
|
|
5. Doze mode handling:
|
|
- `ACTION_IGNORE_BATTERY_OPTIMIZATIONS` solicitar al user en onboarding (no obligatorio, solo para calls fiables).
|
|
- Documentar tradeoff en pantalla onboarding.
|
|
6. Battery monitoring:
|
|
- Log custom: call duration + battery_drain_pct al hangup.
|
|
- Visible en `Settings > Diagnostics` para debug.
|
|
7. Tests:
|
|
- Manual `CallBackgroundTest` — start call + Home button -> notif visible + audio sigue.
|
|
- Manual `CallLockscreenTest` — call + power button -> pantalla apaga + audio sigue + lockscreen controls visibles.
|
|
- Manual `IncomingFullScreenTest` — device en lockscreen + incoming call -> pantalla despierta + UI accept/decline.
|
|
- Manual `BluetoothCarTest` — Bluetooth Car connected + call active + mute desde steering wheel funciona.
|
|
- Manual `BatteryTest` — call 30min en background + WiFi + AC -> drain <15%.
|
|
|
|
## Funciones del registry a crear
|
|
|
|
- `CallForegroundService_kotlin_infra` — service completo.
|
|
- `media_session_kotlin_infra` — wrapper MediaSessionCompat.
|
|
- `wakelock_manager_kotlin_infra` — adquirir/liberar wakelocks de forma idempotente.
|
|
- `IncomingCallActivity_kotlin_ui` — Compose fullscreen activity.
|
|
- `battery_monitor_kotlin_infra` — log drain por session.
|
|
|
|
## Acceptance
|
|
|
|
- [ ] Call activa + Home -> notif ongoing visible + audio sigue 30s.
|
|
- [ ] Call + power button -> lockscreen muestra controls + audio sigue.
|
|
- [ ] Incoming call con pantalla apagada -> despierta + UI accept/decline.
|
|
- [ ] Bluetooth Car: mute/hangup desde steering wheel funciona.
|
|
- [ ] Hangup libera wakelocks (verificar con `dumpsys power | grep matrix_client`).
|
|
- [ ] Battery saver activo: call no se corta (foreground service exempt).
|
|
- [ ] Call 30min background: drain <15% con WiFi+AC.
|
|
|
|
## Notas
|
|
|
|
**Anti-criterios:**
|
|
- NO marcar done si call se corta a los 5min en background (battery optimization kill).
|
|
- NO marcar done si wakelock queda colgado tras hangup (battery leak).
|
|
- NO marcar done si lockscreen no muestra controls (UX critico para calls largas).
|
|
|
|
**Gotchas Android 14+:**
|
|
- Foreground service type DEBE declararse en manifest + runtime: `phoneCall|mediaProjection`.
|
|
- `POST_NOTIFICATIONS` runtime permission (Android 13+).
|
|
- `USE_FULL_SCREEN_INTENT` runtime permission (Android 14+) — pedir explicito.
|
|
|
|
**Decisiones:**
|
|
- Telecom framework (ConnectionService): NO en esta iteracion. Pro: integracion dialer nativo. Con: bug-prone, requiere CALL_PHONE permission con justificacion Play Store. Post-DoD considerar.
|
|
- Audio focus exclusivo durante call (issue 0158 ya lo cubre).
|
|
|
|
**Battery optimization onboarding:**
|
|
- Pantalla en primer launch: explicar por que pedimos exempt battery optimization (calls fiables).
|
|
- Boton "Open settings" -> `Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`.
|
|
- Si user declina: app funciona pero documentar que calls largas pueden cortarse.
|