feat(widgets): next alarm, timer and clock home-screen widgets

Three Glance widgets, mirroring state the app already computes rather
than owning any of their own: the next alarm (AlarmEngine.upcoming()),
the live pill's subject timer (same selection logic, no ticker of its
own — a running countdown is the platform chronometer, exactly like
the ring notification), and the local time growing to world clocks at
larger sizes. WidgetSync collects the same read-only flows the shell
already reads and redraws on change, event-driven (updatePeriodMillis
= 0) — it touches no engine, only re-renders, and covers every write
path including SystemEventReceiver's since the process is already
alive whenever those run.

Tapping a widget reuses the same internal navigation actions the
AlarmClock contract's door already produces; the timer buttons send
the same unexported broadcasts its notification does. A widget is
just another caller of machinery that already exists.

ManifestRulesTest is updated deliberately: three GlanceAppWidgetReceivers
join the exported set, each pinned to exactly the platform-required
APPWIDGET_UPDATE filter and no permission — no new permission is
requested anywhere in this change.
This commit is contained in:
2026-10-01 22:32:07 +02:00
parent a11396b058
commit fb81bfbf2e
25 changed files with 1039 additions and 4 deletions
+9
View File
@@ -341,4 +341,13 @@
<string name="selfcheck_next_alarm_title">Next alarm, as the system sees it</string>
<string name="selfcheck_next_alarm_ok">Matches what Clockula scheduled</string>
<string name="selfcheck_next_alarm_problem">Doesn\'t match what Clockula scheduled — open the app to re-check</string>
<!-- M10: widgets -->
<string name="widget_next_alarm_description">Next alarm</string>
<string name="widget_next_alarm_empty">No alarms set</string>
<string name="widget_next_alarm_today">Today</string>
<string name="widget_timer_description">Timer</string>
<string name="widget_timer_new">New timer</string>
<string name="widget_timer_expired">Time\'s up</string>
<string name="widget_clock_description">Clock</string>
</resources>