fix(audio): keep custom actions out of the media notification controls
The equalizer toggle appended to the transport controls was aborting the whole notification. controls feeds BOTH the phone notification and the car playback screen, and AudioService.setState walks every control through createCustomAction (AudioService.java:513-520) BEFORE reaching mediaSession.setPlaybackState (:552) and enterPlayingState (:559) -- the only place the notification is ever posted. createCustomAction resolves the icon by name via getIdentifier (:415-420), which returns 0 on a miss, and passes it to PlaybackStateCompat.CustomAction.Builder, which throws on a 0 icon or an empty label. That throw aborts setState, so the media session is never published: no shade widget, no lock-screen controls, not even the small status-bar icon. ExoPlayer runs independently so audio keeps playing, and until asyncError got a subscriber the exception was dropped silently. Nothing is lost in the car: the Ecualizador browse folder already lists Desactivar plus every preset by name, which is Auto's own idiom for choosing among options.
This commit is contained in:
@@ -637,6 +637,29 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
/// [MediaControl.skipToPrevious]/play-pause/stop/[MediaControl.skipToNext]
|
||||
/// at their existing indices 0-3, so `androidCompactActionIndices`
|
||||
/// (`[colaActiva ? 1 : 0]`) stays correct unchanged.
|
||||
/// NOTHING custom goes in this list. `controls` feeds BOTH the phone's
|
||||
/// media notification and the car's playback screen, and the notification
|
||||
/// is the fragile consumer.
|
||||
///
|
||||
/// `AudioService.setState` (AudioService.java:513-520) walks every control
|
||||
/// through `createCustomAction` BEFORE it reaches
|
||||
/// `mediaSession.setPlaybackState` (:552) and `enterPlayingState()` (:559),
|
||||
/// which is the ONLY place the notification is ever posted.
|
||||
/// `createCustomAction` resolves the icon by name via
|
||||
/// `getResources().getIdentifier(...)` (:415-420) — which returns 0 on a
|
||||
/// miss — and hands it to `PlaybackStateCompat.CustomAction.Builder`, which
|
||||
/// throws on a 0 icon or an empty label. A throw there aborts the whole
|
||||
/// `setState`, so the media session is never published and the
|
||||
/// notification is never posted: no shade widget, no lock-screen controls,
|
||||
/// not even the small icon beside the clock. Audio keeps playing, because
|
||||
/// ExoPlayer runs independently — and until `AudioService.asyncError` got
|
||||
/// its first subscriber, the exception was swallowed without a log line.
|
||||
///
|
||||
/// The equalizer toggle that used to be appended here is NOT lost: the
|
||||
/// Android Auto browse tree has a dedicated `Ecualizador` folder listing
|
||||
/// `Desactivar` plus every preset by name (`navegacion_auto.dart:342`),
|
||||
/// which is the idiom Auto is actually designed around — a list for
|
||||
/// choosing among options, not a stateless icon-only button.
|
||||
List<MediaControl> _controlesTransporte({
|
||||
required bool colaActiva,
|
||||
required bool playing,
|
||||
@@ -645,23 +668,16 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
if (playing) MediaControl.pause else MediaControl.play,
|
||||
MediaControl.stop,
|
||||
if (colaActiva) MediaControl.skipToNext,
|
||||
..._controlesEqPersonalizados(),
|
||||
];
|
||||
|
||||
List<MediaControl> _controlesEqPersonalizados() =>
|
||||
controlesEcualizadorPersonalizados(
|
||||
disponible: _eqDisponible,
|
||||
activo: _ecualizadorActivo,
|
||||
l10n: _textos,
|
||||
);
|
||||
|
||||
/// Re-pushes `playbackState` with a freshly built controls list (item 4):
|
||||
/// called whenever EQ availability/enabled/preset state changes outside a
|
||||
/// player-state transition (a custom-action tap, or a phone-side preset/
|
||||
/// toggle change), so the equalizer custom actions' label and current-
|
||||
/// preset name stay in sync on the now-playing screen without waiting for
|
||||
/// an unrelated player event. Idempotent and cheap (no native calls) —
|
||||
/// safe to call from any EQ state-changing path.
|
||||
/// Re-pushes `playbackState` with a freshly built controls list.
|
||||
///
|
||||
/// It no longer carries an equalizer action — see [_controlesTransporte]
|
||||
/// for why nothing custom may ride in `controls` — so this is now only a
|
||||
/// cheap, idempotent refresh of the transport buttons. Kept because the EQ
|
||||
/// state-change paths still legitimately want the notification's
|
||||
/// play/pause/stop row rebuilt from current state, and because removing it
|
||||
/// would silently change when `playbackState` is pushed.
|
||||
void _actualizarControlesEq() {
|
||||
playbackState.add(
|
||||
playbackState.value.copyWith(
|
||||
|
||||
Reference in New Issue
Block a user