Files
FreeTLab bccc5c48b8
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s
docs(openspec): add SDD artifact trail for recent alarm and EQ changes
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.
2026-07-04 12:42:11 +02:00

2.8 KiB

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.

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