docs(openspec): archive android-auto-local-music-phase3
Build & Deploy PluriWave / Análisis de código (push) Successful in 28s
Build & Deploy PluriWave / Build APK + AAB release (push) Failing after 1m18s

Merges its delta requirements into the android-auto-media base spec.
Completes the 3-phase local-music-in-Android-Auto feature. Standing
pre-release gate: on-device/DHU validation of every native surface
built across all 4 phases (SAF picking, metadata extraction, art
cache, queue/shuffle handler wiring) is still outstanding.
This commit is contained in:
2026-07-20 01:15:46 +02:00
parent dfd40ca937
commit 49def4b276
8 changed files with 284 additions and 1 deletions
+105
View File
@@ -452,3 +452,108 @@ Play/pause/stop state changes MUST remain synchronized between the car head unit
- GIVEN a station is playing and projected to the car
- WHEN the user pauses from the phone UI
- THEN the car head unit reflects the paused state via the same shared session
### Requirement: Folder-Scoped Sequential Play Action
The local-music browse tree MUST prepend a "Reproducir carpeta" playable item on page 0 of any local folder that has at least one direct audio-file child (`NodoLocal` non-directory). Selecting it MUST build a queue of that folder's direct audio children in filename order and start sequential playback.
#### Scenario: Folder has tracks
- GIVEN a local folder has one or more direct audio-file children
- WHEN page 0 is browsed
- THEN "Reproducir carpeta" is prepended, and selecting it plays those tracks in name order
#### Scenario: Folder has no tracks
- GIVEN a local folder has zero direct audio-file children
- WHEN page 0 is browsed
- THEN no "Reproducir carpeta" item is returned
### Requirement: Folder-Scoped Shuffled Play Action
The local-music browse tree MUST prepend a "Reproducir aleatorio" playable item alongside "Reproducir carpeta", under the same folder-has-tracks condition. Selecting it MUST build a queue of the same direct-audio-children set in shuffled order and start playback.
#### Scenario: Folder has tracks
- GIVEN a local folder has one or more direct audio-file children
- WHEN page 0 is browsed
- THEN "Reproducir aleatorio" is prepended, and selecting it plays the same set shuffled
#### Scenario: Deterministic under seed
- GIVEN a fixed shuffle seed is injected for testing
- WHEN the queue is built for a given track set
- THEN the resulting order is reproducible across runs with that seed
### Requirement: Local Queue Auto-Advance and Transport Skip
While a local-music queue (from either action) is active, `PluriWaveAudioHandler` MUST auto-advance to the next queued track when the current track finishes, and MUST move within the queue when `skipToNext`/`skipToPrevious` is invoked.
#### Scenario: Track completes mid-queue
- GIVEN the current track is not the last one in the queue
- WHEN it finishes
- THEN the handler advances to and plays the next track automatically
#### Scenario: Skip within queue
- GIVEN a local-music queue is active
- WHEN `skipToNext`/`skipToPrevious` is invoked, including at the first or last track
- THEN the queue index moves accordingly and the corresponding track plays without throwing
### Requirement: Local Queue Mode Isolation From Radio Playback (Regression Guard — CRITICAL)
The local-music queue mechanism (auto-advance, skip-within-queue, queue state) MUST be scoped by an explicit mode boundary and MUST NEVER activate for, interfere with, or alter radio playback, reconnection, or any other non-local-music playback path. Switching between an active local queue and radio playback, in either direction, MUST cleanly stop/replace the previously active mode. This is the highest-priority regression requirement of this change.
#### Scenario: Radio starts while a local queue is active
- GIVEN a local-music queue is actively auto-advancing
- WHEN the user selects a station (`emisora:<uuid>`) or a radio-group entry
- THEN the local queue mode stops cleanly (no further auto-advance or skip behavior leaks)
- AND radio playback starts and behaves exactly as before this feature, including reconnection
#### Scenario: Local queue starts while radio is active
- GIVEN a station is currently playing
- WHEN the user selects "Reproducir carpeta" or "Reproducir aleatorio"
- THEN radio playback and its reconnect state exit cleanly
- AND the local-music queue starts playing with auto-advance/skip active
#### Scenario: Radio reconnect logic is provably untouched
- GIVEN no local-music queue has been started in the current session
- WHEN a live stream stalls and reconnects, or errors
- THEN reconnect behavior is byte-identical to pre-feature behavior, since `ProcessingState.completed` (the queue-advance trigger) never fires for radio streams
#### Scenario: Single-track local playback (`pista:<id>`) is unaffected
- GIVEN the user taps a single track directly, not via a folder-play action
- WHEN that track finishes
- THEN no queue auto-advance occurs, matching existing Phase 1/2 single-track behavior
### Requirement: Local Queue End-of-Queue Behavior
When the last track in an active local-music queue finishes, playback MUST stop cleanly rather than loop back to the first track or leave the handler in an inconsistent state, consistent with repeat modes being out of scope for this phase.
#### Scenario: Last track finishes
- GIVEN the current track is the last one in the queue
- WHEN it finishes
- THEN playback stops with no wraparound to the first track
- AND handler state remains consistent for a subsequent, independent play action
### Requirement: New Action Media-IDs Are Collision-Free
The media-ids for "Reproducir carpeta" and "Reproducir aleatorio" MUST use prefixes distinct from every existing media-id family: `emisora:`, `grupo:`, `eq_preset:`, `carpeta_local:`, `carpeta_local_pag:`, `carpeta_local_ord:`, `carpeta_local_bucket:`, `pista:`.
#### Scenario: Prefix uniqueness
- GIVEN the full set of existing prefixes plus the two new action prefixes
- WHEN each prefix is compared against every other
- THEN none duplicates or substring-collides with another
#### Scenario: Raw documentIds with `:`/`/` survive round-trip
- GIVEN a folder's SAF documentId contains `:` or `/` characters
- WHEN an action media-id is encoded and later decoded via `playFromMediaId`
- THEN the original documentId is recovered verbatim, reusing the existing strip-by-length + split-on-first-colon codec