# Delta for Android Auto Media ## MODIFIED Requirements ### Requirement: Browsable Media Tree For a user holding premium entitlement, `getChildren` MUST return a browsable tree rooted at `AudioService.browsableRootId`, organized into non-playable folders (Favoritos, Todas las emisoras, Mis emisoras, Ecualizador, and the local-music root) containing playable items. Playable station items SHOULD carry an audio-quality subtitle when known. The `Favoritos` folder additionally MAY contain non-playable favorite-group sub-folders (see "Favorite Group Sub-Folders"); `Todas las emisoras` and `Mis emisoras` remain flat. The `Ecualizador` folder is flat, non-playable, and contains only the 6 fixed EQ preset items (see "EQ Preset Browsable Folder"). The local-music root folder is non-playable and may itself be nested (see "Local Music Browsable Tree"). For a free-tier (non-premium) user, this full tree is NOT exposed; see "Free-Tier Reduced Root Browse" for the entitlement-aware equivalent. (Previously: root contained exactly 3 folders — Favoritos, Todas las emisoras, Mis emisoras — with no EQ or local-music folder; Favoritos was a flat folder of playable station items only, with no sub-folder nesting; there was no entitlement distinction.) #### Scenario: Car requests the root (premium) - GIVEN the user holds premium entitlement and the car head unit connects and requests the root (`AudioService.browsableRootId`) - WHEN `getChildren` is called with the root id - THEN it returns five folder `MediaItem`s (Favoritos, Todas las emisoras, Mis emisoras, Ecualizador, and the local-music root), each with `playable: false` #### Scenario: Car requests a folder with no stations (premium) - GIVEN the user holds premium entitlement and has zero favorite stations - WHEN `getChildren` is called with the Favoritos folder id - THEN it returns an empty list, not an error #### Scenario: Browse requested before app state is loaded (premium) - GIVEN the user holds premium entitlement and the audio handler starts cold and station/favorites Provider state has not finished loading - WHEN `getChildren` is called (root or any folder) - THEN it returns a valid, possibly empty, list without throwing and without blocking or crashing the service #### Scenario: Station has known codec and bitrate - GIVEN a station's `Emisora.codec` and `Emisora.bitrate` are both known (non-null) - WHEN it is mapped to a playable `MediaItem` - THEN `displaySubtitle` SHALL contain a human-readable quality hint combining bitrate and codec (e.g. "128 kbps · MP3") #### Scenario: Station has unknown codec or bitrate - GIVEN a station's `Emisora.codec` or `Emisora.bitrate` (or both) is null/unknown - WHEN it is mapped to a playable `MediaItem` - THEN `displaySubtitle` SHALL omit the quality hint gracefully (no subtitle, or a subtitle with no quality fragment) - AND the subtitle MUST NOT render literal placeholder text such as "null kbps" or "null · null" #### Scenario: Ungrouped station appears exactly as before (regression guard) - GIVEN a station's `Emisora.grupoFavoritosId` equals `GrupoFavoritos.sinAsignarId` (`'sin_asignar'`, the default when no group is assigned), and the browsing user holds premium entitlement - WHEN the `Favoritos`, `Todas las emisoras`, or `Mis emisoras` folders are browsed - THEN that station appears as a playable `emisora:` item in exactly the same folder(s), position (subject to existing sort rules), title, art, and subtitle as it did before favorite-group folders were introduced - AND its presence and shape are unaffected by the existence, emptiness, or content of any favorite group ## ADDED Requirements ### Requirement: Free-Tier Reduced Root Browse For a free-tier (non-premium) user, `getChildren` at the root MUST NOT return the full folder tree. Instead it MUST return a non-blank list whose items each represent one of the normally-browsable folders (Favoritos, Todas las emisoras, Mis emisoras, Ecualizador, local-music root) rendered as a non-playable, explicitly locked item labeled as a premium feature (e.g. title "Función Premium"). A blank or empty root/folder response for a free-tier user is forbidden. #### Scenario: Free-tier user requests the root - GIVEN a free-tier (non-premium) user's car head unit requests the root - WHEN `getChildren` is called with the root id - THEN it returns non-playable locked items labeled as premium features, one per normally-browsable folder, and never an empty list #### Scenario: Free-tier user selects a locked item - GIVEN a free-tier user is shown a locked "Función Premium" item - WHEN they select it - THEN no real folder content or station list is returned, and no crash or unhandled exception occurs ### Requirement: Free-Tier Browse Never Leaks Real Content (Authoritative Backstop) Even if `getChildren` receives a stale or deep-linked folder id that would resolve to real station or local-music content, for a free-tier (non-premium) user it MUST NOT return that real content. This check MUST be enforced at the `getChildren`/`navegacion_auto.dart` choke point itself, independent of which UI path reached it. #### Scenario: Stale folder id bypass attempt - GIVEN a free-tier user's car client holds a cached `emisora:` or folder id from before downgrade or from another device - WHEN `getChildren`/`playFromMediaId` is called with that id - THEN the authoritative entitlement check at the choke point blocks real content or playback from being returned, regardless of the id's validity ### Requirement: Current-Station Playback Unaffected By Free Tier Regardless of entitlement, transport controls (play/pause/stop) for whatever station is already loaded or playing MUST keep working for a free-tier user in the car. Only browsing/switching to a different station and local music are restricted by the free tier. #### Scenario: Free-tier user controls the current station - GIVEN a free-tier user already has a station loaded or playing when connecting to the car - WHEN they use play/pause/stop from the car head unit - THEN the command is honored exactly as for a premium user #### Scenario: Free-tier user cannot switch stations via browse - GIVEN a free-tier user is currently playing a station - WHEN they attempt to browse to a different station via the root tree - THEN they see only the locked "Función Premium" items, not a station list, and cannot switch stations that way