fix(alarms): a consumed skip stays handled, and only a swipe hides a notice

A skip spent on its occurrence now becomes the handled-occurrence watermark, so a second resolution inside the fire grace cannot ring the skipped alarm after all. The upcoming notice records a swipe through its delete intent rather than inferring one, so a reboot or a blocked channel no longer hides it for good; its Dismiss asks for an unlock, and a Dismiss for a switched-off alarm clears its notice.

Fixes #16
This commit is contained in:
makiolaj committed 2026-10-21 20:18:05 +02:00
1 parent 5b35ef65d4
commit dedcbd5dfd
9 files changed
+122 -42

No files matched your search

+12 -8
View File
@@ -250,9 +250,10 @@ so the skip eats a second alarm. With the watermark:
one after;
- watermark still in the future ⇒ fire the first candidate after it; write
nothing;
- watermark at or before now ⇒ consumed: clear the flag and the watermark, and
*still* return the first candidate after it, so the skipped occurrence cannot
ring on its way out through the grace window.
- watermark at or before now ⇒ consumed: clear the flag and the watermark,
record the skipped occurrence as the handled one, and *still* return the
first candidate after it, so the skipped occurrence cannot ring on its way
out through the grace window, on this pass or the next (#16).
Arming is deferred while a snooze is pending, and a **non-repeating** alarm with
the flag set is *disabled* rather than skipped: a one-shot has exactly one
@@ -1253,12 +1254,15 @@ the alarm's row for whoever opens the app instead.
the instant it carries.
- **No dismiss challenge before the ring**, as in Google Clock. The challenge
proves you are awake while an alarm sounds; before it, skipping is already one
unchallenged switch away in the editor.
unchallenged switch away in the editor. The notification's Dismiss does ask
for an **unlock** (`setAuthenticationRequired`), so a locked phone cannot be
talked out of its alarm by whoever picks it up.
- **Denied notifications** cost the notice and nothing else; the row's chip
still works. The notifier keeps a small SharedPreferences record of the
`id@fireAt` notices it has posted, so a reschedule, even in a new process,
does not bring back a notice the user swiped away; one the app cancelled
itself (the alarm left its window) is dropped from the record and may return.
still works. A swipe is recorded as an `id@fireAt` key in a small
SharedPreferences file through the notification's delete intent, which fires
for the user's swipe and never for the app's own cancel, a reboot or a
blocked channel. So a reschedule, even in a new process, does not bring back
a notice the user got rid of, and one the system took away does come back.
**The `showIntent` was wrong until M9.** It is what the system opens when the
user taps the status-bar alarm icon or the lockscreen's next-alarm line, and it