Mask playWhenReady state in CastPlayer

When the user calls setPlayWhenReady, the state modifications are
observed as immediate, in spite of being sent to the receiver app
as asynchronous operations.

PiperOrigin-RevId: 273289768
This commit is contained in:
aquilescanta 2019-10-07 15:47:21 +01:00 committed by Oliver Woodman
parent 29eebca5c5
commit dddce4307b

View File

@ -50,12 +50,13 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
/**
* {@link Player} implementation that communicates with a Cast receiver app.
*
* <p>The behavior of this class depends on the underlying Cast session, which is obtained from the
* Cast context passed to {@link #CastPlayer}. To keep track of the session, {@link
* Cast context passed to {@link #@}. To keep track of the session, {@link
* #isCastSessionAvailable()} can be queried and {@link SessionAvailabilityListener} can be
* implemented and attached to the player.
*
@ -133,7 +134,7 @@ public final class CastPlayer extends BasePlayer {
currentTrackSelection = EMPTY_TRACK_SELECTION_ARRAY;
pendingSeekWindowIndex = C.INDEX_UNSET;
pendingSeekPositionMs = C.TIME_UNSET;
updateInternalState();
maybeUpdateInternalState();
}
// Media Queue manipulation methods.
@ -323,7 +324,7 @@ public final class CastPlayer extends BasePlayer {
}
@Override
@State
@Player.State
public int getPlaybackState() {
return playbackState;
}
@ -345,11 +346,19 @@ public final class CastPlayer extends BasePlayer {
if (remoteMediaClient == null) {
return;
}
if (playWhenReady) {
remoteMediaClient.play();
} else {
remoteMediaClient.pause();
// We send the message to the receiver app and update the local state, which will cause the
// operation to be perceived as synchronous by the user.
PendingResult<MediaChannelResult> pendingResult =
playWhenReady ? remoteMediaClient.play() : remoteMediaClient.pause();
pendingResult.setResultCallback(
mediaChannelResult -> {
if (remoteMediaClient != null) {
maybeUpdatePlayerStateAndNotify();
flushNotifications();
}
});
maybeSetPlayerStateAndNotify(playWhenReady, playbackState);
flushNotifications();
}
@Override
@ -538,23 +547,14 @@ public final class CastPlayer extends BasePlayer {
// Internal methods.
private void updateInternalState() {
private void maybeUpdateInternalState() {
if (remoteMediaClient == null) {
// There is no session. We leave the state of the player as it is now.
return;
}
boolean wasPlaying = playbackState == Player.STATE_READY && playWhenReady;
int playbackState = fetchPlaybackState(remoteMediaClient);
boolean playWhenReady = !remoteMediaClient.isPaused();
if (this.playbackState != playbackState
|| this.playWhenReady != playWhenReady) {
this.playbackState = playbackState;
this.playWhenReady = playWhenReady;
notificationsBatch.add(
new ListenerNotificationTask(
listener -> listener.onPlayerStateChanged(this.playWhenReady, this.playbackState)));
}
maybeUpdatePlayerStateAndNotify();
boolean isPlaying = playbackState == Player.STATE_READY && playWhenReady;
if (wasPlaying != isPlaying) {
notificationsBatch.add(
@ -592,6 +592,12 @@ public final class CastPlayer extends BasePlayer {
flushNotifications();
}
@RequiresNonNull("remoteMediaClient")
private void maybeUpdatePlayerStateAndNotify() {
maybeSetPlayerStateAndNotify(
!remoteMediaClient.isPaused(), fetchPlaybackState(remoteMediaClient));
}
private void maybeUpdateTimelineAndNotify() {
if (updateTimeline()) {
@Player.TimelineChangeReason
@ -668,6 +674,17 @@ public final class CastPlayer extends BasePlayer {
return false;
}
private void maybeSetPlayerStateAndNotify(
boolean playWhenReady, @Player.State int playbackState) {
if (this.playWhenReady != playWhenReady || this.playbackState != playbackState) {
this.playWhenReady = playWhenReady;
this.playbackState = playbackState;
notificationsBatch.add(
new ListenerNotificationTask(
listener -> listener.onPlayerStateChanged(playWhenReady, playbackState)));
}
}
private void setRemoteMediaClient(@Nullable RemoteMediaClient remoteMediaClient) {
if (this.remoteMediaClient == remoteMediaClient) {
// Do nothing.
@ -684,7 +701,7 @@ public final class CastPlayer extends BasePlayer {
}
remoteMediaClient.addListener(statusListener);
remoteMediaClient.addProgressListener(statusListener, PROGRESS_REPORT_PERIOD_MS);
updateInternalState();
maybeUpdateInternalState();
} else {
if (sessionAvailabilityListener != null) {
sessionAvailabilityListener.onCastSessionUnavailable();
@ -803,7 +820,7 @@ public final class CastPlayer extends BasePlayer {
@Override
public void onStatusUpdated() {
updateInternalState();
maybeUpdateInternalState();
}
@Override
@ -908,5 +925,4 @@ public final class CastPlayer extends BasePlayer {
}
}
}
}