mirror of
https://github.com/kuhyx/wake-alarm.git
synced 2026-11-11 13:07:32 +01:00
Record the phone alarm verified end to end, by the user, on the Pixel
The dismiss path is no longer "covered by widget tests": the user ran it and confirmed it. tag discovered: 0465dab3ce2a81 on the ring screen, challenge solved, alarm silent. Records the four defects that only a hardware run could have found — the onPause reader-mode teardown, the cumulative step sensor that could never move off 0/25, the ON_LOCKED NFC gating, and the self-hiding flash challenge — and the two things still genuinely unverified: the QR scanner UI (which does not exist) and the locked-keyguard dismiss (implemented, never run to completion). Also records the process lesson, because it cost the most time here: after hardware confirms a path, the next change must be the smallest delta on that exact state, never a restructure bundled with a fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EckWmyfetYq3Mi8MAnUudh
This commit is contained in:
parent
a845cac883
commit
f53003ee4d
@ -20,7 +20,7 @@ starting; this file deliberately does not duplicate it.
|
||||
| 2 power button | **Done.** `_inhibit.py` (logind block, self-terminating, stale cleanup by pid via `/proc`) + `_alarm_session.py` fire-time record, re-fired by `_trigger` outside the catch-up window. |
|
||||
| 10 vmbox | **Done.** `scripts/vmbox/harness.sh` + `DOCS-vmbox.md`. 8 cases, fails closed. Found 2 live bugs the host could not reach. |
|
||||
| 5 curtains | **Done.** `_curtains.py` driver protocol + no-op default, called from `prepare_hardware()`. `DOCS-curtains-hardware.md` has the buy list. |
|
||||
| 1/4 phone alarm | **Done.** Five Kotlin files behind one MethodChannel + the Dart ring screen. The phone arms and rings its own alarm; no Clock-app confirmation. Verified on the API 36 AVD (screen Asleep→Awake, AlarmActivity over the lockscreen) and deployed to the Pixel 6a. |
|
||||
| 1/4 phone alarm | **Done, verified on the phone.** Five Kotlin files behind one MethodChannel + the Dart ring screen. Fires from Doze on time, wakes the screen over the lockscreen, rings through DND on STREAM_ALARM, and dismisses via an NFC tap + challenge. Confirmed by the user on the Pixel 6a, not inferred. |
|
||||
| 3 room proofs | **Mostly done.** NFC works end to end: `NfcReader.kt` (hand-written), Settings → "Room proof" registers the tag, and a tap satisfies the gate. Steps+elapsed is the fallback. QR is specified, persisted and unit-tested but has **no scanner UI** — `mobile_scanner` is the droppable extra. |
|
||||
|
||||
## Remaining, in order
|
||||
@ -35,47 +35,54 @@ starting; this file deliberately does not duplicate it.
|
||||
3. **Item 13, black screen.** Different repo (`~/testsAndMisc/
|
||||
linux_configuration`), host-only, blocks nothing.
|
||||
|
||||
### Measured on the Pixel 6a, 2026-08-27
|
||||
### Verified end to end on the Pixel 6a, 2026-08-27
|
||||
|
||||
**Verified for real:** the alarm fires from Doze on time (22:03:01 for a
|
||||
22:03 arm), wakes the screen (`Asleep`→`Awake`), puts `AlarmActivity` on top
|
||||
over the lockscreen, posts the full-screen-intent notification, and **rings
|
||||
through DND** — `zen_mode=1`, player `state:started` on
|
||||
`usage=USAGE_ALARM`/`STREAM_ALARM(4)`, `mutedState:none`. The STREAM_ALARM
|
||||
claim is no longer an assumption. NFC tag registration works end to end
|
||||
(`0465dab3ce2a81` via Settings → Room proof).
|
||||
**The whole path is confirmed on hardware, by the user, not inferred:**
|
||||
|
||||
**Still not verified: the actual dismiss.** Three real defects were found and
|
||||
fixed in the attempt (see `08b44b4`), but none of the fixes has been confirmed
|
||||
on hardware yet — the last test run ended before a successful tap. What needs
|
||||
one more run: register/confirm the tag, fire a ring, unlock at the keyguard
|
||||
prompt, tap the tag, solve the challenge, and confirm the sound stops **and**
|
||||
the screen closes.
|
||||
- Fires from Doze on time (22:03:01 for a 22:03 arm), registered by the system
|
||||
as `RTC_WAKEUP` / "Next wake from idle".
|
||||
- Wakes the screen (`Asleep`→`Awake`) and puts `AlarmActivity` on top over the
|
||||
lockscreen, with the full-screen-intent notification posted.
|
||||
- **Rings through DND** — `zen_mode=1`, player `state:started` on
|
||||
`usage=USAGE_ALARM`/`STREAM_ALARM(4)`, `mutedState:none`. The STREAM_ALARM
|
||||
claim is measured, no longer assumed.
|
||||
- NFC tag registers (Settings → Room proof) and **a tap dismisses**:
|
||||
`tag discovered: 0465dab3ce2a81` on the ring screen, challenge solved,
|
||||
alarm silent.
|
||||
- Step counter reaches the gate.
|
||||
|
||||
**`requestDismissKeyguard` does not silently unlock a secured phone.** It
|
||||
raises the PIN/biometric prompt and returns to `ON_LOCKED` until the user
|
||||
answers, so the NFC tap cannot work before that point. That is the agreed
|
||||
behaviour, not a bug — but it means "tap the tag without touching the phone"
|
||||
was never achievable on a secured device, and the docs should not imply it.
|
||||
**Four defects were found only because it was run on the phone**, every one
|
||||
invisible to the emulator (no NFC, no step sensor) and to the widget tests
|
||||
(which mock the channel):
|
||||
|
||||
### Not yet verified on the phone
|
||||
1. `AlarmActivity.onPause` called `NfcReader.stop()`. `enableReaderMode` is
|
||||
per-activity but `disableReaderMode` is global, so anything briefly in
|
||||
front of the ring screen killed polling for the rest of the ring.
|
||||
2. `TYPE_STEP_COUNTER` is cumulative and on-change: it emits nothing until the
|
||||
user has already walked, and the first emission was being eaten as the
|
||||
baseline, so the screen sat at `0/25` forever. `TYPE_STEP_DETECTOR` is now
|
||||
primary — one event per stride, no baseline to miss.
|
||||
3. NFC does not poll while the ring shows over a locked keyguard
|
||||
(`mScreenState=ON_LOCKED`). `requestDismissKeyguard()` is called on fire.
|
||||
It does **not** silently unlock a secured phone — it raises the PIN prompt
|
||||
— so "tap without touching the phone" was never achievable on a secured
|
||||
device. Say that plainly; don't let docs imply otherwise.
|
||||
4. The **flash** challenge hides its code after 4s, which is unsolvable when
|
||||
the screen is reached by walking to another room. Removed from the phone's
|
||||
rotation, with a test asserting no self-hiding challenge is ever shown.
|
||||
|
||||
The ring itself has only been fired on the API 36 AVD. On the Pixel 6a the
|
||||
build installs and the runtime permission prompts appear, but **an actual
|
||||
alarm has never rung on it** — that needs an alarm armed through the picker
|
||||
(which needs a sync backend connected) and a wait to the fire instant. Ring
|
||||
with **DND on**, since "STREAM_ALARM ignores DND" is the load-bearing claim
|
||||
and has not been observed on hardware.
|
||||
**A process lesson worth more than any of them:** after hardware confirmed the
|
||||
path worked, the next change bundled a MethodChannel restructure with a bug
|
||||
fix and regressed both NFC and steps. The user caught it. When hardware has
|
||||
just gone green, make the smallest possible delta on top of *that exact state*
|
||||
— never a restructure and a fix together.
|
||||
|
||||
The **dismiss path** has never run on any device either: the AVD has neither a
|
||||
step sensor nor NFC, so the room gate correctly refuses to open there. It is
|
||||
covered by widget tests (NFC tap → challenge → `dismiss` + `closeRingScreen`),
|
||||
which is weaker than a real tap on a real tag. Register a tag via Settings →
|
||||
"Room proof" and dismiss a real ring before calling item 3 finished.
|
||||
### Still unverified
|
||||
|
||||
**Mute the host before firing a ring on the emulator.** The AVD routes
|
||||
`STREAM_ALARM` to the PC's speakers, and `raiseAlarmVolume()` sets it to max —
|
||||
this went off out loud during the session (2026-08-27).
|
||||
- The **QR** proof has no scanner UI (`mobile_scanner`); `checkQr` and its
|
||||
persistence are unit-tested only.
|
||||
- The **locked-keyguard** dismiss was not run to completion: the confirmed run
|
||||
was on an unlocked phone. The PIN-prompt path is implemented but unproven.
|
||||
|
||||
## Decisions already made — do not re-litigate
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user