Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ order:
asking Android's `PackageManager` whether the package
`com.google.android.gms` is installed (no import, no binding, nothing read
from it) is not GMS use; the Settings card's information line relies on it.
- **Pointer (2026-10-14, maintainer-approved in chat, `DECISIONS.md` ADR-065, `ai-sessions/0091`):** superseded — the package query is gone; since 1.3.0 the app no longer asks Android whether `com.google.android.gms` is installed (no `<queries>` entry in the manifest).

## 2. GrapheneOS Compatibility & Permissions

Expand Down
57 changes: 36 additions & 21 deletions APP_TESTPLAN.md

Large diffs are not rendered by default.

115 changes: 47 additions & 68 deletions ARCHITECTURE.md

Large diffs are not rendered by default.

43 changes: 24 additions & 19 deletions CAPTURE_BLUETOOTH_HCI_SNOOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -1865,24 +1865,29 @@ exists yet: this run makes the first.**
**Status:** 🔲 planned (skeleton written 2026-10-12 by `ai-sessions/0087`; the run follows `RELEASING.md` B1–C2 for 1.2.1).


#### Group BL — 1.2.2, the constant re-claim step, "Take it back again", the cause line and the renamed card (ADR-062 Update 2, ADR-063) in both GrapheneOS users (skeleton by `ai-sessions/0089`)

Pixel 9a / GrapheneOS, **1.2.2** (versionCode 10202 — the follow-up of `CAP-075`, `ai-sessions/0089`), installed over the 1.2.1 `31ee183` (one APK serves both
users; the stored choice in both users is 1.2.1's "Take it back"). **Two parts, ≤ 20 min on film with sound** (the maintainer's choice in chat 2026-10-13,
"CAP-076" → "both users, as CAP-075"). The skeleton captures/CAP-076-yyyy-MM-dd_HH-mm-ss_HH-mm-ss-Group_BL/CAP-076-EVENT-NOTES.md holds: **part 1, the Owner user
(user 0) with Google Play services** — P0 with Play's *Nearby devices* permission state and version on film (`TODO.md` §3's standing item), the update, Info and
the card **"Noise control with Google Play services"** with its (i), "Google Play services: found on this phone" (ADR-063) and the 1.2.1 choice kept as "This phone
has Google Play services"; holds every ≈ 4 s for 3½ minutes — re-claims **3 s after every cut, up to 20** (≈ 9.3-s cycles, ≈ 50 % held, against `CAP-075`'s 43 % for
44 s), the stop and the hint "…; this app took it back 20 times and stopped. …" with **Take it back again**; the system log right after the chain (Play's "Retry
times remaining"); the (i) line "Changed since the app last saw it (read at HH:MM:SS) …" after a re-claim's changed read; Take it back again → one claim with its
`Get`, **no `Set`**, a new chain (1/20); a tab change, Home and the switch to "This phone has no Google Play services" within 2 s of a cut (`CAP-075`'s untested
BK-11 … BK-13); the APK pull. **Part 2, the secondary user (user 10) without Google Play** — "not found on this phone", the `CAP-073` §4 regression in both options
(every hold shown, no re-claim, no hint), the (i) after a hold made while the app had no claim; optional: the tile, Home/return, a loss with the tab shown
(`TODO.md` §2). Test-IDs: [`PAIR-003`], [`BATT-004`], [`FW-003`], [`ANC-001`]…[`ANC-004`], [`TOUCH-007`]. Reference frames re-derived from `CAP-075` (the Connect
reads on channels 19/21, the cut H2 2369, Play's retry 2401, the refused attempt 2476 and the re-claim's `SABM` 2502, the shown hold 3006, a re-claim's changed
read 2968 → 2980; the hold without Play H1 1192 … 1389) — in the skeleton's table.

**Status:** 🔲 planned (skeleton written 2026-10-13 by `ai-sessions/0089`; the run follows `RELEASING.md` B1–C2 for 1.2.2).
#### Group BL — 1.3.0, the settings stream on the app's own channel (ADR-064, ADR-065) in both GrapheneOS users (skeleton by `ai-sessions/0089`, rewritten by `ai-sessions/0091`)

Pixel 9a / GrapheneOS, **1.3.0** (versionCode 10300 — `ai-sessions/0091`; the 1.2.2 skeleton of `ai-sessions/0089` is replaced, 1.2.2 having been released
without this run), installed over 1.2.2 `bfd7891` (one APK serves both users). **Two parts, the extended tier, screen recordings with sound and a camera on
the ears and the phone** for the hold steps. The skeleton captures/CAP-076-2026-10-15_06-35-26_07-08-20-Group_BL/CAP-076-EVENT-NOTES.md holds: **part 1,
the Owner user (user 0) with Google Play services** — P0 with Play's *Nearby devices* permission state and version on film (`TODO.md` §3's standing item), the
update, Info and a Settings tab **without** the "Noise control with Google Play services" card and the Play line; the Connect's **seventeen** MAESTRO requests (the skeleton said fifteen — `CAP-076-FINDINGS.md` §2)
(`SubscribeToSettingsChanges` and `ReadSetting 4:13` after `SubscribeRuntimeInfo`, byte-identical to `CAP-051` 1177/1178 on channel 21 or `CAP-056` 1451/1450 on
19); **ten press-and-holds with the noise-control tab closed and ten with it open** (≥ 10 each) — every hold one `4:{13:n}` stream packet on DLCI 0x02 and the
mode on screen within a second, **no `SABM` on DLCI 0x04 from the app**; the (i) "Changed by the Buds at HH:MM:SS: …"; a tap on the tab and the tile (one claim
each, the stream packet of the own `Set` ≈ 0.3 s later, released ≈ 1.5 s after the ACK); a wear-change re-home (one bud out with both worn: the Buds' `DISC` →
the ADR-044 re-open → the subscription and the read again, the mode before/after, "Changed since the app last saw it (read at HH:MM:SS)" if it differs);
Bluetooth off/on (the re-open subscribes again); taps while Play holds the channel (the `CAP-075` §5 collision — the known issue, nothing re-claims); optionally
the EQ and a switch changed in the official app on a second phone (the stream packets for field 16 / 2 reach OpenControl) — skipped and said so if no second
phone; the APK pull. **Part 2, the secondary user (user 10) without Google Play** — the same holds (tab closed, tab open), the tap, the tile, the wear-change
re-home, Bluetooth off/on, a Disconnect with two holds made while disconnected and the Connect's read ("Changed since the app last saw it"), both buds into the
case and out (a value 0 never shown as a mode); optional Home with holds while hidden. **Counts for the verdict:** OpenControl's `SABM`s on DLCI 0x04 vs the
taps/tile/pulls/Connects made; holds shown vs made; stream packets vs `Notify`s; the first read's value after every Connect/re-open. Test-IDs: [`PAIR-003`],
[`BATT-004`], [`FW-003`], [`ANC-001`]…[`ANC-004`], [`TOUCH-007`]. Reference frames (the official app's bytes, re-derived by `ai-sessions/0091`: the two requests,
the `4:{13:n}` answers and stream packets per channel and value, the other fields' packets, the own tap's order `CAP-051` 1527 → 1534) and the `tshark` lines
to find them — in the skeleton's table.

**Status:** ✅ captured 2026-10-15 (part 1 06:35–06:52, the Owner user with Google Play; part 2 07:01–07:08, the secondary user without) and analyzed 2026-10-15 by `ai-sessions/0092` (`CAP-076-FINDINGS.md`): the two requests once per session, every hold on the noise-control tab shown in both users (29/29, 12/12), the own taps as the app's change; three minor defects; verdict "release as built + Known issues" (the maintainer, chat 2026-10-15). The maintainer tested only the changed functionality; BL-10, BL-13, BL-15, BL-18, BL-21, BL-24, BL-25 not run (`CAP-076-EVENT-NOTES.md`).

### 4.3 Hardware Actions (either phone)

Expand Down Expand Up @@ -2287,7 +2292,7 @@ is how the 2026-08-18 `CAP-005`/`CAP-007`/`CAP-010` ID-reuse incident (see
| `CAP-073` | 2026-10-10 | Pixel 9a (secondary user 10 without Google Play) | 17 (`CP3A.261005.005`) | `release_5.203` | OpenControl for Pixel Buds Pro 2 **1.2.0** rebuilt, build `5b4d5db`, release-signed (Info tab on film, no -dirty; installed APK SHA-256 = B1's), an update over the `ec6d163` 1.2.0 | BI (new) | `PAIR-003`, `BATT-004`, `FW-003`, `ANC-001`–`ANC-004`, `TOUCH-007`, `CASE-004`, `CASE-005`, `INEAR-006`, `AUDIO-003`; `AUDIO-002`, `INEAR-004` not run | The re-test of the rebuilt 1.2.0 (`ai-sessions/0085`): 11 sessions with the thirteen requests byte-identical to `CAP-072`; the ADR-061 hold held DLCI 0x04 31 s on the noise-control tab, four unprovoked `Notify` shown without a tap, four taps on the held channel (no `SABM`), released 1.509 s after leaving the tab; balance one write per release, "Right 4" on the third; 6 writes and 4 `Set`s answered; no camera, no audio; verdict OK — ready to release | — (one `bugreportz` archive, not kept; the raw logs) | `CAP-073-btsnoop_hci.log` (08:22:51–08:35:07, the run), `CAP-073-btsnoop_hci.log.last` (2026-10-09 18:32 – 2026-10-10 08:22, before the run, the Owner user); one export, the app logcat, `CAP-073-logcat-extract.txt`, the shell log, `CAP-073-screen.mp4` (blurred) | analyzed |
| `CAP-074` | 2026-10-12 | Pixel 9a (**the Owner user 0 with Google Play services**) | 17 (`CP3A.261005.005`) | `release_5.203` | OpenControl for Pixel Buds Pro 2 **1.2.0**, build `5b4d5db`, release-signed (the published release; Info tab on film, no -dirty; the installed APK not pulled) | BJ (new) | `PAIR-003`, `ANC-001`–`ANC-004`, `TOUCH-007`, `BATT-004`, `FW-003`; `AUDIO-002` not run | The maintainer's ad-hoc run in the user with Play services (`ai-sessions/0086`): nine Disconnect/Connect pairs, after each the ANC tab and press-and-holds; 10 sessions byte-identical to `CAP-073`; **every ADR-061 hold cut 4.7–5.1 s after its `SABM` by Play services' Fast Pair recovery** (5.2–5.7 s after it lost the channel, 20 of 20) — 9 holds shown, 35 reached Play services: the cause of the first-hold-only pattern (`CAP-074-FINDINGS.md` §4, §8); fix: a Settings switch, the maintainer's choice | — (`bugreportz` by the maintainer, not kept; the raw logs) | `CAP-074-btsnoop_hci.log` (2026-10-11 19:50 – 2026-10-12 06:52: the run and a 06:30–06:31 window of an earlier process), `CAP-074-btsnoop_hci.log.last` (2026-10-11); one export (06:38–07:03), the app logcat, `CAP-074-logcat-extract.txt`, `CAP-074-recording.mp4` (with audio, as is), `CAP-074-sha256sum.txt` | analyzed |
| `CAP-075` | 2026-10-12 (set 1, 17:22:31–17:28:43 on film) and 2026-10-13 (set 2, 06:29:04–06:34:32 on film) | Pixel 9a (**set 1: the secondary user without Google Play; set 2: the Owner user 0 with Google Play services**) | 17 (`CP3A.261005.005` in `CAP-074`; not re-read) | `release_5.203` | OpenControl for Pixel Buds Pro 2 **1.2.1** (versionCode 10201), build `31ee183`, release-signed (Info tab on film in both users, no -dirty; the installed APK not pulled), updated over 1.2.0 `5b4d5db` on film | BK (new) | `PAIR-003`, `BATT-004`, `FW-003`, `ANC-001`–`ANC-004` (no mode tap: shown from `Notify` only), `TOUCH-007`; `AUDIO-002`, `CASE-004`/`005` not observed | The hardware run of the "Noise-control channel" switch (`DECISIONS.md` ADR-062): without Play both positions identical, 41 of 41 holds shown, no foreign close; with Play "Show a hint" = the hint with the cut's time, 0 of 9 holds shown; "Take it back" = three chains × three re-claims (3/6/12 s scheduled, 4.0–4.8 s on the wire), every re-claim colliding with Play's retry, every hold cut 5.3–5.8 s after Play's loss, 43 % coverage then nothing, 8 of 19 holds shown; the cut's stack path 15 of 15 in the system log (`CAP-075-FINDINGS.md` §4, §5, §8); verdict no heavy issue — 1.2.1 released as built; proposals P1/P2/P4 to the next FEATURE prompt | — (`bugreportz` 06:35:41 and the GrapheneOS log viewer's full log, both local only) | `CAP-075-btsnoop_hci1.log.last` + `CAP-075-btsnoop_hci1.log` (set 1, split at the Bluetooth off/on 17:23:04/08), `CAP-075-btsnoop_hci2.log.last` (2026-10-12 18:13 – 2026-10-13 06:29, incl. the Owner's unfilmed evening session) + `CAP-075-btsnoop_hci2.log` (06:29–06:36); two exports, two app logcats, `CAP-075-logcat-extract.txt` (set 2's system log, redacted), `CAP-075-recording1.mp4` / `CAP-075-recording2.mp4` (with audio, as is), `CAP-075-sha256sum.txt` | analyzed |
| `CAP-076` | TBD | Pixel 9a (**part 1: the Owner user 0 with Google Play services; part 2: the secondary user 10 without**) | 17 | `release_5.203` expected | OpenControl for Pixel Buds Pro 2 **1.2.2** (versionCode 10202), the release APK of `scripts/release.sh 1.2.2`, installed over 1.2.1 `31ee183` — build hash on the Info tab on film, the installed APK pulled | BL (new) | `PAIR-003`, `BATT-004`, `FW-003`, `ANC-001`–`ANC-004`, `TOUCH-007` | The hardware run of ADR-062 Update 2 and ADR-063 (`ai-sessions/0089`): in the Play user the re-claim 3 s after every cut up to 20 (≈ 50 % held for ≈ 3 min), the hint with "20 times" and Take it back again (one claim, no `Set`, a new chain), the changed-since-last-read (i) line, the cancel paths, the renamed card with "found on this phone"; in the user without Play the `CAP-073` §4 regression in both options and "not found on this phone" | — | TBD | planned |
| `CAP-076` | 2026-10-15 (part 1, 06:35:26–06:51:47 on film; part 2, 07:02:31–07:08:20 on film) | Pixel 9a (**part 1: the Owner user 0 with Google Play services; part 2: the secondary user 10 without**) | 17 (`CP3A.261005.005`, film 1 s595) | `release_5.203` | OpenControl for Pixel Buds Pro 2 **1.3.0** (versionCode 10300), build `ff27ee1`, release-signed, installed over 1.2.2 `bfd7891` on film 1; the installed APK pulled: SHA-256 = the tested build's | BL (new) | `PAIR-003`, `BATT-004`, `FW-003`, `ANC-001`–`ANC-004`, `TOUCH-007`, `CASE-004`/`005`, `INEAR-001`–`003`, `FIND-001`; BL-10/15/18/21/24 not run | The hardware run of ADR-064/ADR-065: the two new requests once per MAESTRO session (12 of 12, byte-identical); holds on the noise-control tab shown within 0.1 s — 29 of 29 with Play holding DLCI 0x04, 12 of 12 without; 15 own `Set`s ACKed and classed as the app's; nothing held or re-claimed; every change pushed twice (channels 21 and 19) with both buds out; the re-open's "changed since" cause overwritten by the equal `4:13` answer; one tile tap lost silently to Play; verdict release as built with two Known issues (`CAP-076-FINDINGS.md`, `ai-sessions/0092`) | — (the GrapheneOS log viewer's system log and `adb logcat -b all` of part 1, both local only) | `CAP-076-btsnoop_hci1.log.last` + `CAP-076-btsnoop_hci1.log` (part 1, split at the Bluetooth off/on 06:35:34/06:36:10), `CAP-076-btsnoop_hci2.log.last` + `CAP-076-btsnoop_hci2.log` (part 2, split at 07:02:39/44); two exports, two app logcats, `CAP-076-logcat-extract.txt` (part 1, redacted), `CAP-076-adb-shell.log`, `CAP-076-adb-checks-0092.log`, `CAP-076-recording1.mp4` / `CAP-076-recording2.mp4` | analyzed |

**Column notes:**

Expand Down
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,37 @@ build commit `bfd7891`, `ai-sessions/0089`; tested by the maintainer on the phon

## [Unreleased]

## [1.3.0]

Prepared in `ai-sessions/0091` (2026-10-14) after `ai-sessions/0090`'s cross-check of the official app (`DECISIONS.md` ADR-064, ADR-065): the Buds report every
change of the noise-control mode — and of every other setting — on the app's own channel, once the app asks for it. Two new requests on the wire at every
Connect, both byte-identical to the official app's.

### Changed

- **A press-and-hold on a bud now shows in the app whatever tab is open, with or without Google Play services on the phone.** The Buds push the new mode on the
app's own channel; the noise-control (i) says "Changed by the Buds at HH:MM:SS". The channel shared with Google Play services is claimed only for a tap, as in
1.1.x.
- **Every setting the app shows follows a change made elsewhere** (the official app on another phone, the Buds themselves): the equalizer, the switches, the
balance, the press-and-hold actions and modes — each with the time it came in.
- The noise-control mode is read at every Connect and re-open: a change made while the app was not connected shows at once ("Changed since the app last saw
it").

### Removed

- The setting "Noise control with Google Play services", its card, the "Google Play services: found / not found" line, the hold of the channel while the
noise-control tab is open, the re-claims and "Take it back again" (`DECISIONS.md` ADR-061, ADR-062, ADR-063 — superseded by ADR-065). A choice stored by 1.2.1
or 1.2.2 is ignored. The app no longer asks Android whether Google Play services is installed (the manifest's `<queries>` entry is gone).

### Known issues

- A tap on a noise-control mode claims the shared channel for about 1.5 seconds; on a phone with Google Play services, Play's Fast Pair may be on it at that
moment (about 5 seconds after a claim) — the tap then usually fails with a message (in `CAP-076` once without one, from the tile: nothing changed); tap again.
- When the Buds close the session themselves (one bud out while both are worn — 12 of 77 such changes in the captures), the app re-opens it and reads the mode
again; in between, the mode shown can be a few seconds old.
- After a reconnect (or when the Buds re-open the session themselves), a mode that changed while the app was not connected shows as read: the (i) line
"Changed since the app last saw it" does not appear (`CAP-076`). A fix follows.

## [1.2.2] - 2026-10-14

Prepared in `ai-sessions/0089` (2026-10-13) after `CAP-075` (`ai-sessions/0088`): with Google Play services, Play's Fast Pair takes the noise-control channel
Expand Down
Loading
Loading