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
This commit is contained in:
tonihei 2019-09-16 11:26:44 +01:00 committed by Oliver Woodman
parent f8d81d05a4
commit bbb739d1de

View File

@ -131,6 +131,15 @@ public final class MediaSessionConnector {
/** The default rewind increment, in milliseconds. */ /** The default rewind increment, in milliseconds. */
public static final int DEFAULT_REWIND_MS = 5000; 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"; public static final String EXTRAS_PITCH = "EXO_PITCH";
private static final long BASE_PLAYBACK_ACTIONS = private static final long BASE_PLAYBACK_ACTIONS =
@ -684,7 +693,13 @@ public final class MediaSessionConnector {
public final void invalidateMediaSessionPlaybackState() { public final void invalidateMediaSessionPlaybackState() {
PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder(); PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();
if (player == null) { 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()); mediaSession.setPlaybackState(builder.build());
return; return;
} }
@ -699,15 +714,13 @@ public final class MediaSessionConnector {
} }
customActionMap = Collections.unmodifiableMap(currentActions); customActionMap = Collections.unmodifiableMap(currentActions);
int playbackState = player.getPlaybackState();
Bundle extras = new Bundle(); Bundle extras = new Bundle();
ExoPlaybackException playbackError = @Nullable ExoPlaybackException playbackError = player.getPlaybackError();
playbackState == Player.STATE_IDLE ? player.getPlaybackError() : null;
boolean reportError = playbackError != null || customError != null; boolean reportError = playbackError != null || customError != null;
int sessionPlaybackState = int sessionPlaybackState =
reportError reportError
? PlaybackStateCompat.STATE_ERROR ? PlaybackStateCompat.STATE_ERROR
: mapPlaybackState(player.getPlaybackState(), player.getPlayWhenReady()); : getMediaSessionPlaybackState(player.getPlaybackState(), player.getPlayWhenReady());
if (customError != null) { if (customError != null) {
builder.setErrorMessage(customError.first, customError.second); builder.setErrorMessage(customError.first, customError.second);
if (customErrorExtras != null) { if (customErrorExtras != null) {
@ -722,6 +735,10 @@ public final class MediaSessionConnector {
? queueNavigator.getActiveQueueItemId(player) ? queueNavigator.getActiveQueueItemId(player)
: MediaSessionCompat.QueueItem.UNKNOWN_ID; : MediaSessionCompat.QueueItem.UNKNOWN_ID;
extras.putFloat(EXTRAS_PITCH, player.getPlaybackParameters().pitch); 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 builder
.setActions(buildPrepareActions() | buildPlaybackActions(player)) .setActions(buildPrepareActions() | buildPlaybackActions(player))
.setActiveQueueItemId(activeQueueItemId) .setActiveQueueItemId(activeQueueItemId)
@ -729,8 +746,8 @@ public final class MediaSessionConnector {
.setState( .setState(
sessionPlaybackState, sessionPlaybackState,
player.getCurrentPosition(), player.getCurrentPosition(),
player.getPlaybackParameters().speed, sessionPlaybackSpeed,
SystemClock.elapsedRealtime()) /* updateTime= */ SystemClock.elapsedRealtime())
.setExtras(extras); .setExtras(extras);
mediaSession.setPlaybackState(builder.build()); mediaSession.setPlaybackState(builder.build());
} }
@ -823,19 +840,6 @@ public final class MediaSessionConnector {
return actions; 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) { private boolean canDispatchPlaybackAction(long action) {
return player != null && (enabledPlaybackActions & action) != 0; return player != null && (enabledPlaybackActions & action) != 0;
} }
@ -888,6 +892,20 @@ public final class MediaSessionConnector {
controlDispatcher.dispatchSeekTo(player, windowIndex, positionMs); 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 * Provides a default {@link MediaMetadataCompat} with properties and extras taken from the {@link
* MediaDescriptionCompat} of the {@link MediaSessionCompat.QueueItem} of the active queue item. * MediaDescriptionCompat} of the {@link MediaSessionCompat.QueueItem} of the active queue item.
@ -1022,6 +1040,11 @@ public final class MediaSessionConnector {
invalidateMediaSessionPlaybackState(); invalidateMediaSessionPlaybackState();
} }
@Override
public void onIsPlayingChanged(boolean isPlaying) {
invalidateMediaSessionPlaybackState();
}
@Override @Override
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) { public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
mediaSession.setRepeatMode( mediaSession.setRepeatMode(