Local tracks now show embedded title/artist/album art (via native MediaMetadataRetriever, cached through the existing FileProvider) instead of the raw filename, falling back gracefully when a file has no usable tags. Adds two navigable entry points per folder: sort by audio quality (bitrate, capped at 150 tracks per folder to bound worst-case latency) and alphabetical name buckets -- the closest realistic form of "filtering" given Android Auto has no text-search UI in this integration. Metadata resolves only for the page actually being browsed (same slice-cheap-then-map discipline as the paging change), backed by a flat 256-entry LRU session cache that survives across pages. No new permission, no new pub dependency, no l10n changes (car-tree labels stay hardcoded Spanish, matching every existing label in the tree).
6.0 KiB
Delta for Android Auto Media
MODIFIED Requirements
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. 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
getChildrenis called with the local-music root folder id - THEN it returns the root's immediate subfolders as
carpeta_local:<id>items and audio files aspista:<id>playable items - AND each playable item's title reflects resolved metadata when available, else the file's raw filename
Scenario: Car browses a nested subfolder
- GIVEN a
carpeta_local:<id>folder returned from a prior browse call - WHEN
getChildrenis called with that folder id - 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
titleandartUrireflect 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
ADDED Requirements
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
artUripoints 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
artUrifalls back to the same rotating placeholder used in Phase 1 - AND no broken, empty, or indefinitely-loading art tile is shown
Out of Scope (Phase 2)
The following are explicitly deferred and MUST NOT be treated as Phase 2 requirements: local-folder subfolder-scoping refinements, shuffle playback, live text search, and voice search (audio_service.onSearch). These remain candidates for Phase 3 or later.