Move playWhenReadyChangeReason inside PlaybackInfo

This helps to keep the reason always together with the state it
is referring to, avoiding any side channels and making sure there
are no accidental inconsistencies.

#cherrypick

PiperOrigin-RevId: 644969317
(cherry picked from commit c0abd6f91ec62bc5347561c3f3174b3a660a7ba6)
This commit is contained in:
tonihei 2024-06-20 03:51:19 -07:00 committed by Tianyi Feng
parent 30cb76269a
commit 2fd6b60daa
4 changed files with 37 additions and 38 deletions

View File

@ -192,7 +192,6 @@ import java.util.concurrent.TimeoutException;
private int pendingOperationAcks;
private @DiscontinuityReason int pendingDiscontinuityReason;
private boolean pendingDiscontinuity;
private @PlayWhenReadyChangeReason int pendingPlayWhenReadyChangeReason;
private boolean foregroundMode;
private SeekParameters seekParameters;
private ShuffleOrder shuffleOrder;
@ -569,7 +568,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
playbackInfo,
/* ignored */ TIMELINE_CHANGE_REASON_SOURCE_UPDATE,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -687,7 +685,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -711,7 +708,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
positionDiscontinuity,
DISCONTINUITY_REASON_REMOVE,
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
@ -747,7 +743,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -784,7 +779,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
positionDiscontinuity,
DISCONTINUITY_REASON_REMOVE,
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
@ -809,7 +803,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -951,7 +944,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ true,
/* positionDiscontinuityReason= */ DISCONTINUITY_REASON_SEEK,
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
@ -992,7 +984,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -1932,7 +1923,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
playbackInfo,
/* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -1992,9 +1982,6 @@ import java.util.concurrent.TimeoutException;
pendingDiscontinuityReason = playbackInfoUpdate.discontinuityReason;
pendingDiscontinuity = true;
}
if (playbackInfoUpdate.hasPlayWhenReadyChangeReason) {
pendingPlayWhenReadyChangeReason = playbackInfoUpdate.playWhenReadyChangeReason;
}
if (pendingOperationAcks == 0) {
Timeline newTimeline = playbackInfoUpdate.playbackInfo.timeline;
if (!this.playbackInfo.timeline.isEmpty() && newTimeline.isEmpty()) {
@ -2032,7 +2019,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
playbackInfoUpdate.playbackInfo,
TIMELINE_CHANGE_REASON_SOURCE_UPDATE,
pendingPlayWhenReadyChangeReason,
positionDiscontinuity,
pendingDiscontinuityReason,
discontinuityWindowStartPositionUs,
@ -2046,7 +2032,6 @@ import java.util.concurrent.TimeoutException;
private void updatePlaybackInfo(
PlaybackInfo playbackInfo,
@TimelineChangeReason int timelineChangeReason,
@PlayWhenReadyChangeReason int playWhenReadyChangeReason,
boolean positionDiscontinuity,
@DiscontinuityReason int positionDiscontinuityReason,
long discontinuityWindowStartPositionUs,
@ -2174,7 +2159,7 @@ import java.util.concurrent.TimeoutException;
Player.EVENT_PLAY_WHEN_READY_CHANGED,
listener ->
listener.onPlayWhenReadyChanged(
newPlaybackInfo.playWhenReady, playWhenReadyChangeReason));
newPlaybackInfo.playWhenReady, newPlaybackInfo.playWhenReadyChangeReason));
}
if (previousPlaybackInfo.playbackSuppressionReason
!= newPlaybackInfo.playbackSuppressionReason) {
@ -2414,7 +2399,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* positionDiscontinuity= */ positionDiscontinuity,
DISCONTINUITY_REASON_REMOVE,
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
@ -2832,12 +2816,13 @@ import java.util.concurrent.TimeoutException;
? this.playbackInfo.copyWithEstimatedPosition()
: this.playbackInfo;
newPlaybackInfo =
newPlaybackInfo.copyWithPlayWhenReady(playWhenReady, playbackSuppressionReason);
internalPlayer.setPlayWhenReady(playWhenReady, playbackSuppressionReason);
newPlaybackInfo.copyWithPlayWhenReady(
playWhenReady, playWhenReadyChangeReason, playbackSuppressionReason);
internalPlayer.setPlayWhenReady(
playWhenReady, playWhenReadyChangeReason, playbackSuppressionReason);
updatePlaybackInfo(
newPlaybackInfo,
/* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
playWhenReadyChangeReason,
/* positionDiscontinuity= */ false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL,
/* ignored */ C.TIME_UNSET,
@ -3003,7 +2988,6 @@ import java.util.concurrent.TimeoutException;
updatePlaybackInfo(
newPlaybackInfo,
/* timelineChangeReason= */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* ignored */ false,
/* ignored */ DISCONTINUITY_REASON_REMOVE,
/* ignored */ C.TIME_UNSET,

View File

@ -45,7 +45,6 @@ import androidx.media3.common.PlaybackException.ErrorCode;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.Player.DiscontinuityReason;
import androidx.media3.common.Player.PlayWhenReadyChangeReason;
import androidx.media3.common.Player.PlaybackSuppressionReason;
import androidx.media3.common.Player.RepeatMode;
import androidx.media3.common.Timeline;
@ -102,8 +101,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
public int operationAcks;
public boolean positionDiscontinuity;
public @DiscontinuityReason int discontinuityReason;
public boolean hasPlayWhenReadyChangeReason;
public @PlayWhenReadyChangeReason int playWhenReadyChangeReason;
public PlaybackInfoUpdate(PlaybackInfo playbackInfo) {
this.playbackInfo = playbackInfo;
@ -131,13 +128,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
positionDiscontinuity = true;
this.discontinuityReason = discontinuityReason;
}
public void setPlayWhenReadyChangeReason(
@PlayWhenReadyChangeReason int playWhenReadyChangeReason) {
hasPendingChange = true;
this.hasPlayWhenReadyChangeReason = true;
this.playWhenReadyChangeReason = playWhenReadyChangeReason;
}
}
public interface PlaybackInfoUpdateListener {
@ -353,9 +343,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
public void setPlayWhenReady(
boolean playWhenReady, @PlaybackSuppressionReason int playbackSuppressionReason) {
boolean playWhenReady,
@Player.PlayWhenReadyChangeReason int playWhenReadyChangeReason,
@PlaybackSuppressionReason int playbackSuppressionReason) {
int combinedReasons = playbackSuppressionReason << 4 | playWhenReadyChangeReason;
handler
.obtainMessage(MSG_SET_PLAY_WHEN_READY, playWhenReady ? 1 : 0, playbackSuppressionReason)
.obtainMessage(MSG_SET_PLAY_WHEN_READY, playWhenReady ? 1 : 0, combinedReasons)
.sendToTarget();
}
@ -551,9 +544,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
case MSG_SET_PLAY_WHEN_READY:
setPlayWhenReadyInternal(
/* playWhenReady= */ msg.arg1 != 0,
/* playbackSuppressionReason= */ msg.arg2,
/* playbackSuppressionReason= */ msg.arg2 >> 4,
/* operationAck= */ true,
Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
/* reason= */ msg.arg2 & 0x0F);
break;
case MSG_SET_REPEAT_MODE:
setRepeatModeInternal(msg.arg1);
@ -892,8 +885,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
@Player.PlayWhenReadyChangeReason int reason)
throws ExoPlaybackException {
playbackInfoUpdate.incrementPendingOperationAcks(operationAck ? 1 : 0);
playbackInfoUpdate.setPlayWhenReadyChangeReason(reason);
playbackInfo = playbackInfo.copyWithPlayWhenReady(playWhenReady, playbackSuppressionReason);
playbackInfo =
playbackInfo.copyWithPlayWhenReady(playWhenReady, reason, playbackSuppressionReason);
updateRebufferingState(/* isRebuffering= */ false, /* resetLastRebufferRealtimeMs= */ false);
notifyTrackSelectionPlayWhenReadyChanged(playWhenReady);
if (!shouldPlayWhenReady()) {
@ -1642,6 +1635,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
resetTrackInfo ? ImmutableList.of() : playbackInfo.staticMetadata,
mediaPeriodId,
playbackInfo.playWhenReady,
playbackInfo.playWhenReadyChangeReason,
playbackInfo.playbackSuppressionReason,
playbackInfo.playbackParameters,
/* bufferedPositionUs= */ startPositionUs,

View File

@ -84,6 +84,9 @@ import java.util.List;
/** Whether playback should proceed when {@link #playbackState} == {@link Player#STATE_READY}. */
public final boolean playWhenReady;
/** The reason for {@link #playWhenReady}. */
public final @Player.PlayWhenReadyChangeReason int playWhenReadyChangeReason;
/** Reason why playback is suppressed even though {@link #playWhenReady} is {@code true}. */
public final @PlaybackSuppressionReason int playbackSuppressionReason;
@ -139,6 +142,7 @@ import java.util.List;
/* staticMetadata= */ ImmutableList.of(),
PLACEHOLDER_MEDIA_PERIOD_ID,
/* playWhenReady= */ false,
Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
Player.PLAYBACK_SUPPRESSION_REASON_NONE,
PlaybackParameters.DEFAULT,
/* bufferedPositionUs= */ 0,
@ -162,6 +166,7 @@ import java.util.List;
* @param staticMetadata See {@link #staticMetadata}.
* @param loadingMediaPeriodId See {@link #loadingMediaPeriodId}.
* @param playWhenReady See {@link #playWhenReady}.
* @param playWhenReadyChangeReason See {@link #playWhenReadyChangeReason}.
* @param playbackSuppressionReason See {@link #playbackSuppressionReason}.
* @param playbackParameters See {@link #playbackParameters}.
* @param bufferedPositionUs See {@link #bufferedPositionUs}.
@ -183,6 +188,7 @@ import java.util.List;
List<Metadata> staticMetadata,
MediaPeriodId loadingMediaPeriodId,
boolean playWhenReady,
@Player.PlayWhenReadyChangeReason int playWhenReadyChangeReason,
@PlaybackSuppressionReason int playbackSuppressionReason,
PlaybackParameters playbackParameters,
long bufferedPositionUs,
@ -202,6 +208,7 @@ import java.util.List;
this.staticMetadata = staticMetadata;
this.loadingMediaPeriodId = loadingMediaPeriodId;
this.playWhenReady = playWhenReady;
this.playWhenReadyChangeReason = playWhenReadyChangeReason;
this.playbackSuppressionReason = playbackSuppressionReason;
this.playbackParameters = playbackParameters;
this.bufferedPositionUs = bufferedPositionUs;
@ -254,6 +261,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -284,6 +292,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -314,6 +323,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -344,6 +354,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -374,6 +385,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -404,6 +416,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -418,13 +431,16 @@ import java.util.List;
*
* @param playWhenReady Whether playback should proceed when {@link #playbackState} == {@link
* Player#STATE_READY}.
* @param playWhenReadyChangeReason Reason for {#code playWhenReady}.
* @param playbackSuppressionReason Reason why playback is suppressed even though {@link
* #playWhenReady} is {@code true}.
* @return Copied playback info with new information.
*/
@CheckResult
public PlaybackInfo copyWithPlayWhenReady(
boolean playWhenReady, @PlaybackSuppressionReason int playbackSuppressionReason) {
boolean playWhenReady,
@Player.PlayWhenReadyChangeReason int playWhenReadyChangeReason,
@PlaybackSuppressionReason int playbackSuppressionReason) {
return new PlaybackInfo(
timeline,
periodId,
@ -438,6 +454,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -468,6 +485,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -498,6 +516,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,
@ -530,6 +549,7 @@ import java.util.List;
staticMetadata,
loadingMediaPeriodId,
playWhenReady,
playWhenReadyChangeReason,
playbackSuppressionReason,
playbackParameters,
bufferedPositionUs,

View File

@ -1830,6 +1830,7 @@ public final class MediaPeriodQueueTest {
/* staticMetadata= */ ImmutableList.of(),
/* loadingMediaPeriodId= */ null,
/* playWhenReady= */ false,
Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
Player.PLAYBACK_SUPPRESSION_REASON_NONE,
/* playbackParameters= */ PlaybackParameters.DEFAULT,
/* bufferedPositionUs= */ 0,