diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java
index 3921dbab08..147f769a98 100644
--- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java
+++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java
@@ -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.
*
*
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 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 {
}
}
}
-
}