You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9ddb698
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/radio-action-gap.md
+10-2Lines changed: 10 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,8 +32,8 @@ a missing service call, is the actual gap.
32
32
| A | Pause / stop the radio |**add** — `PAUSE_RADIO`|`srcPauseRadio` is implemented and unreachable. `MEDIA_CONTROL` is not a substitute: it addresses whichever source owns the audio, so it silences Bluetooth when Bluetooth is playing. "Silence the tuner" was not expressible. |
33
33
| B | Explicit radio play/pause toggle on readable state |**add** — `RADIO_PLAY_PAUSE`| One shortcut for a driver who wants the tuner specifically, whatever the current source. Built on `isPlaying()` (`RadioBean.state`), because `AudioManager.isMusicActive` is **false while the radio plays** — a toggle driven by it would send "play" to a playing radio forever. Unknown state fails closed (see below). |
34
34
| C | Open the radio screen |**add, gated** — `OPEN_RADIO_SCREEN`|`startRadioActivity` is implemented and unreachable. It is the one radio action that is not audio-only: throwing a full-screen app in front of a driver at speed is a distraction, so it takes the standstill gate and is refused when speed is unreadable. |
35
-
| D | Select a band |**reject**| The binding contract exposes no band-only call. `tune` takes `(band, frequencyKhz)`together, so a band action would have to invent a frequency — and the one it invented would be the station the driver did not ask for. FM/AM band selection is already carried by `TUNE_RADIO`, which infers the band from what was typed. |
36
-
| E | Select a DAB service |**reject**| A DAB service is addressed by ensemble id + service id, not by a frequency, and neither is a stable identifier a driver could enter or a rule could store across a re-scan. No on-vehicle evidence establishes a portable contract. DAB stays reachable through `RADIO_NEXT_STATION` / `RADIO_PREV_STATION`, which step the tuner's own list on whatever band it is on — band 4 in `MediaConstants`is DAB, and the launcher's own skip is this same call. |
35
+
| D | Select a band |**added**(2026-08-29, reversed) | Originally rejected because the binding contract exposes no band-only call. The owner asked for DAB support anyway, and the rejection turned out to be answering the wrong question: a band action does not need a band-only *call*, because `tune(band, frequencyKhz)`already carries the band as its first argument. `SELECT_RADIO_BAND` composes what is established — read the current band from `RadioBean`, tune into the requested one — and guesses no transaction code. The frequency it lands on is the station this car was last heard on for that band (`RadioBandMemory`), or the band floor followed by one `nextStation()` when it has never been there, so it does not strand the driver on an empty frequency. |
36
+
| E | Select a DAB service |**reject**(unchanged) | A DAB service is addressed by ensemble id + service id, not by a frequency, and neither is a stable identifier a driver could enter or a rule could store across a re-scan. No on-vehicle evidence establishes a portable contract. DAB is now reachable as a **band** (candidate D) and stepped through with `RADIO_NEXT_STATION` / `RADIO_PREV_STATION`; what stays out is selecting one named service directly. A DAB *block* is a real frequency in Band III, which is what a band switch tunes; a DAB *service* is not. |
37
37
| F | Restore the last audible radio state at ignition |**already covered**| Composition, not a new action: an ignition trigger plus `PLAY_RADIO`, whose `srcPlayRadio` resumes the last station by itself. A persistent service that remembered and re-asserted state would be a background watchdog the app does not have and does not want. |
38
38
| G | Radio artwork caching, station metadata display |**reject as an action**| Presentation, not automation. A rule cannot usefully "cache artwork"; a screen can show it. If it is ever wanted it belongs to an app's UI, reading `RadioBean`, not to the action catalogue. |
39
39
| H | Replace or patch the OEM radio APK (the DAB+ fix's strategy) |**reject**| Out of scope by the ticket and by the suite's boundary: EVSuite talks to the vendor services the car ships. It does not swap the car's applications, and the upstream fix carries no license that would permit reuse anyway. |
@@ -55,6 +55,14 @@ a missing service call, is the actual gap.
55
55
`ActionCompatibility` refuses the action there before it is attempted, and the editor does
56
56
not offer it.
57
57
58
+
## Reversal, 2026-08-29
59
+
60
+
Candidate D was reopened at the owner's request after an on-vehicle diagnostic (SWI68). The
61
+
original rejection assumed a band action required a band-only transaction, and that assumption
62
+
was wrong: `tune` takes the band as an argument, so the band is reachable through a call that
63
+
was already proven. The rejection of candidate E stands unchanged — a DAB service still has no
64
+
identifier stable across a re-scan, and none was guessed.
65
+
58
66
## On-vehicle evidence
59
67
60
68
_(pending — CR-020 requires a run. Record, per firmware: `SaicRadio.isAvailable`, whether
0 commit comments