fix(bedtime): DST-safe windows, ordered edits, quieter passes
Whether the wake time is the same night or the next morning is now decided on the local times, so a bedtime in a spring-forward gap no longer turns a 45-minute window into a day-long one. Screen edits start undispatched so they reach the engine's lock in the order they were made, and an edit that rewrites the rule also re-asserts the mode, in case the platform reset its state. The launch-time bedtime pass runs even if an earlier engine pass failed, a restore that never applied settings no longer forces the mode, and a user who never turned bedtime on pays nothing for it at launch or boot. The screen says when equal bedtime and wake-up times mean it never starts. Refs #1
This commit is contained in:
1 parent
2dce78281a
commit
1a443c066f
11 files changed
+87
-38
No files matched your search
@@ -2770,18 +2770,20 @@ engines (`ArchitectureRulesTest` holds it to no `android.*` import):
|
||||
Every entry point is an idempotent pass over "where does the schedule stand
|
||||
now", computed by `BedtimeSchedule`: a night's window runs from the bedtime on
|
||||
one of the chosen days to the first wake time after it (an earlier wake time is
|
||||
the next morning; an equal one is no window at all, since a day-long window on
|
||||
every night would be a Do Not Disturb that never ends), resolved from local times and the
|
||||
the next morning, decided on the local times so a bedtime in a spring-forward
|
||||
gap cannot push a same-night wake time a day later; an equal one is no window
|
||||
at all, since a day-long window on every night would be a Do Not Disturb that
|
||||
never ends, and the screen says so), resolved from local times and the
|
||||
zone like an alarm, so a DST night is as long as the wall clock says. The slot
|
||||
is armed for the earliest of the current window's end, the next window's
|
||||
reminder and the next window's start.
|
||||
|
||||
| Entry point | Called from | What it does |
|
||||
|---|---|---|
|
||||
| `update(transform)` | the bedtime screen, on the application scope so leaving the screen cannot cut a write short | stores the settings, rewrites the rule if a field it carries changed, and when the schedule itself changed sets the mode to what it says now (on at 23:30 for a 23:00 bedtime starts it at once; a reminder or effect edit leaves a hand-switched mode alone), arms the slot. Off removes the rule, which ends the mode, cancels the slot and clears the reminder |
|
||||
| `update(transform)` | the bedtime screen, on the application scope so leaving the screen cannot cut a write short | stores the settings, rewrites the rule if a field it carries changed, and when the schedule or the rule changed sets the mode to what it says now (on at 23:30 for a 23:00 bedtime starts it at once; a reminder edit leaves a hand-switched mode alone), arms the slot. The screen's writes start undispatched, so they queue on the engine's fair lock in the order they were made. Off removes the rule, which ends the mode, cancels the slot and clears the reminder |
|
||||
| `onSlotFired()` | `BedtimeReceiver` | follows any boundary crossed, posts a due reminder, arms the next event. A reminder fire alone crosses no boundary, so it leaves a mode switched on by hand alone |
|
||||
| `resync()` | `ClockulaApp.onCreate` (a force stop clears the slot), `SystemEventReceiver` (boot, app update, clock or zone change, exact-alarm permission) | creates the rule if it is missing, follows any boundary crossed, arms the slot |
|
||||
| `resync(refreshRule = true)` | Do Not Disturb access changing (the screen's `ON_RESUME` check and the broadcast), a backup restore | the same, but also rewrites the rule and re-asserts the mode's state |
|
||||
| `resync(refreshRule = true)` | Do Not Disturb access changing (the screen's `ON_RESUME` check and the broadcast), a backup restore | the same, but also rewrites the rule and re-asserts the mode's state. A restore re-runs it only if it got as far as applying settings |
|
||||
|
||||
"Follows any boundary crossed" is the one rule that lets a hand-switched mode
|
||||
coexist with a schedule. The last state Clockula set is persisted
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ generic advice: exact-alarm permission, notification permission, full-screen-int
|
||||
permission, battery-optimisation exemption, **whether DND currently blocks alarms**
|
||||
(read via `NotificationManager.getCurrentInterruptionFilter()`; the self-check never
|
||||
changes DND itself, it only reports what the user already has. The one place Clockula
|
||||
touches DND is the opt-in bedtime mode added after v1, which needs the user to grant
|
||||
touches DND is the opt-in bedtime mode (issue #1), which needs the user to grant
|
||||
`ACCESS_NOTIFICATION_POLICY` by hand and always lets alarms through; see
|
||||
`ARCHITECTURE.md` §18), whether the OEM has Clockula under an aggressive app-killer, and
|
||||
the next scheduled fire time as the system sees it (`getNextAlarmClock()`), compared
|
||||
|
||||
Reference in new issue
Block a user