Commit 4bb6036c by bachinger Committed by kim-vde

add playback state changed listener

This change deprecates Player.onPlayerStateChanged(boolean pwr, int state). It removes deprecation for trivial cases. I'll remove other deprecated usages (mostly in ui module) in follow-up CLs to not bloat this CL.

PiperOrigin-RevId: 292917872
parent 704dae09
Showing with 120 additions and 53 deletions
......@@ -7,6 +7,8 @@
* Add `play` and `pause` methods to `Player`.
* Add `Player.getCurrentLiveOffset` to conveniently return the live offset.
* Add `Player.onPlayWhenReadyChanged` with reasons.
* Add `Player.onPlaybackStateChanged` and deprecate
`Player.onPlayerStateChanged`.
* Make `MediaSourceEventListener.LoadEventInfo` and
`MediaSourceEventListener.MediaLoadData` top-level classes.
* Rename `MediaCodecRenderer.onOutputFormatChanged` to
......
......@@ -267,7 +267,7 @@ import java.util.Map;
// Player.EventListener implementation.
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
updateCurrentItemIndex();
}
......
......@@ -689,7 +689,7 @@ public class PlayerActivity extends AppCompatActivity
private class PlayerEventListener implements Player.EventListener {
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_ENDED) {
showControls();
}
......
......@@ -724,18 +724,23 @@ public final class CastPlayer extends BasePlayer {
}
}
@SuppressWarnings("deprecation")
private void setPlayerStateAndNotifyIfChanged(
boolean playWhenReady,
@Player.PlayWhenReadyChangeReason int playWhenReadyChangeReason,
@Player.State int playbackState) {
boolean playWhenReadyChanged = this.playWhenReady.value != playWhenReady;
if (playWhenReadyChanged || this.playbackState != playbackState) {
boolean playbackStateChanged = this.playbackState != playbackState;
if (playWhenReadyChanged || playbackStateChanged) {
this.playbackState = playbackState;
this.playWhenReady.value = playWhenReady;
notificationsBatch.add(
new ListenerNotificationTask(
listener -> {
listener.onPlayerStateChanged(playWhenReady, playbackState);
if (playbackStateChanged) {
listener.onPlaybackStateChanged(playbackState);
}
if (playWhenReadyChanged) {
listener.onPlayWhenReadyChanged(playWhenReady, playWhenReadyChangeReason);
}
......
......@@ -80,6 +80,7 @@ public class CastPlayerTest {
remoteMediaClientListener = listenerArgumentCaptor.getValue();
}
@SuppressWarnings("deprecation")
@Test
public void testSetPlayWhenReady_masksRemoteState() {
when(mockRemoteMediaClient.play()).thenReturn(mockPendingResult);
......@@ -104,6 +105,7 @@ public class CastPlayerTest {
verifyNoMoreInteractions(mockListener);
}
@SuppressWarnings("deprecation")
@Test
public void testSetPlayWhenReadyMasking_updatesUponResultChange() {
when(mockRemoteMediaClient.play()).thenReturn(mockPendingResult);
......@@ -125,6 +127,7 @@ public class CastPlayerTest {
assertThat(castPlayer.getPlayWhenReady()).isFalse();
}
@SuppressWarnings("deprecation")
@Test
public void testSetPlayWhenReady_correctChangeReasonOnPause() {
when(mockRemoteMediaClient.play()).thenReturn(mockPendingResult);
......@@ -142,6 +145,7 @@ public class CastPlayerTest {
.onPlayWhenReadyChanged(false, Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
}
@SuppressWarnings("deprecation")
@Test
public void testPlayWhenReady_changesOnStatusUpdates() {
assertThat(castPlayer.getPlayWhenReady()).isFalse();
......
......@@ -20,6 +20,7 @@ import static org.junit.Assert.fail;
import android.content.Context;
import android.net.Uri;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.ExoPlaybackException;
......@@ -88,8 +89,8 @@ public class FlacPlaybackTest {
private final Uri uri;
private final AudioSink audioSink;
private ExoPlayer player;
private ExoPlaybackException playbackException;
@Nullable private ExoPlayer player;
@Nullable private ExoPlaybackException playbackException;
public TestPlaybackRunnable(Uri uri, Context context, AudioSink audioSink) {
this.uri = uri;
......@@ -121,7 +122,7 @@ public class FlacPlaybackTest {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_ENDED
|| (playbackState == Player.STATE_IDLE && playbackException != null)) {
player.release();
......
......@@ -92,14 +92,18 @@ import java.util.ArrayList;
}
/** Sets the {@link Player.State} of this player. */
@SuppressWarnings("deprecation")
public void setState(@Player.State int state, boolean playWhenReady) {
boolean playWhenReadyChanged = this.playWhenReady != playWhenReady;
boolean playerStateChanged = this.state != state || playWhenReadyChanged;
boolean playbackStateChanged = this.state != state;
this.state = state;
this.playWhenReady = playWhenReady;
if (playerStateChanged) {
if (playbackStateChanged || playWhenReadyChanged) {
for (Player.EventListener listener : listeners) {
listener.onPlayerStateChanged(playWhenReady, state);
if (playbackStateChanged) {
listener.onPlaybackStateChanged(state);
}
if (playWhenReadyChanged) {
listener.onPlayWhenReadyChanged(
playWhenReady, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
......
......@@ -272,7 +272,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
// Player.EventListener implementation.
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
notifyStateChanged();
}
......
......@@ -20,6 +20,7 @@ import static org.junit.Assert.fail;
import android.content.Context;
import android.net.Uri;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.ExoPlaybackException;
......@@ -67,8 +68,8 @@ public class OpusPlaybackTest {
private final Context context;
private final Uri uri;
private ExoPlayer player;
private ExoPlaybackException playbackException;
@Nullable private ExoPlayer player;
@Nullable private ExoPlaybackException playbackException;
public TestPlaybackRunnable(Uri uri, Context context) {
this.uri = uri;
......@@ -97,7 +98,7 @@ public class OpusPlaybackTest {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_ENDED
|| (playbackState == Player.STATE_IDLE && playbackException != null)) {
player.release();
......
......@@ -21,6 +21,7 @@ import static org.junit.Assert.fail;
import android.content.Context;
import android.net.Uri;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
......@@ -102,8 +103,8 @@ public class VpxPlaybackTest {
private final Context context;
private final Uri uri;
private ExoPlayer player;
private ExoPlaybackException playbackException;
@Nullable private ExoPlayer player;
@Nullable private ExoPlaybackException playbackException;
public TestPlaybackRunnable(Uri uri, Context context) {
this.uri = uri;
......@@ -137,7 +138,7 @@ public class VpxPlaybackTest {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_ENDED
|| (playbackState == Player.STATE_IDLE && playbackException != null)) {
player.release();
......
......@@ -430,6 +430,7 @@ import java.util.concurrent.TimeoutException;
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
}
@SuppressWarnings("deprecation")
public void setPlayWhenReady(
boolean playWhenReady,
@PlaybackSuppressionReason int playbackSuppressionReason,
......@@ -454,8 +455,6 @@ import java.util.concurrent.TimeoutException;
listener -> {
if (playWhenReadyChanged) {
listener.onPlayerStateChanged(playWhenReady, playbackState);
}
if (playWhenReadyChanged) {
listener.onPlayWhenReadyChanged(playWhenReady, playWhenReadyChangeReason);
}
if (suppressionReasonChanged) {
......@@ -880,6 +879,7 @@ import java.util.concurrent.TimeoutException;
/* isPlayingChanged= */ previousIsPlaying != isPlaying));
}
@SuppressWarnings("deprecation")
private void setMediaItemsInternal(
List<MediaSource> mediaItems,
int startWindowIndex,
......@@ -933,6 +933,7 @@ import java.util.concurrent.TimeoutException;
listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED);
if (playbackStateChanged) {
listener.onPlayerStateChanged(currentPlayWhenReady, finalMaskingPlaybackState);
listener.onPlaybackStateChanged(finalMaskingPlaybackState);
}
});
}
......@@ -952,6 +953,7 @@ import java.util.concurrent.TimeoutException;
return holders;
}
@SuppressWarnings("deprecation")
private void removeMediaItemsInternal(int fromIndex, int toIndex) {
Assertions.checkArgument(
fromIndex >= 0 && toIndex >= fromIndex && toIndex <= mediaSourceHolders.size());
......@@ -980,6 +982,7 @@ import java.util.concurrent.TimeoutException;
listener.onTimelineChanged(timeline, TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED);
if (transitionsToEnded) {
listener.onPlayerStateChanged(currentPlayWhenReady, STATE_ENDED);
listener.onPlaybackStateChanged(STATE_ENDED);
}
});
}
......@@ -1167,6 +1170,7 @@ import java.util.concurrent.TimeoutException;
previousPlaybackInfo.trackSelectorResult != playbackInfo.trackSelectorResult;
}
@SuppressWarnings("deprecation")
@Override
public void run() {
if (timelineChanged) {
......@@ -1196,7 +1200,10 @@ import java.util.concurrent.TimeoutException;
if (playbackStateChanged) {
invokeAll(
listenerSnapshot,
listener -> listener.onPlayerStateChanged(playWhenReady, playbackInfo.playbackState));
listener -> {
listener.onPlayerStateChanged(playWhenReady, playbackInfo.playbackState);
listener.onPlaybackStateChanged(playbackInfo.playbackState);
});
}
if (isPlayingChanged) {
invokeAll(
......
......@@ -410,15 +410,20 @@ public interface Player {
default void onLoadingChanged(boolean isLoading) {}
/**
* Called when the value returned from either {@link #getPlayWhenReady()} or {@link
* #getPlaybackState()} changes.
*
* @param playWhenReady Whether playback will proceed when ready.
* @param playbackState The new {@link State playback state}.
* @deprecated Use {@link #onPlaybackStateChanged(int)} and {@link
* #onPlayWhenReadyChanged(boolean, int)} instead.
*/
@Deprecated
default void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {}
/**
* Called when the value returned from {@link #getPlaybackState()} changes.
*
* @param state The new playback {@link State state}.
*/
default void onPlaybackStateChanged(@State int state) {}
/**
* Called when the value returned from {@link #getPlayWhenReady()} changes.
*
* @param playWhenReady Whether playback will proceed when ready.
......@@ -492,7 +497,7 @@ public interface Player {
/**
* Called when all pending seek requests have been processed by the player. This is guaranteed
* to happen after any necessary changes to the player state were reported to {@link
* #onPlayerStateChanged(boolean, int)}.
* #onPlaybackStateChanged(int)}.
*/
default void onSeekProcessed() {}
}
......
......@@ -1662,6 +1662,22 @@ public class SimpleExoPlayer extends BasePlayer
}
}
private void updateWakeLock() {
@State int playbackState = getPlaybackState();
switch (playbackState) {
case Player.STATE_READY:
case Player.STATE_BUFFERING:
wakeLockManager.setStayAwake(getPlayWhenReady());
break;
case Player.STATE_ENDED:
case Player.STATE_IDLE:
wakeLockManager.setStayAwake(false);
break;
default:
throw new IllegalStateException();
}
}
private static int getPlayWhenReadyChangeReason(boolean playWhenReady, int playerCommand) {
return playWhenReady && playerCommand != AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY
? PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS
......@@ -1920,17 +1936,14 @@ public class SimpleExoPlayer extends BasePlayer
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {
switch (playbackState) {
case Player.STATE_READY:
case Player.STATE_BUFFERING:
wakeLockManager.setStayAwake(playWhenReady);
break;
case Player.STATE_ENDED:
case Player.STATE_IDLE:
wakeLockManager.setStayAwake(false);
break;
}
public void onPlaybackStateChanged(@State int playbackState) {
updateWakeLock();
}
@Override
public void onPlayWhenReadyChanged(
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
updateWakeLock();
}
}
}
......@@ -438,6 +438,7 @@ public class AnalyticsCollector
}
}
@SuppressWarnings("deprecation")
@Override
public final void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
......@@ -447,6 +448,14 @@ public class AnalyticsCollector
}
@Override
public final void onPlaybackStateChanged(@Player.State int state) {
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
for (AnalyticsListener listener : listeners) {
listener.onPlaybackStateChanged(eventTime, state);
}
}
@Override
public final void onPlayWhenReadyChanged(
boolean playWhenReady, @Player.PlayWhenReadyChangeReason int reason) {
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
......
......@@ -124,16 +124,22 @@ public interface AnalyticsListener {
}
/**
* Called when the player state changed.
*
* @param eventTime The event time.
* @param playWhenReady Whether the playback will proceed when ready.
* @param playbackState The new {@link Player.State playback state}.
* @deprecated Use {@link #onPlaybackStateChanged(EventTime, int)} and {@link
* #onPlayWhenReadyChanged(EventTime, boolean, int)} instead.
*/
@Deprecated
default void onPlayerStateChanged(
EventTime eventTime, boolean playWhenReady, @Player.State int playbackState) {}
/**
* Called when the playback state changed.
*
* @param eventTime The event time.
* @param state The new {@link Player.State playback state}.
*/
default void onPlaybackStateChanged(EventTime eventTime, @Player.State int state) {}
/**
* Called when the value changed that indicates whether playback will proceed when ready.
*
* @param eventTime The event time.
......
......@@ -96,8 +96,7 @@ public class EventLogger implements AnalyticsListener {
}
@Override
public void onPlayerStateChanged(
EventTime eventTime, boolean playWhenReady, @Player.State int state) {
public void onPlaybackStateChanged(EventTime eventTime, @Player.State int state) {
logd(eventTime, "state", getStateString(state));
}
......
......@@ -79,7 +79,13 @@ public class DebugTextViewHelper implements Player.EventListener, Runnable {
// Player.EventListener implementation.
@Override
public final void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public final void onPlaybackStateChanged(@Player.State int playbackState) {
updateAndPost();
}
@Override
public final void onPlayWhenReadyChanged(
boolean playWhenReady, @Player.PlayWhenReadyChangeReason int playbackState) {
updateAndPost();
}
......
......@@ -1380,7 +1380,13 @@ public class PlayerNotificationManager {
private class PlayerListener implements Player.EventListener {
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
postStartOrUpdateNotification();
}
@Override
public void onPlayWhenReadyChanged(
boolean playWhenReady, @Player.PlayWhenReadyChangeReason int reason) {
postStartOrUpdateNotification();
}
......
......@@ -843,7 +843,7 @@ public abstract class Action {
/**
* Waits for a specified playWhenReady value, returning either immediately or after a call to
* {@link Player.EventListener#onPlayerStateChanged(boolean, int)}.
* {@link Player.EventListener#onPlayWhenReadyChanged(boolean, int)}.
*/
public static final class WaitForPlayWhenReady extends Action {
......@@ -874,8 +874,8 @@ public abstract class Action {
player.addListener(
new Player.EventListener() {
@Override
public void onPlayerStateChanged(
boolean playWhenReady, @Player.State int playbackState) {
public void onPlayWhenReadyChanged(
boolean playWhenReady, @Player.PlayWhenReadyChangeReason int reason) {
if (targetPlayWhenReady == playWhenReady) {
player.removeListener(this);
nextAction.schedule(player, trackSelector, surface, handler);
......@@ -894,7 +894,7 @@ public abstract class Action {
/**
* Waits for a specified playback state, returning either immediately or after a call to {@link
* Player.EventListener#onPlayerStateChanged(boolean, int)}.
* Player.EventListener#onPlaybackStateChanged(int)}.
*/
public static final class WaitForPlaybackState extends Action {
......@@ -925,8 +925,7 @@ public abstract class Action {
player.addListener(
new Player.EventListener() {
@Override
public void onPlayerStateChanged(
boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (targetPlaybackState == playbackState) {
player.removeListener(this);
nextAction.schedule(player, trackSelector, surface, handler);
......
......@@ -609,8 +609,7 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
/**
* Asserts that the playback states reported by {@link
* Player.EventListener#onPlayerStateChanged(boolean, int)} are equal to the provided playback
* states.
* Player.EventListener#onPlaybackStateChanged(int)} are equal to the provided playback states.
*/
public void assertPlaybackStatesEqual(Integer... states) {
assertThat(playbackStates).containsExactlyElementsIn(Arrays.asList(states)).inOrder();
......@@ -706,7 +705,7 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
public void onPlaybackStateChanged(@Player.State int playbackState) {
playbackStates.add(playbackState);
playerWasPrepared |= playbackState != Player.STATE_IDLE;
if (playbackState == Player.STATE_ENDED
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment