fix(alarms): keep clock changes and setting writes inside one window
Third round of review fixes for the silence-after setting. A backstop that fires while the clock is still behind the ring's start now closes the ring instead of re-arming in a loop until the wall clock catches up. A clock change re-measures a ring in progress before it reschedules: a clock moved back re-arms the backstop at most one window from the moved clock, and one moved forward past the window closes the ring. The engine now owns the alarm setting's write. setAlarmSilenceAfter stores it and re-measures the ring under one lock and without cancellation, so a write can no longer land without the re-measure. A snooze the resolver drops takes its "Snoozed until" notification with it. SNOOZE_GRACE is derived from the default window, and the silence-after picker moves to ui/settings, since it is not a per-alarm override. Refs #17
This commit is contained in:
1 parent
fb875ca71c
commit
4cb4b6b6eb
9 files changed
+151
-61
No files matched your search
+11
-7
@@ -1179,13 +1179,17 @@ go through `SilenceAfter.sanitise` on read, on write and from a backup: over 60
|
||||
is 60, so no value can make a ring outlast the hard stop, and a negative one is
|
||||
the default rather than the clamp's floor, which would be "Never".
|
||||
|
||||
Changing the setting mid-ring applies at once. The settings screen calls
|
||||
`AlarmEngine.onSilenceAfterChanged()`, which measures the ring in progress
|
||||
against the new window from when it *started*: past it, the cycle closes as
|
||||
missed through `closeCycleLocked`; inside it, the backstop moves to the new
|
||||
end. As a second line, `onAutoSilence` re-arms rather than closes a ring that
|
||||
is still inside the current window, so a backstop armed for a shorter one can
|
||||
never end a ring early.
|
||||
Changing the setting mid-ring applies at once. The settings screen writes it
|
||||
through `AlarmEngine.setAlarmSilenceAfter()`, which stores it and, under the
|
||||
same lock and uncancellably, measures the ring in progress against the new
|
||||
window from when it *started*: past it, the cycle closes as missed through
|
||||
`closeCycleLocked`; inside it, the backstop moves to the new end. As a second
|
||||
line, `onAutoSilence` re-arms rather than closes a ring that is still inside
|
||||
the current window, so a backstop armed for a shorter one can never end a ring
|
||||
early. A clock change re-measures the ring the same way before rescheduling:
|
||||
the backstop is a wall-clock registration, so a clock moved back re-arms it at
|
||||
most one window from the moved clock (and the backstop then closes the ring,
|
||||
its age still negative), and one moved forward past the window closes it.
|
||||
|
||||
Whenever the resolver closes a ring (a clock jumped forward, a ringing alarm
|
||||
switched off, a reboot outlasting the window), `persist` stops the ring service
|
||||
|
||||
Reference in new issue
Block a user