From c8cc156691cb399593fc2e6f46b2ca5c97d8c8e8 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Thu, 1 Oct 2026 17:22:07 +0200 Subject: [PATCH] docs: bring home-screen widgets into M10, out of post-v1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- docs/PLAN.md | 39 +++++++++++++++++++++++++++++++-------- docs/ROADMAP.md | 10 ++++++---- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/docs/PLAN.md b/docs/PLAN.md index ba0bd9f..9aed8bf 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -54,7 +54,7 @@ Agendula swap its whole storage posture without touching the UI. | # | 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. | -| 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. | | 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. | @@ -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 generic advice: exact-alarm permission, notification permission, full-screen-intent -permission, battery-optimisation exemption, DND policy access, whether the OEM has -Clockula under an aggressive app-killer, and the next scheduled fire time as the -system sees it (`getNextAlarmClock()`). Where possible each row deep-links to the -exact settings page. This screen is a v1 feature, not a support afterthought. +permission, battery-optimisation exemption, **whether DND currently blocks alarms** +(read via `NotificationManager.getCurrentInterruptionFilter()` — Clockula never +requests `ACCESS_NOTIFICATION_POLICY` or changes DND itself, it only reports what the +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 `{ "format": "clockula-backup", "version": 1, "exportedAt": …, "alarms": […], "timers": […], "worldClocks": […], "settings": {…} }`. The schema is **documented -in the repo**, versioned, and import is tolerant of unknown fields and strict -about known ones. Ringtone URIs are exported as-is with a documented fallback -when the target device can't resolve them. +in the repo** (`docs/BACKUP.md`), versioned, and import is tolerant of unknown +fields (ignored, at any level) and strict about known ones (a malformed known +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. +### 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 diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index de4a801..c13bd86 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -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, 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, 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) — 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 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 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. - **Bedtime / sleep schedule** — wind-down and wake, with DND handoff. A feature in its own right, realistically v2.