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.
5.8 KiB
Delta for Android Auto Media — Local Music Phase 3 (Folder Queue + Shuffle)
ADDED Requirements
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/skipToPreviousis 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
Out of Scope (explicit boundary — not requirements of this change)
- Recursive whole-subtree queueing; only a folder's direct audio children are queued.
- OS-level shuffle-mode toggle (
AudioService.setShuffleMode); shuffle is exposed only as a browsable action. - Repeat modes.
- Cross-folder, persisted, or resumable queues; queue-reordering UI.