docs: bring home-screen widgets into M10, out of post-v1

Widgets share M10's machinery end to end: the next-alarm and timer
state a widget mirrors is exactly what the settings/backup/self-check
work already touches, and a widget tap is just another caller of the
MainActivity door the AlarmClock contract already opens. Keeping them
parked in post-v1 would mean building the same read paths twice.

QS tile, screensaver and bedtime stay deferred — none of them shares
M10's surface the way widgets do.

Also tightens PLAN.md §4's DND wording (interruption-filter read, no
ACCESS_NOTIFICATION_POLICY) and §7's backup semantics (whole-state
replace, ring state excluded, Room column vocabulary) ahead of M10's
implementation.
This commit is contained in:
2026-10-01 17:22:07 +02:00
parent d47220947b
commit c8cc156691
2 changed files with 37 additions and 12 deletions
+31 -8
View File
@@ -54,7 +54,7 @@ Agendula swap its whole storage posture without touching the UI.
| # | Decision | Why | | # | Decision | Why |
|---|---|---| |---|---|---|
| 1 | **Four surfaces in v1**: alarms, timers, stopwatch, world clock. | The complete stock-clock feature set. Anything less reads as a toy next to the app it wants to replace. | | 1 | **Four surfaces in v1**: alarms, timers, stopwatch, world clock. | The complete stock-clock feature set. Anything less reads as a toy next to the app it wants to replace. |
| 2 | **No extras in v1.** No widget, no QS tile, no screensaver, no bedtime. | v1 is already large. All four land in the roadmap as post-v1 milestones. Better a tight, finished v1 than five half-surfaces. | | 2 | **Home-screen widgets (next alarm, running timer, clock) are in v1, in M10.** No QS tile, no screensaver, no bedtime. | Widgets are the cheapest way to make the live pill's promise ("a running timer is never invisible") reach past the app itself, and M10 already touches every piece of state a widget reads. The other three stay out: v1 is already large, and none of them shares M10's machinery the way widgets do. |
| 3 | **Full `AlarmClock` intent contract** + next-alarm publishing via `setAlarmClock`. | §6. This is the thesis. | | 3 | **Full `AlarmClock` intent contract** + next-alarm publishing via `setAlarmClock`. | §6. This is the thesis. |
| 4 | **Room + DataStore + JSON export.** | Repeat rules, per-alarm overrides and lap history want a real schema. Prefs stay DataStore. Backup is an open documented format. | | 4 | **Room + DataStore + JSON export.** | Repeat rules, per-alarm overrides and lap history want a real schema. Prefs stay DataStore. Backup is an open documented format. |
| 5 | **Maximum alarm reliability**, including a self-check diagnostics screen. | §4. An alarm that doesn't ring is a dead app. This is the whole value proposition, not a nice-to-have. | | 5 | **Maximum alarm reliability**, including a self-check diagnostics screen. | §4. An alarm that doesn't ring is a dead app. This is the whole value proposition, not a nice-to-have. |
@@ -161,10 +161,13 @@ notification whose content intent is the ring activity.
A "**Why might my alarm not ring?**" screen that reports actual device state, not A "**Why might my alarm not ring?**" screen that reports actual device state, not
generic advice: exact-alarm permission, notification permission, full-screen-intent generic advice: exact-alarm permission, notification permission, full-screen-intent
permission, battery-optimisation exemption, DND policy access, whether the OEM has permission, battery-optimisation exemption, **whether DND currently blocks alarms**
Clockula under an aggressive app-killer, and the next scheduled fire time as the (read via `NotificationManager.getCurrentInterruptionFilter()` — Clockula never
system sees it (`getNextAlarmClock()`). Where possible each row deep-links to the requests `ACCESS_NOTIFICATION_POLICY` or changes DND itself, it only reports what the
exact settings page. This screen is a v1 feature, not a support afterthought. user already has), whether the OEM has Clockula under an aggressive app-killer, and
the next scheduled fire time as the system sees it (`getNextAlarmClock()`), compared
against the next fire Clockula itself computed. Where possible each row deep-links to
the exact settings page. This screen is a v1 feature, not a support afterthought.
--- ---
@@ -221,9 +224,18 @@ than writing anything. `SKIP_UI` never means "skip validation".
(`DocumentFile`), mirroring Agendula's export module shape. Top-level (`DocumentFile`), mirroring Agendula's export module shape. Top-level
`{ "format": "clockula-backup", "version": 1, "exportedAt": …, "alarms": […], `{ "format": "clockula-backup", "version": 1, "exportedAt": …, "alarms": […],
"timers": […], "worldClocks": […], "settings": {…} }`. The schema is **documented "timers": […], "worldClocks": […], "settings": {…} }`. The schema is **documented
in the repo**, versioned, and import is tolerant of unknown fields and strict in the repo** (`docs/BACKUP.md`), versioned, and import is tolerant of unknown
about known ones. Ringtone URIs are exported as-is with a documented fallback fields (ignored, at any level) and strict about known ones (a malformed known
when the target device can't resolve them. field rejects the whole file — nothing is imported half-way). Ringtone URIs are
exported as-is with a documented fallback when the target device can't resolve
them.
Import is **whole-state replacement**, not a merge: the user is shown exactly
that before confirming. Alarm and timer records carry only configuration — ring
state (`alarm_states`, a timer's running anchors) is never exported and never
touched by an import; an imported timer always lands `IDLE`. Record field names
mirror the Room column vocabulary (§5), so the schema, the exported Room schema
and the backup all read the same words.
--- ---
@@ -265,6 +277,17 @@ standing on its tab. The pill is not decoration; it is the fix.
Adaptive: navigation rail on wide layouts, per M3 adaptive guidance. Adaptive: navigation rail on wide layouts, per M3 adaptive guidance.
### Home-screen widgets (M10)
Three Jetpack Glance app widgets, each a read-only mirror of state that already
exists — no widget owns data: **next alarm** (day, time, label), **timer**
(the live pill's subject timer, same selection logic, with pause/resume/reset),
and **clock** (local time, growing to world clocks at larger sizes). Tapping a
widget opens the matching tab through the same `MainActivity` intents the
`AlarmClock` contract (§6) already uses — a widget is just another caller of
that door, not a second entry point. Refresh is event-driven (`updatePeriodMillis
= 0`): widgets update when the state they mirror changes, not on a timer.
--- ---
## 10. Repository & pipeline ## 10. Repository & pipeline
+6 -4
View File
@@ -586,13 +586,16 @@ next-alarm publishing. Hostile-input validation at the intent boundary.
hardware**, as no device was attached — the same caveat M5's seven, M6's four, hardware**, as no device was attached — the same caveat M5's seven, M6's four,
M7's four and M8's four carry. M7's four and M8's four carry.
### ⬜ M10 — Settings, backup, and the self-check ### ⬜ M10 — Settings, backup, the self-check, and widgets
- Settings composed from kit components: theme, dynamic colour, language, - Settings composed from kit components: theme, dynamic colour, language,
alarm/timer/clock defaults, about + crash reporting. alarm/timer/clock defaults, about + crash reporting.
- JSON backup export/import via SAF (`PLAN.md` §7), schema documented in the repo. - JSON backup export/import via SAF (`PLAN.md` §7), schema documented in
`docs/BACKUP.md`.
- The **"why might my alarm not ring?"** self-check screen (`PLAN.md` §4) — - The **"why might my alarm not ring?"** self-check screen (`PLAN.md` §4) —
real device state, deep links to the exact settings pages. real device state, deep links to the exact settings pages.
- **Tests:** backup round-trip and unknown-field tolerance. - Three Glance home-screen widgets — next alarm, timer, clock (`PLAN.md` §9).
- **Tests:** backup round-trip and unknown-field tolerance; self-check rule
logic per permission/state combination; widget model selection/formatting.
### ⬜ M11 — Release readiness ### ⬜ M11 — Release readiness
Translations wired to Weblate, fastlane metadata and screenshots, F-Droid Translations wired to Weblate, fastlane metadata and screenshots, F-Droid
@@ -608,7 +611,6 @@ Deferred deliberately, in rough priority order:
- **Dock / screensaver mode** — a `DreamService` full-screen clock. Cheapest big - **Dock / screensaver mode** — a `DreamService` full-screen clock. Cheapest big
win, and the surface people look at most. win, and the surface people look at most.
- **Glance home-screen widget** — next alarm and running timer.
- **Quick Settings tile** — timer control and next alarm from the shade. - **Quick Settings tile** — timer control and next alarm from the shade.
- **Bedtime / sleep schedule** — wind-down and wake, with DND handoff. A feature - **Bedtime / sleep schedule** — wind-down and wake, with DND handoff. A feature
in its own right, realistically v2. in its own right, realistically v2.