fix(auto): advertise the transport actions Android for Cars requires
Reported: on the Android Auto playback screen the play/pause button stays
on PLAY while audio is audibly playing, and "it used to work, in the
latest versions it doesn't".
Previous rounds looked for a regression in this repo's audio commits and
found none: every playbackState.add site publishes playing:true with a
ready processingState, and AudioService.getPlaybackState maps that to
STATE_PLAYING. That search was aimed at the wrong thing.
The Android for Cars guide ("Enable playback control") is explicit:
"Android Auto and AAOS display playback controls based on the actions
that are enabled in the PlaybackStateCompat object. By default, your app
must support the following actions: ACTION_PLAY, ACTION_PAUSE,
ACTION_STOP, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH."
systemActions has carried only `seek` + `stop` since e9d1f67, the first
commit of the project -- git log -S confirms it was never once edited. So
the required actions have never been advertised, and no audio commit can
explain a change in behaviour. Android Auto ships as its own app and
updates itself, which is how a working screen breaks with a clean repo
history. That fits the report better than any commit here does.
The phone notification was never affected: it builds its play/pause
button from `controls`, not from these bits, which is exactly why the
symptom is car-only.
Skip actions stay conditional on an active queue on purpose -- the same
guide notes Auto reserves the prev/next slots for them and gives the
space to custom actions when the app does not support them, and that is
the space the equalizer toggle needs.
ACTION_PLAY_FROM_SEARCH is now implemented rather than merely claimed:
advertising it unimplemented would have the car's assistant accept "play
Radio X" and silently do nothing. emisoraParaBusqueda ranks exact name,
then prefix, then substring, then country, accent- and case-insensitive
because voice transcription rarely gets diacritics right; favourites are
searched first so they win a name tie, and a miss plays nothing rather
than something arbitrary.
Still a hypothesis for the play/pause symptom, not a confirmed fix -- it
is documentation-backed and cheap, but only a head unit can confirm it.
Tests: 1132 -> 1141.
This commit is contained in:
@@ -709,9 +709,32 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
colaActiva: colaActiva,
|
||||
playing: playing,
|
||||
),
|
||||
// Android for Cars, "Enable playback control": «Android Auto and
|
||||
// AAOS display playback controls based on the actions that are
|
||||
// enabled in the PlaybackStateCompat object. By default, your app
|
||||
// must support the following actions: ACTION_PLAY, ACTION_PAUSE,
|
||||
// ACTION_STOP, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH.»
|
||||
//
|
||||
// This set had carried only `seek` + `stop` since the very first
|
||||
// commit, so the required transport actions were never advertised.
|
||||
// The car got away with it for a long time — but Android Auto is a
|
||||
// separate app that updates itself, so a tolerance it used to have
|
||||
// can disappear without a single line changing on our side. That
|
||||
// matches the report exactly: "it used to work, and in the latest
|
||||
// versions it doesn't", with no audio commit in between that could
|
||||
// explain it.
|
||||
//
|
||||
// The phone notification never depended on any of this: it builds
|
||||
// its play/pause button from `controls`, which is why the symptom
|
||||
// is car-only.
|
||||
systemActions: {
|
||||
MediaAction.seek,
|
||||
MediaAction.play,
|
||||
MediaAction.pause,
|
||||
MediaAction.playPause,
|
||||
MediaAction.stop,
|
||||
MediaAction.playFromMediaId,
|
||||
MediaAction.playFromSearch,
|
||||
MediaAction.seek,
|
||||
if (colaActiva) MediaAction.skipToPrevious,
|
||||
if (colaActiva) MediaAction.skipToNext,
|
||||
},
|
||||
@@ -1622,6 +1645,42 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// Voice search from the car ("pon Radio Clásica").
|
||||
///
|
||||
/// `ACTION_PLAY_FROM_SEARCH` is one of the actions Android for Cars
|
||||
/// documents as required, and it is now advertised in `systemActions` — so
|
||||
/// it has to actually do something. Advertising it unimplemented would be
|
||||
/// worse than omitting it: the assistant would accept the command and
|
||||
/// nothing would play, with no error to explain it.
|
||||
///
|
||||
/// Favourites first, then my stations, then the full list, so a station the
|
||||
/// driver already cares about wins a name tie. Never throws and never plays
|
||||
/// something arbitrary on a miss — see [emisoraParaBusqueda].
|
||||
@override
|
||||
Future<void> playFromSearch(
|
||||
String query, [
|
||||
Map<String, dynamic>? extras,
|
||||
]) async {
|
||||
try {
|
||||
final fuente = _fuenteNavegacionGlobal;
|
||||
if (fuente == null) return;
|
||||
final candidatas = <Emisora>[
|
||||
...await fuente.favoritos(),
|
||||
...await fuente.misEmisoras(),
|
||||
...await fuente.todas(),
|
||||
];
|
||||
final emisora = emisoraParaBusqueda(query, candidatas);
|
||||
if (emisora == null) return;
|
||||
await playMediaItem(mediaItemParaEmisora(emisora, l10n: _textos));
|
||||
} catch (e) {
|
||||
developer.log(
|
||||
'[PluriWave] Error en playFromSearch($query): $e',
|
||||
name: 'ServicioAudio',
|
||||
level: 900,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> playFromMediaId(
|
||||
String mediaId, [
|
||||
|
||||
Reference in New Issue
Block a user