# Exploration: Pre-notice live countdown (30 -> 1 min ticks) ## Current State - `AlarmScheduler.kt` `schedulePreNotice()` (L138-189) arms exactly ONE `setExactAndAllowWhileIdle` alarm at `triggerAtMillis - PRE_NOTICE_MILLIS` (30 min). `PluriWaveAlarmReceiver.ACTION_PRE_NOTICE` fires once, computes `computeRemainingMinutes()`, posts notification. No re-arm. - Snooze countdown (`scheduleSnoozeCountdown`, `armNextSnoozeCountdownTick`, `handleSnoozeCountdownTick`, `cancelSnoozeCountdown`) is a genuine repeating chain: posts notification, re-arms `ACTION_SNOOZE_COUNTDOWN` at the next minute boundary, self-stops when `remaining <= 1`. - Both notifications reuse the same ID (`notificationIdForAlarm`) and are mutually exclusive. - `cancelAlarm()` is the single teardown chokepoint, already cancels preNotice + snoozeCountdown. - requestCode slots in use: 1=fire, 2=show, 3=preNotice, 5/6/7=snooze actions, 8=snoozeCountdown-tick. Slots 4, 9 free. - L10n already fully wired: `preNoticeCountdown`/`snoozeCountdown` ARB keys exist in all 13 locales. No l10n/Dart/MainActivity work needed. ## Recommended Approach **Parallel implementation** (mirror snooze pattern independently for pre-notice, not a shared abstraction): - Keep `schedulePreNotice` arming the first exact alarm at T-30min unchanged - After posting, `ACTION_PRE_NOTICE` handler calls new `armNextPreNoticeCountdownTick(id, remaining)` to re-arm at next minute boundary, self-stopping when `remaining <= 1` - Switch `computeRemainingMinutes` to same `ceilMinutes()` rounding as snooze for consistency Rejected: shared abstraction (different notification actions/files diverge enough that a callback/strategy param would be needed anyway, for marginal savings while risking the shipped snooze chain). ## Risks - **Doze quota**: `setExactAndAllowWhileIdle` capped at ~once/9min only in deep Doze. This codebase always pairs a `setAlarmClock()` for the same alarm, which is Doze-exempt — likely why snooze chain already works reliably. 30-min window spans more Doze risk than 3-10min snooze window. Mitigation: each tick computes from wall clock (not decrementing counter) — missed tick just causes display to "jump", self-healing. - **OEM battery managers**: pre-existing risk, not unique to this change. - **4-site cancellation checklist**: `cancelAlarm()`, `scheduleSpec` no-next-trigger branch, snooze-transition branch inside `schedulePreNotice`, AND newly `ACTION_SKIP_NEXT`/`ACTION_POSTPONE_NEXT` handlers (today only cancel notification since nothing repeats). ## Affected Files - `android/.../AlarmScheduler.kt` — new repeating tick mechanism mirroring scheduleSnoozeCountdown - `android/.../PluriWaveAlarmReceiver.kt` — ACTION_PRE_NOTICE re-arms itself; skip/postpone handlers cancel tick chain - No changes needed: AlarmNotificationStrings.kt, MainActivity.kt, servicio_alarmas_android.dart, ARB files