fix(bedtime): switch a recreated rule, keep manual overrides, finish edits
A rule recreated by a pass (deleted in Settings, access re-granted) now gets its state set even when no boundary was crossed, and the applied state is recorded only once the system accepted it. Edits that can't move a boundary (reminder, effects) no longer re-assert the mode over a manual override, and the screen's writes run on the application scope so leaving right after a change can't cut it short. A late reminder counts the minutes actually left, and one slot fire reads the zone once. An equal bedtime and wake time is now no window instead of a day-long one, which on every night meant Do Not Disturb never ended, and an empty days mask in prefs reads as every night, as a backup's does. The rule-id extras are translated to the bedtime action in MainActivity, keeping the routing table keyed on the action alone. Refs #1
This commit is contained in:
1 parent
119197106b
commit
2dce78281a
14 files changed
+148
-67
No files matched your search
+12
-6
@@ -2728,8 +2728,9 @@ A rule needs an owner `ConditionProviderService` or a configuration activity.
|
||||
Clockula uses `MainActivity` as the configuration activity: it is already
|
||||
exported, so no new component is exposed. Settings opens it with the explicit
|
||||
component, the rule id in `NotificationManager.EXTRA_AUTOMATIC_RULE_ID` /
|
||||
`ConditionProviderService.EXTRA_RULE_ID`, and **no action**, so the presence of
|
||||
either extra is what makes the shell open the bedtime screen
|
||||
`ConditionProviderService.EXTRA_RULE_ID`, and **no action**, so `MainActivity`
|
||||
turns an action-less intent carrying either extra into the reminder's own
|
||||
`ACTION_SHOW_BEDTIME`, and the shell opens the bedtime screen
|
||||
(`ShellRequest.OpenBedtime`). There is no condition provider service:
|
||||
Clockula reports the rule's state itself with `setAutomaticZenRuleState`.
|
||||
|
||||
@@ -2769,14 +2770,15 @@ 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 a full day), resolved from local times and the
|
||||
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
|
||||
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 | stores the settings, rewrites the rule if a field it carries changed, sets the mode to what the schedule says now (on at 23:30 for a 23:00 bedtime starts it at once), 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 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 |
|
||||
| `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 |
|
||||
@@ -2785,12 +2787,16 @@ reminder and the next window's start.
|
||||
coexist with a schedule. The last state Clockula set is persisted
|
||||
(`bedtime_applied_active`, device state, not in the JSON backup), and a pass
|
||||
that is not an edit switches the mode only when the schedule now says
|
||||
something different. A launch in the afternoon leaves a mode the user turned
|
||||
something different, or when the rule was just recreated (a new rule starts
|
||||
off). The state is recorded only once the system accepted it, so a refused
|
||||
call is retried by the next pass. A launch in the afternoon leaves a mode the user turned
|
||||
on alone; a launch after a force stop that slept through the wake-up time
|
||||
turns it off. Each pass reads the clock **once**, so the mode's state and the
|
||||
next slot always agree about which side of a boundary "now" is on. A posted
|
||||
reminder is withdrawn by any pass once no coming bedtime is due within its
|
||||
lead, so moving the schedule away from it does not leave a stale one.
|
||||
lead, so moving the schedule away from it does not leave a stale one, and its
|
||||
title counts the minutes actually left, so a late fire does not promise the
|
||||
full lead.
|
||||
|
||||
Every bedtime call on a shared path runs **after** the alarm, timer and
|
||||
stopwatch passes and inside `runCatching` (in `SystemEventReceiver`, in its
|
||||
|
||||
Reference in new issue
Block a user