Persist the exploration, proposal, spec, design, tasks, and verify/archive reports produced during the multi-device EQ, alarm-countdown, and notification-visual-polish SDD cycles.
35 lines
3.3 KiB
Markdown
35 lines
3.3 KiB
Markdown
# Exploration: snooze-reschedule-fix
|
|
|
|
## Root Cause (single defect explains all 3 symptoms)
|
|
|
|
`lib/estado/estado_alarmas.dart` — `posponerAlarma()` (L194-212) and `posponerProximaDesdePreaviso()` (L214-236) call `await android.programar(actualizada)` with **no try/catch**, unlike `guardarAlarma()` (L98-115) which wraps the identical call in try/catch and still reaches `notifyListeners()` on failure.
|
|
|
|
### Failure chain
|
|
1. Native `scheduleMainAlarm()` likely fails (most probable: exact-alarm permission revoked on Android 14+/OEM battery manager — `posponerAlarma` never re-requests permission before scheduling, unlike `guardarAlarma` which calls `_solicitarPermisosNecesariosParaAlarma()` first)
|
|
2. `AlarmScheduler.scheduleSpec()` (Kotlin, L108-118): if `scheduleMainAlarm()` returns `false`, returns `false` immediately — **before reaching `scheduleSnoozeCountdown()` at L126**. This is why the countdown notification never appears too — same root cause as the no-refire bug.
|
|
3. `scheduleAlarm()` returns `false` → `ServicioAlarmasAndroid.programar()` throws `StateError`
|
|
4. Exception propagates out of `posponerAlarma()` **uncaught** — `notifyListeners()` (L211) never reached, even though `_aplicar(config)` (L206) already mutated `_alarmas` in memory
|
|
5. `_posponer()` in `pantalla_alarma_sonando.dart` (L181-187) catches it only to `debugPrint` and dismiss the screen — no user feedback, no retry
|
|
6. Result: (A) no real fire alarm scheduled; (B) `scheduleSnoozeCountdown` never runs; (C) `proximaAlarma`/`proximaProgramable` getters hold correct data in memory but UI never rebuilds because `notifyListeners()` was skipped
|
|
|
|
## Ruled out (verified)
|
|
- PendingIntent requestCode collision — different formulas (31x vs 47x), correctly scoped
|
|
- Notification channel mismatch — channel created identically by both classes
|
|
- "Missing initial countdown post" — `scheduleSnoozeCountdown()` posts notification AND arms first tick in one call
|
|
- Dart→Kotlin Long encoding, `alarma.activa` flag, periodic resync, fire-vs-snooze race — all verified correct
|
|
|
|
## Affected Areas
|
|
- `lib/estado/estado_alarmas.dart` — `posponerAlarma()`, `posponerProximaDesdePreaviso()`: missing try/catch, missing notifyListeners()-on-failure, missing permission pre-check
|
|
- `android/.../AlarmScheduler.kt` — `scheduleSpec()` (81-137): early return false skips scheduleSnoozeCountdown entirely (by design, but compounds the silent Dart-side failure)
|
|
- `lib/pantallas/pantalla_alarma_sonando.dart` — `_posponer()`: swallows exception with only debugPrint, no user-facing signal
|
|
|
|
## Recommendation
|
|
1. Wrap `android.programar()` in both snooze methods in try/catch mirroring `guardarAlarma()` — always reach `notifyListeners()`
|
|
2. Add the same permission pre-check (`_solicitarPermisosNecesariosParaAlarma()`) before scheduling in both snooze methods
|
|
3. Surface failure to user in `_posponer()` (SnackBar) since the screen always dismisses regardless by design
|
|
4. Device-test with exact-alarm permission both granted and revoked
|
|
|
|
## Risks
|
|
- Root cause is permission-dependent; cannot be 100% confirmed without `adb logcat` from the device at failure time. Fix should land regardless since missing try/catch + missing notifyListeners is a confirmed defect independent of which native call failed underneath
|
|
- `posponerProximaDesdePreaviso` shares the identical defect, must be fixed together
|