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
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="110dp"
android:minHeight="60dp"
android:minResizeWidth="110dp"
android:minResizeHeight="40dp"
android:targetCellWidth="2"
android:targetCellHeight="2"
android:updatePeriodMillis="0"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:previewImage="@mipmap/ic_launcher"
android:description="@string/widget_timer_description" />