docs(openspec): archive android-auto-local-music-phase2

Merges its delta requirements into the android-auto-media base spec.
Completes Phase 2; only Phase 3 (subfolder scoping, shuffle) remains.
On-device validation of the native metadata path is still an
outstanding pre-release gate across all local-music phases shipped
today.
This commit is contained in:
2026-07-19 23:59:21 +02:00
parent 352eb9fc37
commit 85dd043cd4
8 changed files with 208 additions and 4 deletions
+73 -2
View File
@@ -197,14 +197,15 @@ The system MUST let the user select a local-music root folder via SAF (`ACTION_O
### Requirement: Local Music Browsable Tree
The Android Auto browse tree MUST expose a new non-playable local-music root folder alongside the existing station folders. Browsing that root and any nested subfolder MUST recursively mirror the picked SAF folder's structure: subfolders as non-playable `carpeta_local:<id>` items and audio files as playable `pista:<id>` items resolving to `PistaLocal` instances, using the raw filename as the displayed title.
The Android Auto browse tree MUST expose a new non-playable local-music root folder alongside the existing station folders. Browsing that root and any nested subfolder MUST recursively mirror the picked SAF folder's structure: subfolders as non-playable `carpeta_local:<id>` items and audio files as playable `pista:<id>` items resolving to `PistaLocal` instances. When embedded metadata (title and/or album art) can be resolved for a track on the requested page, the displayed title and art MUST reflect that metadata instead of the raw filename and generic placeholder art. When metadata is unavailable, unparseable, or resolution otherwise fails, the item MUST fall back to the raw filename as title and the existing generic placeholder art, exactly as in Phase 1.
(Previously: always used the raw filename as the displayed title, with no metadata resolution.)
#### Scenario: Car browses the local-music root
- GIVEN a local music root folder was picked and its permission is valid
- WHEN `getChildren` is called with the local-music root folder id
- THEN it returns the root's immediate subfolders as `carpeta_local:<id>` items and audio files as `pista:<id>` playable items
- AND each playable item's title is the file's raw filename
- AND each playable item's title reflects resolved metadata when available, else the file's raw filename
#### Scenario: Car browses a nested subfolder
@@ -213,6 +214,76 @@ The Android Auto browse tree MUST expose a new non-playable local-music root fol
- THEN it returns that subfolder's own contents (nested folders and/or tracks), recursively mirroring the on-device structure
- AND browsing an empty subfolder returns an empty list, not an error
#### Scenario: Track has embedded metadata
- GIVEN an audio file on the requested page has parseable embedded title and/or album art
- WHEN it is mapped to a playable `pista:<id>` `MediaItem`
- THEN its `title` and `artUri` reflect the resolved metadata, not the raw filename or generic placeholder
#### Scenario: Metadata unavailable or resolution fails (graceful fallback)
- GIVEN an audio file's embedded metadata is absent, corrupt, in an unsupported format, or blocked by a permission edge case
- WHEN it is mapped to a playable `pista:<id>` `MediaItem`
- THEN its title falls back to the raw filename and its art falls back to the generic placeholder, exactly as in Phase 1
- AND no exception propagates from metadata resolution, and the rest of that page's items are still returned
### Requirement: Local Music Sort Mode Navigation
The local-music browse tree MUST expose sort mode as navigable, non-playable browse-tree entries (at least "by name" and "by audio quality") for a folder's tracks, since the underlying legacy browse surface cannot re-sort an already-rendered folder in place. Selecting a sort-mode entry MUST return that folder's tracks ordered accordingly: name sort orders by filename; quality sort orders by bitrate descending, reusing the existing `ordenarEmisoras(..., OrdenEmisoras.calidad)` comparator shape.
#### Scenario: Sort-mode entries are available for a folder
- GIVEN the user is browsing a local-music folder containing tracks
- WHEN that folder's sort-mode navigation is requested
- THEN at least a "by name" and a "by audio quality" navigable entry are returned
#### Scenario: User selects sort by quality
- GIVEN the user selects the "by audio quality" entry for a folder
- WHEN its children are resolved
- THEN the folder's tracks are returned ordered by bitrate descending
- AND tracks with unknown bitrate are ordered consistently, without throwing
#### Scenario: User selects sort by name
- GIVEN the user selects the "by name" entry for a folder
- WHEN its children are resolved
- THEN the folder's tracks are returned ordered by filename
### Requirement: Local Music Alphabetical Name Buckets
The local-music browse tree MUST expose alphabetical name-bucket entries (e.g. A-F, G-M, ...) as navigable, non-playable folders for a folder's tracks, as the Phase 2 realization of name-based filtering — the underlying legacy `MediaBrowserService` surface does not support a live text-search box.
#### Scenario: User browses name buckets for a folder
- GIVEN a local-music folder contains tracks spanning multiple starting letters
- WHEN the user browses that folder's name-bucket navigation level
- THEN each returned bucket is a non-playable folder covering a contiguous letter range
- AND selecting a bucket returns only the tracks whose name falls within that range
#### Scenario: Bucket with no matching tracks
- GIVEN a name-bucket range that currently matches zero tracks in a folder
- WHEN that bucket is browsed
- THEN it returns an empty list, not an error
### Requirement: Local Track Embedded Album Art Display
A playable `pista:<id>` `MediaItem` MUST display embedded album art via `artUri` when the track's embedded picture can be resolved and served as a static URI. When embedded art is absent or cannot be resolved (per the browse tree's metadata-resolution fallback), the item MUST fall back to Phase 1's existing generic rotating placeholder art (`station_art_*` rotation). The car head unit MUST NOT display an empty or broken art tile for any local track.
#### Scenario: Track has embedded album art
- GIVEN an audio file on the requested page has a resolvable embedded picture
- WHEN it is mapped to a playable `MediaItem`
- THEN `artUri` points at the resolved embedded art, served as a static URI
#### Scenario: Track has no or unresolvable embedded art
- GIVEN an audio file has no embedded picture, or it cannot be parsed or served
- WHEN it is mapped to a playable `MediaItem`
- THEN `artUri` falls back to the same rotating placeholder used in Phase 1
- AND no broken, empty, or indefinitely-loading art tile is shown
### Requirement: Local Track Playback Reuses Existing Pipeline
Selecting a `pista:<id>` item MUST resolve to the corresponding `PistaLocal` and play it through the existing `playMediaItem`/`PluriWaveAudioHandler` pipeline, unchanged, including the shared EQ signal chain.