docs: reconcile USB, Waydroid, audio and charging
This commit is contained in:
parent
71f6ce591e
commit
4aa61d735c
9 changed files with 357 additions and 50 deletions
105
PAF/README.md
105
PAF/README.md
|
|
@ -1,10 +1,67 @@
|
||||||
# PAF — Pixel 3 (blueline) Arch Architecture Framework
|
# PAF — Pixel 3 (blueline) architecture
|
||||||
|
|
||||||
The single living spine for this port. Migrated 2026-07-10 from the pmOS
|
The single living spine for the phone. It began in the pmOS project, moved to
|
||||||
project and modernized; fully self-contained — the old location is
|
Pixel3Arch in July, and was copied here on 2026-07-24 without completing the
|
||||||
disposable. Doctrine unchanged: **update the relevant layer in place**,
|
move. SouveraineOS became canonical on 2026-08-07; device code remains in
|
||||||
never append another dated handoff. Dated docs are evidence, the spine is
|
`../../Pixel3Arch/`.
|
||||||
what you read first.
|
|
||||||
|
**Update the relevant layer in place.** Dated captures are evidence, not a
|
||||||
|
second spine. Git holds the old arrangements: SouveraineOS `72aaa53` is the
|
||||||
|
July import; Pixel3Arch `9b1afd1` is the last full in-repo PAF snapshot.
|
||||||
|
|
||||||
|
## Start here — "I want to work on my phone"
|
||||||
|
|
||||||
|
The six things you need before any of the layer docs below matter.
|
||||||
|
|
||||||
|
**Where it is.** `10.10.20.234` over WiFi (stable since 2026-07-20; the MAC is
|
||||||
|
pinned, so it does not drift the way this doc used to claim). `172.16.42.1`
|
||||||
|
over USB, which is the fallback when WiFi is wedged.
|
||||||
|
|
||||||
|
ssh -i ~/.ssh/ani casey@10.10.20.234
|
||||||
|
|
||||||
|
**What it runs.** Souveraine OS — Arch Linux ARM, systemd, pacman, bash. Our
|
||||||
|
own kernel (`uname -r` → `7.1.1-sdm845-g<hash>`; the hash is ground truth for
|
||||||
|
what is actually booted). Slot A is ours, slot B is LineageOS and is the
|
||||||
|
fallback — never touch it. `casey` has passwordless sudo.
|
||||||
|
|
||||||
|
**Where things get built.** Never here, and never on the laptop:
|
||||||
|
ArchDev, `casey@10.10.20.123`, same key. The phone has 3.5 GB of RAM and is the
|
||||||
|
daily driver; the laptop is for device ops only. This holds for `cargo test`
|
||||||
|
and `cargo clippy` too, not just release builds.
|
||||||
|
|
||||||
|
**How it updates.** `sudo pacman -Syu`. Everything we build ships as a signed
|
||||||
|
package — kernel included. Reaching for fastboot because a kernel changed is a
|
||||||
|
regression, not a fallback; see `../START-HERE.md` and
|
||||||
|
`../../Pixel3Arch/CLAUDE.md` for the few real reasons to flash. COLD boots only
|
||||||
|
(a warm reboot poisons TZ/remoteproc), and reboots are Casey's, at the device.
|
||||||
|
|
||||||
|
**When it will not answer.** Two failures look identical (ping works, ssh
|
||||||
|
hangs) and both are routing, not the phone:
|
||||||
|
- *USB:* networkd matches `Name=usb*`, so a stale down `usb0` and the live
|
||||||
|
`usb1` both hold 172.16.42.1 and replies leave by the dead one.
|
||||||
|
`sudo ip addr flush dev usb0`, and on the laptop
|
||||||
|
`sudo ip neigh del 172.16.42.1 dev <iface>` if the MAC looks wrong.
|
||||||
|
- *WiFi:* ath10k_snoc wedges with auth timeouts — reload the module, then
|
||||||
|
`systemctl restart wpa_supplicant`.
|
||||||
|
|
||||||
|
**Work that started on the phone.** This is the one with no tooling, so it is
|
||||||
|
the one that bites. Things get hacked on-device and then live only there —
|
||||||
|
`~/stevia-pkg` was four pkgrels deep before any of it came back. To find it:
|
||||||
|
|
||||||
|
ssh -i ~/.ssh/ani casey@10.10.20.234 'ls -lt ~ | head -20'
|
||||||
|
pacman -Qm # foreign packages — built here, owned by nobody upstream
|
||||||
|
pacman -Qo /usr/bin/<x> # "No package owns" = it was hand-copied
|
||||||
|
|
||||||
|
Finishing it means three steps, in order, and the middle one is the one that
|
||||||
|
gets skipped: **merge it back** into `../../Pixel3Arch/pkgs/<name>/` (the repo
|
||||||
|
copy may have moved too — diff both ways, they can both claim the same pkgrel),
|
||||||
|
**build it on ArchDev** (`CARCH=aarch64 makepkg -f --ignorearch --nodeps`;
|
||||||
|
`../../Pixel3Arch/pkgs/stevia` is the worked cross example), then **install the
|
||||||
|
built package** rather than the on-device one. A thing that only exists on the
|
||||||
|
phone is one reflash from gone, and `../../Pixel3Arch/rootfs-overlay/` only
|
||||||
|
reaches a device at provision time — which is TASK-27's whole subject.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
- **[platform.md](platform.md)** — hardware map, live partition layout,
|
- **[platform.md](platform.md)** — hardware map, live partition layout,
|
||||||
reaching the phone, boot chain, recovery.
|
reaching the phone, boot chain, recovery.
|
||||||
|
|
@ -16,19 +73,21 @@ what you read first.
|
||||||
telemetry, the tap-to-wake/SLPI handoff goal.
|
telemetry, the tap-to-wake/SLPI handoff goal.
|
||||||
- **[slpi.md](slpi.md)** — sensor island: the five-fix bring-up chain and
|
- **[slpi.md](slpi.md)** — sensor island: the five-fix bring-up chain and
|
||||||
the `sar.cc:27` wall. Arch status header + pmOS-era record.
|
the `sar.cc:27` wall. Arch status header + pmOS-era record.
|
||||||
- **[audio.md](audio.md)** — WCD9340/SLIMbus audio state: working speaker
|
- **[audio.md](audio.md)** — WCD9340/SLIMbus audio: working HiFi speaker and
|
||||||
path, verified zero-capture transport state, and the current mic frontier.
|
microphone profiles, working two-way calls, and the lifecycle archaeology.
|
||||||
|
- **[edge-sense.md](edge-sense.md)** — Active Edge force path, calibration,
|
||||||
|
sessiond gating, and the remaining doze gap.
|
||||||
- **[modem.md](modem.md)** — WORKING on Arch. Status header + the full
|
- **[modem.md](modem.md)** — WORKING on Arch. Status header + the full
|
||||||
52-wall research record (modemsmem root cause).
|
52-wall research record (modemsmem root cause).
|
||||||
- **[evidence/](evidence/)** — the dated capture/research docs the spine
|
- **[evidence/](evidence/)** — dated capture/research docs the spine cites:
|
||||||
cites (modem/qcril/TZ archaeology, pmOS-era platform/build/README
|
audio handoffs under `evidence/audio/`, power handoffs under
|
||||||
snapshots, diag captures). Read-only history; never update these.
|
`evidence/power/`, plus modem/QCRIL/TZ archaeology and pmOS-era snapshots.
|
||||||
|
Read-only history; amend the living layer doc instead.
|
||||||
|
|
||||||
Related in-repo: `../CLAUDE.md` (project doctrine + session resume state),
|
Related: `../START-HERE.md` for triage, `../docs/tasks/` for live work, and
|
||||||
`../docs/tasks/` (per-subsystem task scopes; auto-rotate-task.md is the
|
`../../Pixel3Arch/` for kernel, packages, overlays, and device tooling.
|
||||||
live SLPI log), `../docs/phone-shell-ux.md` (Hyprland/Quickshell layer).
|
|
||||||
|
|
||||||
## Status at a glance (2026-07-11)
|
## Status at a glance (reconciled 2026-08-07)
|
||||||
|
|
||||||
| Layer | State |
|
| Layer | State |
|
||||||
|---|---|
|
|---|---|
|
||||||
|
|
@ -38,13 +97,15 @@ live SLPI log), `../docs/phone-shell-ux.md` (Hyprland/Quickshell layer).
|
||||||
| Modem / RF (LTE data) | 🟢 WORKING on Arch — mmcli connected, LTE, Fido, clat up (verified live 2026-07-10) |
|
| Modem / RF (LTE data) | 🟢 WORKING on Arch — mmcli connected, LTE, Fido, clat up (verified live 2026-07-10) |
|
||||||
| WiFi (ath10k_snoc) | 🟢 True unplugged cold boot verified 2026-07-11: no `rejected:90`, associates, gets DHCP, and reaches gateway + Internet. `failed to install key … -110` still occurs during association/roam but did not break connectivity; `cryptmode=1` remains a fallback only if it does. |
|
| WiFi (ath10k_snoc) | 🟢 True unplugged cold boot verified 2026-07-11: no `rejected:90`, associates, gets DHCP, and reaches gateway + Internet. `failed to install key … -110` still occurs during association/roam but did not break connectivity; `cryptmode=1` remains a fallback only if it does. |
|
||||||
| Bluetooth (bluetoothd) | 🟢 WORKING 2026-07-10: controller was invisible because WCN3990 ships no BD address (kernel leaves hci0 unconfigured) — blueline-bt-bdaddr.service sets a persisted one; live scan verified |
|
| Bluetooth (bluetoothd) | 🟢 WORKING 2026-07-10: controller was invisible because WCN3990 ships no BD address (kernel leaves hci0 unconfigured) — blueline-bt-bdaddr.service sets a persisted one; live scan verified |
|
||||||
|
| USB device / KVM | 🟠 Full GUD + HID + NCM + smoo composite builds on ArchDev with transactional rollback and a sessiond-owned power-sheet verb. Not installed on glass yet: the phone still runs usb-signaller 0.3.1-3 and has no smoo package — see `../USB/README.md` and TASK-62. |
|
||||||
| SLPI sensor island | 🟢 `sar.cc` fatal is gone (regression, not a real limit) — `iio-sensor-proxy` runs always-on via `blueline-sensors-enable.service` (After=blueline-hexagonrpcd-sdsp), no more on-demand start/stop. Proximity (TMD2725) and accelerometer both live — see slpi.md |
|
| SLPI sensor island | 🟢 `sar.cc` fatal is gone (regression, not a real limit) — `iio-sensor-proxy` runs always-on via `blueline-sensors-enable.service` (After=blueline-hexagonrpcd-sdsp), no more on-demand start/stop. Proximity (TMD2725) and accelerometer both live — see slpi.md |
|
||||||
| Tap-to-wake | 🟠 AP-side gesture mode detects DBLTAP and delivers wake, but the current screen-toggle path can half-wake on the first tap. DT2W now gates on proximity — `blueline-screen-toggle on` checks `ProximityNear` over D-Bus and suppresses the wake if blocked (phone in pocket). The SLPI gesture-nanoapp path is unblocked by the sar.cc fix but not required for AP-side DT2W. |
|
| Tap-to-wake | 🟠 AP-side gesture mode detects DBLTAP and delivers wake, but the current screen-toggle path can half-wake on the first tap. DT2W now gates on proximity — `blueline-screen-toggle on` checks `ProximityNear` over D-Bus and suppresses the wake if blocked (phone in pocket). The SLPI gesture-nanoapp path is unblocked by the sar.cc fix but not required for AP-side DT2W. |
|
||||||
| Audio | 🟠 SPEAKERS WORK end-to-end 2026-07-10 (pipewire→UCM→QUAT_TDM→CS35L36). Mic capture is verified all-zero despite a live Q6 SLIMBUS_0_TX start, correct TX7/TX8 map and WCD interface-port configuration. IFD `0x097` remains `00` (Android capture has `21`; direct debugfs write does not stick); cause unproven — see audio.md |
|
| Audio | 🟢 WORKING. PipeWire/WirePlumber exposes the HiFi speaker and microphone; Casey uses the mic for STT. The Voice Call profile carries real two-way calls, with earpiece/speaker switching handled by `blueline-callaudio-hook` — see audio.md. |
|
||||||
| Camera / NFC / haptics / fingerprint | ⚪ parked — task scopes in ../docs/tasks/ |
|
| Active Edge (squeeze) | 🟢 WORKING 2026-07-28 — force detected (2502-2990 deflection) after the rail became a DT gpio-hog; producer packaged, enabled, and gated through sessiond's pocket veto. No detection while the AP sleeps — see edge-sense.md |
|
||||||
|
| Fingerprint (FPC1020) | 🟠 driver written and building 2026-08-01 — `drivers/input/misc/fpc1020.c` on branch `fingerprint-fpc1020`, reset gpio7 / IRQ gpio121 verified against this unit's DTBO, reports `KEY_WAKEUP`. **Never run on the device.** Electrical half only; capture/matching are a TrustZone app we do not load — see TASK-44 |
|
||||||
|
| Camera | 🟠 Front IMX355 streams real frames. Rear IMX363 DT exists but remains unbuilt — see TASK-46. |
|
||||||
|
| NFC / haptics | ⚪ Open — see TASK-45 and the live task index. |
|
||||||
|
|
||||||
**One-line state:** daily-driver Arch on slot A with LTE, WiFi, BT, speaker
|
**One-line state:** daily-driver Arch on slot A with LTE, WiFi, Bluetooth,
|
||||||
audio, working daytime touch, and an on-demand SSC client. Current reliability
|
speaker/microphone/call audio, daytime touch, Active Edge, always-on sensors,
|
||||||
work is the libssc-triggered wake lockup plus green/half-wake display behavior;
|
and a working front camera. Android (LOS) remains intact on slot B.
|
||||||
microphone capture remains the audio wall. Android (LOS) is intact on slot B as
|
|
||||||
fallback.
|
|
||||||
|
|
|
||||||
98
PAF/audio.md
98
PAF/audio.md
|
|
@ -1,5 +1,35 @@
|
||||||
# Audio — WCD9340 / SLIMbus
|
# Audio — WCD9340 / SLIMbus
|
||||||
|
|
||||||
|
## Current — 2026-08-07
|
||||||
|
|
||||||
|
This is a working phone audio stack, not an active microphone bring-up.
|
||||||
|
|
||||||
|
- **Runtime:** PipeWire + WirePlumber + pipewire-pulse + pipewire-alsa. Native
|
||||||
|
PulseAudio and the ABI-provider shims are historical experiments, not the
|
||||||
|
running authority.
|
||||||
|
- **HiFi:** both CS35L36 speakers play; the WCD9340 microphone captures clean
|
||||||
|
mono audio through DMIC4 → DEC5/TX5. Casey uses it regularly for STT.
|
||||||
|
- **Calls:** the `Voice Call` UCM profile, `souveraine-callaudio`,
|
||||||
|
`souveraine-q6voiced`, and `souveraine-callaudiod` carry real two-way calls
|
||||||
|
and the earpiece/speaker path.
|
||||||
|
- **Persistence:** WirePlumber restores volumes and the selected profile. Do
|
||||||
|
not add another volume writer; role policy remains TASK-39.
|
||||||
|
- **One hardware debt remains:** the kernel permanently holds codec sysclk and
|
||||||
|
MICB2 from probe. Audio works, but the hold costs idle power and blocks a
|
||||||
|
clean suspend story. TASK-07 owns removing it.
|
||||||
|
|
||||||
|
The July **“UN-PIN TEST PASSED”** below removed the userspace always-open mic
|
||||||
|
pin. It did **not** remove kernel commit `cd7758eae`'s sysclk + MICB2 hold; that
|
||||||
|
similar noun is the likely source of the remembered “we resolved it.”
|
||||||
|
|
||||||
|
The implementation lives in Pixel3Arch under `pkgs/souveraine-ucm-blueline`,
|
||||||
|
`pkgs/blueline-callaudio` (package name `souveraine-callaudio`),
|
||||||
|
`pkgs/souveraine-callaudiod`, and `pkgs/q6voiced` (package name
|
||||||
|
`souveraine-q6voiced`).
|
||||||
|
|
||||||
|
Everything below is the evidence ledger. Headings such as “still open” describe
|
||||||
|
the date beneath them unless the current block above repeats the defect.
|
||||||
|
|
||||||
## PIPEWIRE RESTORED — 2026-07-19 late evening
|
## PIPEWIRE RESTORED — 2026-07-19 late evening
|
||||||
|
|
||||||
The PA-native arrangement is retired. Live state, all verified on-device:
|
The PA-native arrangement is retired. Live state, all verified on-device:
|
||||||
|
|
@ -36,12 +66,58 @@ The PA-native arrangement is retired. Live state, all verified on-device:
|
||||||
the voice BE routes (`SLIMBUS_0_RX Voice Mixer VoiceMMode1`,
|
the voice BE routes (`SLIMBUS_0_RX Voice Mixer VoiceMMode1`,
|
||||||
`VoiceMMode1 Capture Mixer SLIMBUS_0_TX`) are applied — DPCM
|
`VoiceMMode1 Capture Mixer SLIMBUS_0_TX`) are applied — DPCM
|
||||||
no-backend rejection. With routes applied the PCM opens. This is why
|
no-backend rejection. With routes applied the PCM opens. This is why
|
||||||
q6voiced logged "Failed to open tx/rx: Invalid argument". Because the
|
q6voiced logged "Failed to open tx/rx: Invalid argument". ~~Because the
|
||||||
PCM is unprobeable, ACP can never synthesize a VoiceCall profile, so
|
PCM is unprobeable, ACP can never synthesize a VoiceCall profile, so
|
||||||
callaudiod's profile-switching path is structurally dead on this card.
|
callaudiod's profile-switching path is structurally dead on this card.~~
|
||||||
Shipped `blueline-callaudio-hook` (system service): MM `CallAdded` →
|
**Wrong — see 2026-07-29.** ACP never probes `hw:0,2`; it probes the PCMs
|
||||||
UCM VoiceCall verb, last `CallDeleted` → HiFi verb restore. q6voiced
|
the verb *declares*, and the profile was lost for two reasons of our own
|
||||||
then opens an already-routed PCM. Real two-way call test pending.
|
making. Shipped `blueline-callaudio-hook` (system service): MM `CallAdded`
|
||||||
|
→ UCM voice verb, last call terminating → HiFi verb restore. q6voiced then
|
||||||
|
opens an already-routed PCM.
|
||||||
|
|
||||||
|
## PHONE CALLS WORK — TWO-WAY AUDIO ON A REAL BEARER — 2026-07-29
|
||||||
|
|
||||||
|
Incoming call, answered, audio both directions, confirmed by ear at both ends.
|
||||||
|
Five defects had to fall, every one of them ours:
|
||||||
|
|
||||||
|
- **Verb named `VoiceCall`.** alsa-lib's `SND_USE_CASE_VERB_VOICECALL` is
|
||||||
|
`"Voice Call"`, with the space, and callaudiod accepts only a profile
|
||||||
|
carrying that prefix (`cad-pulse.c:508`). Renamed.
|
||||||
|
- **The voice verb gave MultiMedia1 no backend.** HiFi routes it through
|
||||||
|
`QUAT_TDM_RX_0`; the voice verb routed nothing, so opening `hw:0,0` under
|
||||||
|
the verb returned -EINVAL and ACP dropped the profile — *"Profile 'Voice
|
||||||
|
Call' mapping 'Voice Call: Speaker: sink': output PCM open failed"*,
|
||||||
|
`spa-acp-tool -v -v`. That, not an unprobeable `hw:0,2`, is why no voice
|
||||||
|
profile ever appeared. The card carries one now.
|
||||||
|
- **Downlink went to `SLIMBUS_0_RX`.** blueline's earpiece and loudspeaker are
|
||||||
|
both CS35L36 amps on `QUAT_TDM_RX_0`; the WCD9340 is the uplink and the
|
||||||
|
headset jack. Voice sent to the codec reached nothing — audible as a call
|
||||||
|
the far end heard perfectly while this end heard silence.
|
||||||
|
- **A front-end takes exactly one backend.** These mixers are *not* additive:
|
||||||
|
enabling a second silently clears the first, measured in both directions.
|
||||||
|
Setting `QUAT` and `SLIMBUS` together is not belt-and-braces, it is a no-op.
|
||||||
|
- **q6voiced latches a failed open.** tinyalsa's `pcm_open()` returns a
|
||||||
|
non-NULL handle on failure and `q6voiced_open()` guards on `if (v->tx)`, so
|
||||||
|
one lost race silences the whole call. Reachable on any outgoing call:
|
||||||
|
`mm_state_is_active()` counts DIALING, emitted in the same instant as
|
||||||
|
`CallAdded`. Incoming calls are safe only by accident — RINGING_IN is not
|
||||||
|
counted active, so their open lands well after the routes. Patched in
|
||||||
|
`souveraine-q6voiced` to release and retry.
|
||||||
|
|
||||||
|
Two further findings:
|
||||||
|
|
||||||
|
- **The mic died after every call**, not just occasionally. `alsaucm` holds its
|
||||||
|
UCM context in-process, so a one-shot `set _verb HiFi` has no previous verb
|
||||||
|
to dismantle and never runs its `DisableSequence`. TX5 and TX7 both stayed
|
||||||
|
mapped into `AIF1_CAP`, SLIM_0_TX carried two channels into a mono front-end,
|
||||||
|
and capture read exact zeros. The hook now unmaps the outgoing leg explicitly.
|
||||||
|
- **callaudiod cannot own earpiece/speaker on this card.** It switches a sink
|
||||||
|
*port* (`cad-pulse.c:961`) and needs both port types on one sink, but ACP
|
||||||
|
models UCM devices as one profile per combination — `Voice Call (Earpiece,
|
||||||
|
Mic)` and `Voice Call (Mic, Speaker)`. `ConflictingDevices` does not change
|
||||||
|
it. enchilada sidesteps this by giving each transducer its own PCM; blueline
|
||||||
|
has both amps behind one. The toggle is therefore
|
||||||
|
`blueline-callaudio-hook speaker on|off`, writing the amps directly.
|
||||||
|
|
||||||
## ROOT CAUSE FOUND AND FIXED — MICS CAPTURE REAL AUDIO — 2026-07-19
|
## ROOT CAUSE FOUND AND FIXED — MICS CAPTURE REAL AUDIO — 2026-07-19
|
||||||
|
|
||||||
|
|
@ -90,7 +166,7 @@ kexecs `/boot/vmlinuz-blueline` + `/boot/dtbs/sdm845-google-blueline.dtb` per
|
||||||
live chosen node). Flashing boot_a via fastboot does NOT change the running
|
live chosen node). Flashing boot_a via fastboot does NOT change the running
|
||||||
kernel/DTB — install to `/boot` on the rootfs instead.
|
kernel/DTB — install to `/boot` on the rootfs instead.
|
||||||
|
|
||||||
### Still open — capture intermittency (the remaining bug)
|
### Then-open capture intermittency — superseded later on 2026-07-19
|
||||||
- Ordering effect observed on the first post-fix boot: DMIC3/4 through
|
- Ordering effect observed on the first post-fix boot: DMIC3/4 through
|
||||||
MUX6/MUX7 read zero until the DEC5/DEC6 (Android-native) routes ran once;
|
MUX6/MUX7 read zero until the DEC5/DEC6 (Android-native) routes ran once;
|
||||||
after that, the previously-dead MUX7+DMIC4 handset route worked. Some
|
after that, the previously-dead MUX7+DMIC4 handset route worked. Some
|
||||||
|
|
@ -561,7 +637,7 @@ returned `0` and the audio data was still all zero.
|
||||||
- This work did not start `iio-sensor-proxy`. There is no evidence that the
|
- This work did not start `iio-sensor-proxy`. There is no evidence that the
|
||||||
sensor-client HACK or SLPI wake-lockup mechanism gates this audio path.
|
sensor-client HACK or SLPI wake-lockup mechanism gates this audio path.
|
||||||
|
|
||||||
## Verified capture path
|
## Verified zero-capture path — historical 2026-07-11
|
||||||
|
|
||||||
The controlled route is Android's documented handset/endfire pair:
|
The controlled route is Android's documented handset/endfire pair:
|
||||||
|
|
||||||
|
|
@ -600,14 +676,14 @@ The controlled route is Android's documented handset/endfire pair:
|
||||||
- This is **not** a missing FE-to-BE connection: runtime ASoC state reports
|
- This is **not** a missing FE-to-BE connection: runtime ASoC state reports
|
||||||
`MultiMedia2 Capture: start` with `SLIM Capture 1: start` as its active
|
`MultiMedia2 Capture: start` with `SLIM Capture 1: start` as its active
|
||||||
backend, and the codec's AIF/decimator event callbacks run. With the CDC
|
backend, and the codec's AIF/decimator event callbacks run. With the CDC
|
||||||
muxes selected, the DMIC callbacks run too; the remaining wall is after the
|
muxes selected, the DMIC callbacks run too; the unresolved point at that
|
||||||
fully powered codec capture path.
|
date was after the fully powered codec capture path.
|
||||||
- Reducing the route to the downstream-style single TX7/DMIC4 channel did not
|
- Reducing the route to the downstream-style single TX7/DMIC4 channel did not
|
||||||
change the result: a four-second `hw:0,1` mono capture contained 192,000
|
change the result: a four-second `hw:0,1` mono capture contained 192,000
|
||||||
zero samples. Channel count/configuration is therefore not the activation
|
zero samples. Channel count/configuration is therefore not the activation
|
||||||
trigger.
|
trigger.
|
||||||
|
|
||||||
## What the evidence does and does not say
|
## What the 2026-07-11 evidence did and did not say
|
||||||
|
|
||||||
Android's captured recording state has IFD `0x097=21`; mainline reads `00`.
|
Android's captured recording state has IFD `0x097=21`; mainline reads `00`.
|
||||||
During a five-second live TX7/TX8 capture, writing `0097 21` through the
|
During a five-second live TX7/TX8 capture, writing `0097 21` through the
|
||||||
|
|
@ -623,7 +699,7 @@ unconstrained map three channels (`0x86`, `0x87`, `0x88`), while disabling it
|
||||||
produces the correct TX7/TX8 pair above. That is a real UCM/machine-routing
|
produces the correct TX7/TX8 pair above. That is a real UCM/machine-routing
|
||||||
cleanup item, but it did not restore capture and is not the root cause.
|
cleanup item, but it did not restore capture and is not the root cause.
|
||||||
|
|
||||||
## Next narrow work
|
## Proposed next work on 2026-07-11 — superseded
|
||||||
|
|
||||||
1. Capture the working Android interface-device transition, or find the
|
1. Capture the working Android interface-device transition, or find the
|
||||||
downstream owner/meaning of IFD `0x097`; compare the actual write sequence,
|
downstream owner/meaning of IFD `0x097`; compare the actual write sequence,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,29 @@
|
||||||
# USB — the Pixel 3 as a KVM device
|
# USB — the Pixel 3 as a KVM device
|
||||||
|
|
||||||
**Exploration opened 2026-08-04** from Casey: "start exploring the notion of
|
## Current — 2026-08-07
|
||||||
KVM from this thing." This folder holds USB-related design and measurement;
|
|
||||||
the KVM exploration starts here.
|
|
||||||
|
|
||||||
## What exists, measured on the phone (2026-08-04)
|
The direction is settled: another computer sends its display **into** the
|
||||||
|
phone over GUD; the phone returns keyboard, pointer and touch as boot HID.
|
||||||
|
The same composite keeps NCM for control and carries a smoo FunctionFS
|
||||||
|
responder for host-backed storage. This is not the earlier UVC/VNC sketch.
|
||||||
|
|
||||||
|
| Piece | Current state |
|
||||||
|
|---|---|
|
||||||
|
| Display in | `souveraine-usb-kvm`: GUD FunctionFS responder, RGB565 surface on Wayland |
|
||||||
|
| Hands back | Boot keyboard + relative pointer; window keyboard, mouse and touch become HID reports |
|
||||||
|
| Storage | `smoo-gadget` FunctionFS responder; `ublk_drv` on the phone |
|
||||||
|
| Control link | NCM remains in the composite |
|
||||||
|
| Mode owner | `usb-signaller` exposes `kvm_mode`; GUD and smoo readiness gate the bind, and failure restores the prior mode |
|
||||||
|
| Human/agent surface | `sessiond` owns the audited `usb` / `set_usb_mode` verbs; held-power **Power Options** exposes HID and full KVM |
|
||||||
|
| Canonical source | receiver/session/UI/package in `~/Projects/souveraine`; device mechanism in `~/Projects/usb-signaller`; package recipes in Pixel3Arch |
|
||||||
|
| Build proof | full ARM64 release receiver and sessiond built on ArchDev; receiver tests + strict Clippy pass |
|
||||||
|
| Phone | **Not installed yet.** Live phone still has `usb-signaller 0.3.1-3`, no `smoo`, and advertises no HID/KVM mode |
|
||||||
|
|
||||||
|
TASK-62 owns the package and glass landing. The material below is the
|
||||||
|
2026-08-04 exploration ledger; it remains useful for host mode and for why the
|
||||||
|
discarded UVC/VNC routes were considered, but it is no longer the build plan.
|
||||||
|
|
||||||
|
## Baseline measured on the phone (2026-08-04, historical)
|
||||||
|
|
||||||
| Piece | State |
|
| Piece | State |
|
||||||
|---|---|
|
|---|---|
|
||||||
|
|
@ -81,7 +100,7 @@ real keyboard for free. If the dock's *monitors* ever light up, the DP lanes
|
||||||
exist and we go hunt the mux wiring; with no typec/altmode wired, expect
|
exist and we go hunt the mux wiring; with no typec/altmode wired, expect
|
||||||
nothing from them.
|
nothing from them.
|
||||||
|
|
||||||
## The KVM notion
|
## Original KVM notion — superseded by TASK-62
|
||||||
|
|
||||||
Plug the phone into another machine's USB port. The phone controls that
|
Plug the phone into another machine's USB port. The phone controls that
|
||||||
machine and sees its screen — keyboard, mouse, monitor, in one cable. Two
|
machine and sees its screen — keyboard, mouse, monitor, in one cable. Two
|
||||||
|
|
@ -122,7 +141,7 @@ BIOS, so a BIOS-stage KVM is HID plus whatever screen the machine itself has.
|
||||||
variety of sources", i.e. the phone-side userspace we would adapt to feed
|
variety of sources", i.e. the phone-side userspace we would adapt to feed
|
||||||
viewtop/compositor frames into the gadget.
|
viewtop/compositor frames into the gadget.
|
||||||
|
|
||||||
## Questions to settle, in order
|
## Original questions — answered by TASK-62
|
||||||
|
|
||||||
1. **Directions:** KVM-into-another-machine only, or also the reverse
|
1. **Directions:** KVM-into-another-machine only, or also the reverse
|
||||||
(phone screen out as webcam)? Both share the UVC config; the userspace
|
(phone screen out as webcam)? Both share the UVC config; the userspace
|
||||||
|
|
@ -141,7 +160,7 @@ BIOS, so a BIOS-stage KVM is HID plus whatever screen the machine itself has.
|
||||||
package still publishes unsigned raw `.pkg.tar.zst` (TASK-25's
|
package still publishes unsigned raw `.pkg.tar.zst` (TASK-25's
|
||||||
`repo-add --sign` is unbuilt) and installs are cold-boot events.
|
`repo-add --sign` is unbuilt) and installs are cold-boot events.
|
||||||
|
|
||||||
## Next steps (ordered, each measurable)
|
## Original next steps — historical
|
||||||
|
|
||||||
1. **Prove HID today** — provision a HID keyboard function into a scratch
|
1. **Prove HID today** — provision a HID keyboard function into a scratch
|
||||||
gadget on the phone (configfs, no reboot), bind it, write
|
gadget on the phone (configfs, no reboot), bind it, write
|
||||||
|
|
@ -155,7 +174,7 @@ BIOS, so a BIOS-stage KVM is HID plus whatever screen the machine itself has.
|
||||||
4. **usb-signaller "kvm" mode** once the pieces exist, with clean
|
4. **usb-signaller "kvm" mode** once the pieces exist, with clean
|
||||||
teardown/provision against the dev mode.
|
teardown/provision against the dev mode.
|
||||||
|
|
||||||
## Acceptance (measured)
|
## Original acceptance sketch — historical
|
||||||
|
|
||||||
- Phone plugged into the laptop enumerates as keyboard+mouse; typing from
|
- Phone plugged into the laptop enumerates as keyboard+mouse; typing from
|
||||||
the phone lands in the laptop's focused app.
|
the phone lands in the laptop's focused app.
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ the threat register), [`souveraine-components/`](souveraine-components/) (the
|
||||||
authority binaries and their audit ladder).
|
authority binaries and their audit ladder).
|
||||||
|
|
||||||
**Designs of record.** [`STORAGE-ENCRYPTION.md`](STORAGE-ENCRYPTION.md),
|
**Designs of record.** [`STORAGE-ENCRYPTION.md`](STORAGE-ENCRYPTION.md),
|
||||||
|
[`WAYDROID.md`](WAYDROID.md), [`../USB/README.md`](../USB/README.md),
|
||||||
[`FEDERATION.md`](FEDERATION.md),
|
[`FEDERATION.md`](FEDERATION.md),
|
||||||
[`session-authority-boot-order.md`](session-authority-boot-order.md).
|
[`session-authority-boot-order.md`](session-authority-boot-order.md).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,10 +285,11 @@ built once; the gating design is its own doc.
|
||||||
container (free once binder is up — `ANDROID_BINDER_IPC=y`, but
|
container (free once binder is up — `ANDROID_BINDER_IPC=y`, but
|
||||||
`ANDROID_BINDERFS` off is a real Waydroid blocker, kernel change), per-agent
|
`ANDROID_BINDERFS` off is a real Waydroid blocker, kernel change), per-agent
|
||||||
UNIX accounts for native callers (the Personal-class work above).
|
UNIX accounts for native callers (the Personal-class work above).
|
||||||
- **Nothing installed today:** no Flatpak, bubblewrap, xdg-desktop-portal, or
|
- **Waydroid is installed now:** measured 2026-08-07 on the phone with
|
||||||
Waydroid in either repo. The namespace/cgroup/seccomp primitives are compiled
|
`ANDROID_BINDER_IPC=y` and `ANDROID_BINDERFS=y`. Its container unit was
|
||||||
in and unused. "Free granularity from Flatpak" is a design premise that
|
active while its session was stopped; [`WAYDROID.md`](WAYDROID.md) owns that
|
||||||
requires installing Flatpak first.
|
layered status. Flatpak and an app-identity portal backend remain absent, so
|
||||||
|
the runtime-isolation design here is still unbuilt.
|
||||||
- **Runtime vs at-rest:** fscrypt protects a powered-off device. It does not
|
- **Runtime vs at-rest:** fscrypt protects a powered-off device. It does not
|
||||||
stop a process in the unlocked session reading another's files — that is the
|
stop a process in the unlocked session reading another's files — that is the
|
||||||
runtime half, and per-app UIDs are its foundation too. At-rest encryption
|
runtime half, and per-app UIDs are its foundation too. At-rest encryption
|
||||||
|
|
|
||||||
28
docs/WAYDROID.md
Normal file
28
docs/WAYDROID.md
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Waydroid — current device state
|
||||||
|
|
||||||
|
## Current — 2026-08-07
|
||||||
|
|
||||||
|
Waydroid is present on the daily driver; documents saying it is absent are
|
||||||
|
stale.
|
||||||
|
|
||||||
|
Measured on the phone at `10.10.30.213`:
|
||||||
|
|
||||||
|
| Fact | State |
|
||||||
|
|---|---|
|
||||||
|
| Package | `waydroid 1.6.3-1` |
|
||||||
|
| Kernel | `7.1.1-sdm845-g08e9db54cfce` |
|
||||||
|
| Binder | `CONFIG_ANDROID_BINDER_IPC=y`, `CONFIG_ANDROID_BINDERFS=y`; binder, hwbinder and vndbinder devices configured |
|
||||||
|
| Container unit | active/running, disabled at boot |
|
||||||
|
| Waydroid session | stopped |
|
||||||
|
| Vendor type | mainline |
|
||||||
|
|
||||||
|
This is installation and runtime truth, not an ownership claim. Souveraine has
|
||||||
|
no Waydroid lifecycle verb, health model, power policy, or first-class app
|
||||||
|
surface yet. The old radial-dial memory of “Kill waydroid” is not present in
|
||||||
|
the canonical dial and should not be resurrected as a shell command. If the
|
||||||
|
container becomes a device verb, it belongs in sessiond with start, stop,
|
||||||
|
status, refusal and forensic history; the power sheet may then be its view.
|
||||||
|
|
||||||
|
Until that exists, a stopped session with a running container is expected to
|
||||||
|
look ambiguous. Do not call it stopped, running, or absent without naming
|
||||||
|
which layer was measured.
|
||||||
|
|
@ -5,6 +5,25 @@
|
||||||
**Repos:** `~/Projects/souveraine` (`packaging/upower-souveraine`,
|
**Repos:** `~/Projects/souveraine` (`packaging/upower-souveraine`,
|
||||||
`surfaces/quickshell`, `src/sessiond`).
|
`surfaces/quickshell`, `src/sessiond`).
|
||||||
|
|
||||||
|
## Policy decision — 2026-08-07
|
||||||
|
|
||||||
|
This is a **charge ceiling + resume floor**, not “trickle charging.” Charge
|
||||||
|
type is evidence about what the charger is doing; thresholds are control over
|
||||||
|
when it may do it. Keep those as different fields and different verbs.
|
||||||
|
|
||||||
|
The live phone has only
|
||||||
|
`pmi8998-charger/charge_control_end_threshold=99`; there is no
|
||||||
|
`charge_control_start_threshold`. The resulting narrow hardware behaviour is
|
||||||
|
the observed 99→stop, 98→start twitch. The wanted policy is a wide, flexible
|
||||||
|
hysteresis pair: stay below 100%, and permit a bounded agent decision to hold
|
||||||
|
charging until a useful floor (30% was Casey's example) before re-enabling it.
|
||||||
|
|
||||||
|
Authority is settled: a human defines the safe envelope; an agent may propose
|
||||||
|
or choose inside it only through step-up, and every move is recorded. No agent
|
||||||
|
or QML surface writes charger sysfs directly. Until both thresholds and that
|
||||||
|
authority path exist, the power sheet shows this as a draft rather than a
|
||||||
|
switch that lies.
|
||||||
|
|
||||||
## Why this exists
|
## Why this exists
|
||||||
|
|
||||||
Charging has no owner. Every surface reads UPower directly and renders
|
Charging has no owner. Every surface reads UPower directly and renders
|
||||||
|
|
|
||||||
101
docs/tasks/62-full-usb-kvm.md
Normal file
101
docs/tasks/62-full-usb-kvm.md
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
# TASK 62 — full USB KVM: the phone becomes the glass and the hands
|
||||||
|
|
||||||
|
**Status: built on ArchDev, not installed on the phone.** Opened 2026-08-07.
|
||||||
|
This task owns the one-cable composite from mode request through rollback and
|
||||||
|
the first hardware acceptance. It does not own phone-as-host power; TASK-58
|
||||||
|
does.
|
||||||
|
|
||||||
|
## Contract
|
||||||
|
|
||||||
|
The attached computer is the host. It sends a GUD display into the Pixel 3.
|
||||||
|
The phone draws that display in a Wayland surface and returns keyboard,
|
||||||
|
pointer and touch through boot-protocol HID. NCM keeps a control lane and smoo
|
||||||
|
offers host-backed storage through FunctionFS/ublk.
|
||||||
|
|
||||||
|
One mode change owns all four functions:
|
||||||
|
|
||||||
|
```
|
||||||
|
kvm_mode = ffs.gud + ffs.smoo + ncm.usb0 + hid.keyboard + hid.pointer
|
||||||
|
```
|
||||||
|
|
||||||
|
`usb-signaller` prepares both FunctionFS mounts, starts both responders, waits
|
||||||
|
for both readiness signals, then binds the UDC. Any failure tears the partial
|
||||||
|
mode down and restores the previously working USB posture. The shell never
|
||||||
|
writes configfs: it asks sessiond, which records an `Action::UsbMode` and calls
|
||||||
|
the system D-Bus mechanism.
|
||||||
|
|
||||||
|
## Where the work lives
|
||||||
|
|
||||||
|
| Layer | Canonical path | State |
|
||||||
|
|---|---|---|
|
||||||
|
| Receiver + display + HID | `souveraine/src/bin/souveraine-usb-kvm.rs` | built ARM64 |
|
||||||
|
| Session authority | `souveraine/src/sessiond/{protocol,device_state,server}.rs` | `usb` + `set_usb_mode`, including `kvm` |
|
||||||
|
| Human surface | `souveraine/surfaces/quickshell/` | nested Power Options; HID and KVM are live leaves when advertised |
|
||||||
|
| Souveraine package | `souveraine/packaging/arch/PKGBUILD.prebuilt` | receiver included on aarch64 |
|
||||||
|
| Gadget mechanism | `usb-signaller/` | full composite, readiness gates, rollback, user-owned HID/GUD lane |
|
||||||
|
| Device packages | `Pixel3Arch/pkgs/{usb-signaller,smoo}` | recipes written; not published/installed |
|
||||||
|
|
||||||
|
The separate local `souveraine-usb` repo is a safety copy from the first
|
||||||
|
layout attempt, not a source of record. Do not build another package from it.
|
||||||
|
|
||||||
|
## Verification already earned
|
||||||
|
|
||||||
|
- Receiver unit tests: RGB565 dirty-rect conversion and HID usage mapping.
|
||||||
|
- Receiver strict Clippy: clean.
|
||||||
|
- ArchDev full release build: ARM64 PIE, 3,893,576 bytes,
|
||||||
|
SHA-256 `1fb58409cb1923599bcbcf229d1d2c1a61d4d7b2143387f21e7c6043ec44622d`.
|
||||||
|
- ArchDev sessiond build: ARM64 PIE,
|
||||||
|
SHA-256 `46046a53231b4f838fb47d8a8e75a51c6c8471ea3ccd2bc43bbf7ced2e38841a`.
|
||||||
|
- Mode scripts parse, the source/package copies match, and the Casey-owned
|
||||||
|
runtime directory, environment file and `/dev/hidg*` nodes are reachable by
|
||||||
|
the unprivileged receiver.
|
||||||
|
|
||||||
|
`gud-gadget` has no declared licence. Casey explicitly accepted that risk for
|
||||||
|
this private build. Do not publish its binary into a public archive until that
|
||||||
|
is resolved.
|
||||||
|
|
||||||
|
## Phone truth before landing
|
||||||
|
|
||||||
|
Measured at `10.10.30.213` on 2026-08-07:
|
||||||
|
|
||||||
|
- `usb-signaller 0.3.1-3`, `souveraine r379`, no `smoo` package;
|
||||||
|
- live mode `charging_only`;
|
||||||
|
- advertised modes: developer, tethering, charging-only, MTP and host;
|
||||||
|
- data role `device`, charger online;
|
||||||
|
- `charge_control_end_threshold=99`; no start-threshold attribute.
|
||||||
|
|
||||||
|
So a KVM button in a newly deployed shell must remain unavailable until the
|
||||||
|
new usb-signaller package advertises `kvm_mode`. That is deliberate feature
|
||||||
|
discovery, not a version guess.
|
||||||
|
|
||||||
|
## Landing order
|
||||||
|
|
||||||
|
1. Publish/install the new `souveraine`, `smoo`, and `usb-signaller` packages.
|
||||||
|
Keep Wi-Fi SSH alive; do not make a USB mode change the only recovery path.
|
||||||
|
2. Verify `get_modes` includes `hid_mode,kvm_mode` before opening the power
|
||||||
|
sheet. Verify all installed files are package-owned.
|
||||||
|
3. Enter HID mode first. Confirm keyboard and pointer enumerate on the host,
|
||||||
|
reports arrive, and developer mode restores cleanly.
|
||||||
|
4. Enter KVM mode. Confirm host enumeration for GUD, both HIDs, NCM and smoo;
|
||||||
|
then confirm a host frame reaches the phone and touch returns to the host.
|
||||||
|
5. Pull the cable and force one responder failure. In both cases the daemon
|
||||||
|
must stop services, release FunctionFS, and leave or restore a usable mode.
|
||||||
|
6. Only after those checks make KVM a normal daily-driver choice.
|
||||||
|
|
||||||
|
No phone mutation or flash belongs before step 1's packages exist.
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- A host frame is visible on the phone; resize redraws without a blank buffer.
|
||||||
|
- Physical keyboard, mouse and touch in that surface control the attached host.
|
||||||
|
- NCM remains usable and smoo reaches its ready endpoint.
|
||||||
|
- Closing the surface, unplugging, or a failed responder leaves no stuck UDC,
|
||||||
|
root-only endpoint or dead management port.
|
||||||
|
- The held-power sheet reports the actual mode and returns to developer USB.
|
||||||
|
|
||||||
|
## Connects to
|
||||||
|
|
||||||
|
`USB/README.md` (exploration and host-mode record), TASK-30 (verb tables),
|
||||||
|
TASK-33 (adjacent charging policy), TASK-50 (the inverse hand-on-glass path),
|
||||||
|
TASK-57 (phone-as-gadget dock), TASK-58 (host-role VBUS), SAF federation
|
||||||
|
(attached identity and probe ownership).
|
||||||
|
|
@ -29,6 +29,7 @@ Four that are cheap relative to what they unblock:
|
||||||
|
|
||||||
| # | Task | What's left |
|
| # | Task | What's left |
|
||||||
|---|------|-------------|
|
|---|------|-------------|
|
||||||
|
| 60 | [Multitasking is a place, not a transition](60-the-multitasking-view.md) | One-owner compositor and shell halves are built; strand repro and measured landing pass on glass. `16c6ee1` is pushed and CI 1236 is green. What remains is Casey's thumb on the settle/fade and a real split-zone card check. |
|
||||||
| 53 | [viewtop audit: what it left open](53-viewtop-audit-open.md) | All ten fixed and **packaged onto the phone** (`r74.g6c9614c20471`). The cold boot then exposed a *third*: a lost sessiond race had left the power button dead — discovery waits now. Hardware found two more the gates did not — `delivered` reported true for a withheld contact, and a drift warning that fired on every normal close. What is left needs the PIN. |
|
| 53 | [viewtop audit: what it left open](53-viewtop-audit-open.md) | All ten fixed and **packaged onto the phone** (`r74.g6c9614c20471`). The cold boot then exposed a *third*: a lost sessiond race had left the power button dead — discovery waits now. Hardware found two more the gates did not — `delivered` reported true for a withheld contact, and a drift warning that fired on every normal close. What is left needs the PIN. |
|
||||||
| 43 | [viewtop: the Souveraine compositor](43-viewtop-compositor.md) | Runs on the phone. Next lane is the ext-session-lock admission gate. The two-client lock handoff is the thing not to get wrong. |
|
| 43 | [viewtop: the Souveraine compositor](43-viewtop-compositor.md) | Runs on the phone. Next lane is the ext-session-lock admission gate. The two-client lock handoff is the thing not to get wrong. |
|
||||||
| 29 | [SouveraineOS Updater](29-souveraine-updater.md) | Ships and installs by `pacman -Syu`. **Read-only on device** until something runs a polkit agent — that is the shell's job. Also owns TASK-42's layer 2. |
|
| 29 | [SouveraineOS Updater](29-souveraine-updater.md) | Ships and installs by `pacman -Syu`. **Read-only on device** until something runs a polkit agent — that is the shell's job. Also owns TASK-42's layer 2. |
|
||||||
|
|
@ -37,6 +38,7 @@ Four that are cheap relative to what they unblock:
|
||||||
|
|
||||||
| # | Task | What's left |
|
| # | Task | What's left |
|
||||||
|---|------|-------------|
|
|---|------|-------------|
|
||||||
|
| 62 | [Full USB KVM](62-full-usb-kvm.md) | GUD display-in + HID + NCM + smoo, transactional mode rollback, sessiond verbs and the nested power-sheet control all build. Package publication and the staged host/glass acceptance remain; the phone still runs usb-signaller pkgrel 3 and has no smoo. |
|
||||||
| 08 | [Device state manager / power profiles](08-device-state-manager.md) | Largest task; sub-divide before starting. (e) lease missing, (f) **surfaced 2026-07-31** — health, evidence and the decision trail render on the Device page; last-seen and grip still absent from `device_state`. (g) confidence gates need a decision before code. |
|
| 08 | [Device state manager / power profiles](08-device-state-manager.md) | Largest task; sub-divide before starting. (e) lease missing, (f) **surfaced 2026-07-31** — health, evidence and the decision trail render on the Device page; last-seen and grip still absent from `device_state`. (g) confidence gates need a decision before code. |
|
||||||
| 16 | [culver: messenger + contacts](16-culver-messenger-contacts.md) | A/B/D landed. C (contact card) builds and awaits phone acceptance. F is the folded-in TASK-01. |
|
| 16 | [culver: messenger + contacts](16-culver-messenger-contacts.md) | A/B/D landed. C (contact card) builds and awaits phone acceptance. F is the folded-in TASK-01. |
|
||||||
| 19 | [First-party Settings control center](19-settings-control-center.md) | State-machine + source-health readout **built 2026-07-31**, unverified on glass. 34 and 42's layer 3 still surface here. |
|
| 19 | [First-party Settings control center](19-settings-control-center.md) | State-machine + source-health readout **built 2026-07-31**, unverified on glass. 34 and 42's layer 3 still surface here. |
|
||||||
|
|
@ -59,7 +61,6 @@ Four that are cheap relative to what they unblock:
|
||||||
|
|
||||||
| # | Task | What's left |
|
| # | Task | What's left |
|
||||||
|---|------|-------------|
|
|---|------|-------------|
|
||||||
| 60 | [Multitasking is a place, not a transition](60-the-multitasking-view.md) | Written after building the wrong thing. The rail scales the active zone's windows on swipe — a *transition* mistaken for the *destination*. It scales the wrong windows (2 s poll, and the shell has no "focused window" fact at all), and scaling one zone can never show what is backgrounded. `WindowOverview` draws one column of window cards and has no concept of zones; its own header admits the gap. Needs deciding before code: card = window or zone, `ScreencopyView` pictures vs posed real windows, where focus comes from, and whether the poll gets replaced by a push. |
|
|
||||||
| 59 | [Her face on the glass: a Live2D presence](59-her-face-on-the-glass.md) | **Phase 1 passed on hardware 2026-08-05: ~58 fps, rig verified drawing (`painted_px` 23.6k/24k), 283 MB WebKit RSS.** Scoped from a Live2D board-girl found in a cloned blog. The reference streams its chat over **SSE terminated by `[DONE]`** — the contract souveraine's server already speaks, so the integration is accidentally done. Base layer is **wry**, not the Chromium already on the phone; the first deliverable is a measured frame rate for the Cubism runtime in WebKit on freedreno, and if that fails the task stops there. Replaces ani-avatar's 2.5 GB of sprite states with one rig. Reference rig ships as the working placeholder and gets edited toward Annie — it just stays out of any public repo. Summoned by app launch and/or the radial dial, not always-on. |
|
| 59 | [Her face on the glass: a Live2D presence](59-her-face-on-the-glass.md) | **Phase 1 passed on hardware 2026-08-05: ~58 fps, rig verified drawing (`painted_px` 23.6k/24k), 283 MB WebKit RSS.** Scoped from a Live2D board-girl found in a cloned blog. The reference streams its chat over **SSE terminated by `[DONE]`** — the contract souveraine's server already speaks, so the integration is accidentally done. Base layer is **wry**, not the Chromium already on the phone; the first deliverable is a measured frame rate for the Cubism runtime in WebKit on freedreno, and if that fails the task stops there. Replaces ani-avatar's 2.5 GB of sprite states with one rig. Reference rig ships as the working placeholder and gets edited toward Annie — it just stays out of any public repo. Summoned by app launch and/or the radial dial, not always-on. |
|
||||||
| 58 | [Host power: the SMB2 OTG boost](58-host-power-smb2-boost.md) | Host data works; the boost isn't. The SMB2 5 V boost exists in silicon and mainline's `qcom-smbx-charger` never registers it. Investigation first (which tree builds the running kernel, does smb2 touch the boost, does `qcom_pmic_typec` bind pmi8998), then vbus-supply + regulator + typec. Unlocks host-mode power, power-bank mode, and the Pi without a wall wart. |
|
| 58 | [Host power: the SMB2 OTG boost](58-host-power-smb2-boost.md) | Host data works; the boost isn't. The SMB2 5 V boost exists in silicon and mainline's `qcom-smbx-charger` never registers it. Investigation first (which tree builds the running kernel, does smb2 touch the boost, does `qcom_pmic_typec` bind pmi8998), then vbus-supply + regulator + typec. Unlocks host-mode power, power-bank mode, and the Pi without a wall wart. |
|
||||||
| 57 | [The Pi dock head](57-pi-dock-head.md) | Phone stays a gadget; the Pi 4 drives the monitor + dock. NCM link is default, Venus encoder is present, compositor capture landed — the unproven seams are `zwlr_screencopy` vs our own capture IPC, and the Pi's own bring-up ("major malfunctions TBD"). Four phases: Pi bring-up, static chain, real capture + udev trigger, input injection. |
|
| 57 | [The Pi dock head](57-pi-dock-head.md) | Phone stays a gadget; the Pi 4 drives the monitor + dock. NCM link is default, Venus encoder is present, compositor capture landed — the unproven seams are `zwlr_screencopy` vs our own capture IPC, and the Pi's own bring-up ("major malfunctions TBD"). Four phases: Pi bring-up, static chain, real capture + udev trigger, input injection. |
|
||||||
|
|
@ -77,10 +78,10 @@ Four that are cheap relative to what they unblock:
|
||||||
| 36 | [CHRE nanoapp host for the SLPI](36-chre-nanoapp-host.md) | Three methods to add; method table recovered 07-27. No longer on grip's critical path — wanted for DozeDeep detection and `elmyra_haptics_control`. |
|
| 36 | [CHRE nanoapp host for the SLPI](36-chre-nanoapp-host.md) | Three methods to add; method table recovered 07-27. No longer on grip's critical path — wanted for DozeDeep detection and `elmyra_haptics_control`. |
|
||||||
| 34 | [SLPI FastRPC session wedge](34-slpi-bringup-sequencing.md) | Re-diagnose. The real symptom: a DSP session survives its host daemon's death and only a cold boot clears it. **No longer blocks grip.** |
|
| 34 | [SLPI FastRPC session wedge](34-slpi-bringup-sequencing.md) | Re-diagnose. The real symptom: a DSP session survives its host daemon's death and only a cold boot clears it. **No longer blocks grip.** |
|
||||||
| 03 | [Boot timing: splash → lock](03-boot-timing-splash-to-lock.md) | The EBUSY handoff race is the last timing bug. Splash text killed, holder added. |
|
| 03 | [Boot timing: splash → lock](03-boot-timing-splash-to-lock.md) | The EBUSY handoff race is the last timing bug. Splash text killed, holder added. |
|
||||||
| 07 | [WCD9340 mic](07-mic-wcd9340-slim-tx.md) | Functional since 07-20. One defect: the power pin that makes it work. Kernel branch `mic-race-fix`. |
|
| 07 | [WCD9340 mic](07-mic-wcd9340-slim-tx.md) | Functional and in daily STT use. One defect: the permanent sysclk + MICB2 power pin. Kernel branch `mic-race-fix`. |
|
||||||
| 09 | [Suspend-resume FTS calibration race](09-suspend-resume-fts.md) | Kernel-side real fix; interim fix shipped. Cold-boot only. |
|
| 09 | [Suspend-resume FTS calibration race](09-suspend-resume-fts.md) | Kernel-side real fix; interim fix shipped. Cold-boot only. |
|
||||||
| 12 | [Face auth as a capability factor](12-gaze-reference-face-auth.md) | Per-target. Phone needs front-camera bring-up — **that is TASK-46's IMX355 half.** |
|
| 12 | [Face auth as a capability factor](12-gaze-reference-face-auth.md) | Per-target. Phone needs front-camera bring-up — **that is TASK-46's IMX355 half.** |
|
||||||
| 17 | [Keyboard + dictation polish](17-keyboard-stevia-dictation.md) | No word completion (stevia asks hunspell for `en-us`, the dict is `en_US`); no recording indicator on the mic key. The layout half moved to TASK-24. **TTS now exists** (`10.10.20.123:7863`) — the settings field can be filled. |
|
| 17 | [Keyboard + dictation polish](17-keyboard-stevia-dictation.md) | Dictation works in daily use. Open: no word completion (`en-us` vs `en_US`) and the stateful mic-key indicator is written but not built. Layout moved to TASK-24. **TTS now exists** (`10.10.20.123:7863`). |
|
||||||
| 18 | [Selection/highlight action menu](18-selection-menu.md) | Component first, fluid before functional. **Read Aloud is unblocked** — TTS is live. |
|
| 18 | [Selection/highlight action menu](18-selection-menu.md) | Component first, fluid before functional. **Read Aloud is unblocked** — TTS is live. |
|
||||||
| 20 | [Player: video + agent control](20-player-video-agent.md) | Video, snapshot, manifest. Preserve the music path. |
|
| 20 | [Player: video + agent control](20-player-video-agent.md) | Video, snapshot, manifest. Preserve the music path. |
|
||||||
| 21 | [Reboot-to-Android confirmation](21-reboot-android-confirmation.md) | Scoped 07-22. A one-tap irreversible slot flip still sits bare in app search. |
|
| 21 | [Reboot-to-Android confirmation](21-reboot-android-confirmation.md) | Scoped 07-22. A one-tap irreversible slot flip still sits bare in app search. |
|
||||||
|
|
@ -91,7 +92,7 @@ Four that are cheap relative to what they unblock:
|
||||||
| 33 | [Battery belongs to the state machine](33-battery-as-device-state.md) | Last raw feed going straight to the glass. The charge ceiling is writable today. |
|
| 33 | [Battery belongs to the state machine](33-battery-as-device-state.md) | Last raw feed going straight to the glass. The charge ceiling is writable today. |
|
||||||
| 37 | ["Back" as a first-class verb](37-navigation-back-verb.md) | Our `Gestures.qml` is already the compositor half; `can_go_back` is the dial's enabled/reason. |
|
| 37 | ["Back" as a first-class verb](37-navigation-back-verb.md) | Our `Gestures.qml` is already the compositor half; `can_go_back` is the dial's enabled/reason. |
|
||||||
| 38 | [Pill swipe-to-max swaps the keyboard](38-pill-swipe-osk-swap.md) | Micro. The only route to a terminal keyboard since stevia dropped its layout. |
|
| 38 | [Pill swipe-to-max swaps the keyboard](38-pill-swipe-osk-swap.md) | Micro. The only route to a terminal keyboard since stevia dropped its layout. |
|
||||||
| 39 | [Audio levels as tracked state](39-audio-levels-as-state.md) | Defaults + roles, **not** a save bug — WirePlumber persistence measured working 07-28. Do not add a second writer. |
|
| 39 | [Audio levels as tracked state](39-audio-levels-as-state.md) | Open policy: roles, defaults, lock tiers, and state-driven profile intent. WirePlumber persistence works; do not add a second writer. |
|
||||||
| — | [Unify the shell trees](unify-shell-trees-laptop-phone.md) | **DONE 2026-07-31** — verified by md5 across both devices: 918 differing files → 7, all 7 declared in the `ii-phone` overlay, laptop-only **0**, zero stranded. The KEEP list was promoted to repo overrides, not lost. Blocks nothing; archive it. |
|
| — | [Unify the shell trees](unify-shell-trees-laptop-phone.md) | **DONE 2026-07-31** — verified by md5 across both devices: 918 differing files → 7, all 7 declared in the `ii-phone` overlay, laptop-only **0**, zero stranded. The KEEP list was promoted to repo overrides, not lost. Blocks nothing; archive it. |
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue