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