Commit bbb739d1 by tonihei Committed by Oliver Woodman

Fix playback speed in MediaSessionConnector

The playback speed set in MediaSession's PlaybackStateCompat needs to be the
actual speed at which the playback position progresses and not the user-defined
target speed.

This fixed a bug where the position advances although the player lost audio
focus.

Issue:#6203
PiperOrigin-RevId: 269295249
parent f8d81d05
......@@ -131,6 +131,15 @@ public final class MediaSessionConnector {
/** The default rewind increment, in milliseconds. */
public static final int DEFAULT_REWIND_MS = 5000;
/**
* The name of the {@link PlaybackStateCompat} float extra with the value of {@link
* PlaybackParameters#speed}.
*/
public static final String EXTRAS_SPEED = "EXO_SPEED";
/**
* The name of the {@link PlaybackStateCompat} float extra with the value of {@link
* PlaybackParameters#pitch}.
*/
public static final String EXTRAS_PITCH = "EXO_PITCH";
private static final long BASE_PLAYBACK_ACTIONS =
......@@ -684,7 +693,13 @@ public final class MediaSessionConnector {
public final void invalidateMediaSessionPlaybackState() {
PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();
if (player == null) {
builder.setActions(buildPrepareActions()).setState(PlaybackStateCompat.STATE_NONE, 0, 0, 0);
builder
.setActions(buildPrepareActions())
.setState(
PlaybackStateCompat.STATE_NONE,
/* position= */ 0,
/* playbackSpeed= */ 0,
/* updateTime= */ SystemClock.elapsedRealtime());
mediaSession.setPlaybackState(builder.build());
return;
}
......@@ -699,15 +714,13 @@ public final class MediaSessionConnector {
}
customActionMap = Collections.unmodifiableMap(currentActions);
int playbackState = player.getPlaybackState();
Bundle extras = new Bundle();
ExoPlaybackException playbackError =
playbackState == Player.STATE_IDLE ? player.getPlaybackError() : null;
@Nullable ExoPlaybackException playbackError = player.getPlaybackError();
boolean reportError = playbackError != null || customError != null;
int sessionPlaybackState =
reportError
? PlaybackStateCompat.STATE_ERROR
: mapPlaybackState(player.getPlaybackState(), player.getPlayWhenReady());
: getMediaSessionPlaybackState(player.getPlaybackState(), player.getPlayWhenReady());
if (customError != null) {
builder.setErrorMessage(customError.first, customError.second);
if (customErrorExtras != null) {
......@@ -722,6 +735,10 @@ public final class MediaSessionConnector {
? queueNavigator.getActiveQueueItemId(player)
: MediaSessionCompat.QueueItem.UNKNOWN_ID;
extras.putFloat(EXTRAS_PITCH, player.getPlaybackParameters().pitch);
PlaybackParameters playbackParameters = player.getPlaybackParameters();
extras.putFloat(EXTRAS_SPEED, playbackParameters.speed);
extras.putFloat(EXTRAS_PITCH, playbackParameters.pitch);
float sessionPlaybackSpeed = player.isPlaying() ? playbackParameters.speed : 0f;
builder
.setActions(buildPrepareActions() | buildPlaybackActions(player))
.setActiveQueueItemId(activeQueueItemId)
......@@ -729,8 +746,8 @@ public final class MediaSessionConnector {
.setState(
sessionPlaybackState,
player.getCurrentPosition(),
player.getPlaybackParameters().speed,
SystemClock.elapsedRealtime())
sessionPlaybackSpeed,
/* updateTime= */ SystemClock.elapsedRealtime())
.setExtras(extras);
mediaSession.setPlaybackState(builder.build());
}
......@@ -823,19 +840,6 @@ public final class MediaSessionConnector {
return actions;
}
private int mapPlaybackState(int exoPlayerPlaybackState, boolean playWhenReady) {
switch (exoPlayerPlaybackState) {
case Player.STATE_BUFFERING:
return PlaybackStateCompat.STATE_BUFFERING;
case Player.STATE_READY:
return playWhenReady ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
case Player.STATE_ENDED:
return PlaybackStateCompat.STATE_STOPPED;
default:
return PlaybackStateCompat.STATE_NONE;
}
}
private boolean canDispatchPlaybackAction(long action) {
return player != null && (enabledPlaybackActions & action) != 0;
}
......@@ -888,6 +892,20 @@ public final class MediaSessionConnector {
controlDispatcher.dispatchSeekTo(player, windowIndex, positionMs);
}
private static int getMediaSessionPlaybackState(
@Player.State int exoPlayerPlaybackState, boolean playWhenReady) {
switch (exoPlayerPlaybackState) {
case Player.STATE_BUFFERING:
return PlaybackStateCompat.STATE_BUFFERING;
case Player.STATE_READY:
return playWhenReady ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
case Player.STATE_ENDED:
return PlaybackStateCompat.STATE_STOPPED;
default:
return PlaybackStateCompat.STATE_NONE;
}
}
/**
* Provides a default {@link MediaMetadataCompat} with properties and extras taken from the {@link
* MediaDescriptionCompat} of the {@link MediaSessionCompat.QueueItem} of the active queue item.
......@@ -1023,6 +1041,11 @@ public final class MediaSessionConnector {
}
@Override
public void onIsPlayingChanged(boolean isPlaying) {
invalidateMediaSessionPlaybackState();
}
@Override
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
mediaSession.setRepeatMode(
repeatMode == Player.REPEAT_MODE_ONE
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment