Privacy-Period-Tracker/app
null f43d580cc7 fix: make a reminder arrive when the user asked for it
Changing the reminder time did not move the reminder. WorkManager's
UPDATE policy carries the previous request's lastEnqueueTime and
periodCount forward, and a periodic request computes its next run as
periodCount == 0 ? lastEnqueueTime + initialDelay : lastEnqueueTime +
interval. Both halves bit:

After the first run, a new initial delay is ignored entirely -- Morning to
Evening did nothing at all. Before it, the delay is applied to the
ORIGINAL enqueue time, and the coordinator reschedules at every process
start, so asking for 19:00 at 09:00 on work enqueued at 08:00 produced
18:00, with every later period anchored off that.

The scheduler reads the existing work first: KEEP when nothing is
scheduled, leave an overdue run alone -- moving it skips today's reminder
entirely -- leave a run already within five minutes alone, and otherwise
UPDATE with an explicit setNextScheduleTimeOverride, which is the only way
to say WHEN rather than how long from a moment WorkManager has its own
opinion about. CANCEL_AND_REENQUEUE is wrong for a subtler reason: this
runs at every process start including the one WorkManager started to run
the worker, and cancelling the unique work there cancels the worker.

A time zone or clock change now re-aims it. The delay was computed once,
from the zone in force then, so flying east left the reminder arriving at
the old wall-clock time indefinitely. WorkManager's own RescheduleReceiver
declares BOOT_COMPLETED and nothing else -- which is why ClockChangeReceiver
exists for the other two broadcasts, and why it does not duplicate boot.
Unexported, no permission, checkPermissions still green.

No flex window was added, and the screen's copy changed instead. Flex
would have made "a few minutes either side" true and placed the first run
nearly a full period out, skipping the reminder on the day the user set
it -- to keep a sentence. It now says Android may deliver a few minutes
after, never before, which is what actually happens.

schedule() had no test; only the arithmetic beneath it did. Nine now,
against WorkManager's own recorded next-run time, sharing one clock with
it -- a test that fixes only the scheduler's measures a 2026 delay against
a real System.currentTimeMillis().

Writing them was necessary rather than tidy: the first version of the
change-the-time test passed with the defect still in place, because both
schedules happened at the same instant and the bug only bites once time
has moved. The test that catches it advances the clock an hour between
them, which is what a real second process start does.

closes #72

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 22:42:09 -05:00
..
src fix: make a reminder arrive when the user asked for it 2026-08-20 22:42:09 -05:00
build.gradle.kts fix: give every settings page a way out 2026-08-20 21:49:57 -05:00
proguard-rules.pro feat: guard §45's logging rules, and stop the leak that needed no log call 2026-08-18 22:01:33 -05:00