Align PlaybackStateCompat states with logic in MediaSessionConnector
Creating the PlaybackStateCompat from a media3 Player state is done already by the MediaSessionConnector (and used widely). The media3 session module should set the same states under the same circumstances to ensure compatiblity and consistency. PlaybackStateCompat changes made in media3 session: - Use STATE_STOPPED when player is ended instead of STATE_PAUSED - Use STATE_PLAYING when playback is suppressed temporarily. - Set the playback speed to 0 if the player is not playing. - Add extras for mediaId and user-set playback speed. Part of the problem was that Player.isPlaying() was used to check the state. Unfortunately, MockPlayer.isPlaying() is implemented in a way that makes it hard to test these changes, because the value is set independently of playbackState, playWhenReady and suppression reason. To be able to write consistent, logical tests, this change also removes the independent setting of isPlaying in MockPlayer to align it better with a real player. This requires to update some other tests to use alternative methods. PiperOrigin-RevId: 487500859
This commit is contained in:
parent
4f04a284ed
commit
c5e071e556
@ -32,7 +32,7 @@ import androidx.media3.session.MediaLibraryService.MediaLibrarySession;
|
|||||||
public final class MediaConstants {
|
public final class MediaConstants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The legacy error code for expired authentication.
|
* {@link Bundle} key used for the error code for expired authentication.
|
||||||
*
|
*
|
||||||
* <p>Use this error code to indicate an expired authentication when {@linkplain
|
* <p>Use this error code to indicate an expired authentication when {@linkplain
|
||||||
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
|
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
|
||||||
@ -43,7 +43,23 @@ public final class MediaConstants {
|
|||||||
public static final int ERROR_CODE_AUTHENTICATION_EXPIRED_COMPAT = 3;
|
public static final int ERROR_CODE_AUTHENTICATION_EXPIRED_COMPAT = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The extras key for the localized error resolution string.
|
* {@link Bundle} key used for the value of {@code Player.getPlaybackParameters().speed}.
|
||||||
|
*
|
||||||
|
* <p>Use this key in the extras bundle of the legacy {@link PlaybackStateCompat}.
|
||||||
|
*/
|
||||||
|
@UnstableApi public static final String EXTRAS_KEY_PLAYBACK_SPEED_COMPAT = "EXO_SPEED";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Bundle} key used for the media id of the media being played.
|
||||||
|
*
|
||||||
|
* <p>Use this key in the extras bundle of the legacy {@link PlaybackStateCompat}.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
public static final String EXTRAS_KEY_MEDIA_ID_COMPAT =
|
||||||
|
androidx.media.utils.MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Bundle} key used for a localized error resolution string.
|
||||||
*
|
*
|
||||||
* <p>Use this key to populate the extras bundle of the {@link LibraryParams} when {@linkplain
|
* <p>Use this key to populate the extras bundle of the {@link LibraryParams} when {@linkplain
|
||||||
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
|
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
|
||||||
@ -53,7 +69,7 @@ public final class MediaConstants {
|
|||||||
androidx.media.utils.MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL;
|
androidx.media.utils.MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The extras key for the error resolution intent.
|
* {@link Bundle} key used for an error resolution intent.
|
||||||
*
|
*
|
||||||
* <p>Use this key to populate the extras bundle of the {@link LibraryParams} when {@linkplain
|
* <p>Use this key to populate the extras bundle of the {@link LibraryParams} when {@linkplain
|
||||||
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
|
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
|
||||||
|
@ -728,20 +728,17 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
public static int convertToPlaybackStateCompatState(
|
public static int convertToPlaybackStateCompatState(
|
||||||
@Nullable PlaybackException playerError,
|
@Nullable PlaybackException playerError,
|
||||||
@Player.State int playbackState,
|
@Player.State int playbackState,
|
||||||
boolean playWhenReady,
|
boolean playWhenReady) {
|
||||||
boolean isPlaying) {
|
|
||||||
if (playerError != null) {
|
if (playerError != null) {
|
||||||
return PlaybackStateCompat.STATE_ERROR;
|
return PlaybackStateCompat.STATE_ERROR;
|
||||||
}
|
}
|
||||||
if (isPlaying) {
|
|
||||||
return PlaybackStateCompat.STATE_PLAYING;
|
|
||||||
}
|
|
||||||
switch (playbackState) {
|
switch (playbackState) {
|
||||||
case Player.STATE_IDLE:
|
case Player.STATE_IDLE:
|
||||||
return PlaybackStateCompat.STATE_NONE;
|
return PlaybackStateCompat.STATE_NONE;
|
||||||
case Player.STATE_READY:
|
case Player.STATE_READY:
|
||||||
|
return playWhenReady ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
|
||||||
case Player.STATE_ENDED:
|
case Player.STATE_ENDED:
|
||||||
return PlaybackStateCompat.STATE_PAUSED;
|
return PlaybackStateCompat.STATE_STOPPED;
|
||||||
case Player.STATE_BUFFERING:
|
case Player.STATE_BUFFERING:
|
||||||
return playWhenReady
|
return playWhenReady
|
||||||
? PlaybackStateCompat.STATE_BUFFERING
|
? PlaybackStateCompat.STATE_BUFFERING
|
||||||
|
@ -18,6 +18,8 @@ package androidx.media3.session;
|
|||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static androidx.media3.common.util.Util.postOrRun;
|
import static androidx.media3.common.util.Util.postOrRun;
|
||||||
|
import static androidx.media3.session.MediaConstants.EXTRAS_KEY_MEDIA_ID_COMPAT;
|
||||||
|
import static androidx.media3.session.MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT;
|
||||||
|
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -768,7 +770,7 @@ import java.util.List;
|
|||||||
@Nullable PlaybackException playerError = getPlayerError();
|
@Nullable PlaybackException playerError = getPlayerError();
|
||||||
int state =
|
int state =
|
||||||
MediaUtils.convertToPlaybackStateCompatState(
|
MediaUtils.convertToPlaybackStateCompatState(
|
||||||
playerError, getPlaybackState(), getPlayWhenReady(), isPlaying());
|
playerError, getPlaybackState(), getPlayWhenReady());
|
||||||
long allActions =
|
long allActions =
|
||||||
PlaybackStateCompat.ACTION_STOP
|
PlaybackStateCompat.ACTION_STOP
|
||||||
| PlaybackStateCompat.ACTION_PAUSE
|
| PlaybackStateCompat.ACTION_PAUSE
|
||||||
@ -798,16 +800,22 @@ import java.util.List;
|
|||||||
allActions |= PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
|
allActions |= PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
|
||||||
}
|
}
|
||||||
long queueItemId = MediaUtils.convertToQueueItemId(getCurrentMediaItemIndex());
|
long queueItemId = MediaUtils.convertToQueueItemId(getCurrentMediaItemIndex());
|
||||||
|
float playbackSpeed = getPlaybackParameters().speed;
|
||||||
|
float sessionPlaybackSpeed = isPlaying() ? playbackSpeed : 0f;
|
||||||
|
Bundle extras = new Bundle();
|
||||||
|
extras.putFloat(EXTRAS_KEY_PLAYBACK_SPEED_COMPAT, playbackSpeed);
|
||||||
|
@Nullable MediaItem currentMediaItem = getCurrentMediaItem();
|
||||||
|
if (currentMediaItem != null && !MediaItem.DEFAULT_MEDIA_ID.equals(currentMediaItem.mediaId)) {
|
||||||
|
extras.putString(EXTRAS_KEY_MEDIA_ID_COMPAT, currentMediaItem.mediaId);
|
||||||
|
}
|
||||||
PlaybackStateCompat.Builder builder =
|
PlaybackStateCompat.Builder builder =
|
||||||
new PlaybackStateCompat.Builder()
|
new PlaybackStateCompat.Builder()
|
||||||
.setState(
|
.setState(
|
||||||
state,
|
state, getCurrentPosition(), sessionPlaybackSpeed, SystemClock.elapsedRealtime())
|
||||||
getCurrentPosition(),
|
|
||||||
getPlaybackParameters().speed,
|
|
||||||
SystemClock.elapsedRealtime())
|
|
||||||
.setActions(allActions)
|
.setActions(allActions)
|
||||||
.setActiveQueueItemId(queueItemId)
|
.setActiveQueueItemId(queueItemId)
|
||||||
.setBufferedPosition(getBufferedPosition());
|
.setBufferedPosition(getBufferedPosition())
|
||||||
|
.setExtras(extras);
|
||||||
|
|
||||||
for (int i = 0; i < customLayout.size(); i++) {
|
for (int i = 0; i < customLayout.size(); i++) {
|
||||||
CommandButton commandButton = customLayout.get(i);
|
CommandButton commandButton = customLayout.get(i);
|
||||||
|
@ -55,7 +55,6 @@ interface IRemoteMediaSession {
|
|||||||
void notifyPlayerError(String sessionId, in Bundle playerErrorBundle);
|
void notifyPlayerError(String sessionId, in Bundle playerErrorBundle);
|
||||||
void notifyPlayWhenReadyChanged(String sessionId, boolean playWhenReady, int reason);
|
void notifyPlayWhenReadyChanged(String sessionId, boolean playWhenReady, int reason);
|
||||||
void notifyPlaybackStateChanged(String sessionId, int state);
|
void notifyPlaybackStateChanged(String sessionId, int state);
|
||||||
void notifyIsPlayingChanged(String sessionId, boolean isPlaying);
|
|
||||||
void notifyIsLoadingChanged(String sessionId, boolean isLoading);
|
void notifyIsLoadingChanged(String sessionId, boolean isLoading);
|
||||||
void notifyPositionDiscontinuity(String sessionId,
|
void notifyPositionDiscontinuity(String sessionId,
|
||||||
in Bundle oldPositionBundle, in Bundle newPositionBundle, int reason);
|
in Bundle oldPositionBundle, in Bundle newPositionBundle, int reason);
|
||||||
|
@ -90,7 +90,6 @@ public class CommonConstants {
|
|||||||
public static final String KEY_PLAY_WHEN_READY = "playWhenReady";
|
public static final String KEY_PLAY_WHEN_READY = "playWhenReady";
|
||||||
public static final String KEY_PLAYBACK_SUPPRESSION_REASON = "playbackSuppressionReason";
|
public static final String KEY_PLAYBACK_SUPPRESSION_REASON = "playbackSuppressionReason";
|
||||||
public static final String KEY_PLAYBACK_STATE = "playbackState";
|
public static final String KEY_PLAYBACK_STATE = "playbackState";
|
||||||
public static final String KEY_IS_PLAYING = "isPlaying";
|
|
||||||
public static final String KEY_IS_LOADING = "isLoading";
|
public static final String KEY_IS_LOADING = "isLoading";
|
||||||
public static final String KEY_REPEAT_MODE = "repeatMode";
|
public static final String KEY_REPEAT_MODE = "repeatMode";
|
||||||
public static final String KEY_SHUFFLE_MODE_ENABLED = "shuffleModeEnabled";
|
public static final String KEY_SHUFFLE_MODE_ENABLED = "shuffleModeEnabled";
|
||||||
|
@ -338,7 +338,6 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
assertThat(errorLatch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(errorLatch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(lastReportedPlaybackStateCompat).isNotNull();
|
|
||||||
assertThat(lastReportedPlaybackStateCompat.getState())
|
assertThat(lastReportedPlaybackStateCompat.getState())
|
||||||
.isEqualTo(PlaybackStateCompat.STATE_ERROR);
|
.isEqualTo(PlaybackStateCompat.STATE_ERROR);
|
||||||
assertThat(
|
assertThat(
|
||||||
@ -361,7 +360,11 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
|
|||||||
// Any successful calls remove the error state,
|
// Any successful calls remove the error state,
|
||||||
assertThat(lastReportedPlaybackStateCompat.getState())
|
assertThat(lastReportedPlaybackStateCompat.getState())
|
||||||
.isNotEqualTo(PlaybackStateCompat.STATE_ERROR);
|
.isNotEqualTo(PlaybackStateCompat.STATE_ERROR);
|
||||||
assertThat(lastReportedPlaybackStateCompat.getExtras()).isNull();
|
assertThat(
|
||||||
|
lastReportedPlaybackStateCompat
|
||||||
|
.getExtras()
|
||||||
|
.getString(MediaConstants.EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL_COMPAT))
|
||||||
|
.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -123,6 +123,7 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
Bundle playerConfig =
|
Bundle playerConfig =
|
||||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||||
.setPlaybackState(testState)
|
.setPlaybackState(testState)
|
||||||
|
.setPlayWhenReady(true)
|
||||||
.setBufferedPosition(testBufferingPosition)
|
.setBufferedPosition(testBufferingPosition)
|
||||||
.setPlaybackParameters(new PlaybackParameters(testSpeed))
|
.setPlaybackParameters(new PlaybackParameters(testSpeed))
|
||||||
.setTimeline(testTimeline)
|
.setTimeline(testTimeline)
|
||||||
@ -153,7 +154,7 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
.isEqualTo(testState);
|
.isEqualTo(testState);
|
||||||
assertThat(controller.getPlaybackState().getBufferedPosition())
|
assertThat(controller.getPlaybackState().getBufferedPosition())
|
||||||
.isEqualTo(testBufferingPosition);
|
.isEqualTo(testBufferingPosition);
|
||||||
assertThat(controller.getPlaybackState().getPlaybackSpeed()).isWithin(EPSILON).of(testSpeed);
|
assertThat(controller.getPlaybackState().getPlaybackSpeed()).isEqualTo(testSpeed);
|
||||||
|
|
||||||
assertThat(controller.getMetadata().getString(METADATA_KEY_MEDIA_ID))
|
assertThat(controller.getMetadata().getString(METADATA_KEY_MEDIA_ID))
|
||||||
.isEqualTo(testMediaItems.get(testItemIndex).mediaId);
|
.isEqualTo(testMediaItems.get(testItemIndex).mediaId);
|
||||||
@ -380,9 +381,7 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
assertThat(latchForPlaybackState.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latchForPlaybackState.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(playbackStateRef.get().getBufferedPosition()).isEqualTo(testBufferedPositionMs);
|
assertThat(playbackStateRef.get().getBufferedPosition()).isEqualTo(testBufferedPositionMs);
|
||||||
assertThat(playbackStateRef.get().getPosition()).isEqualTo(testCurrentPositionMs);
|
assertThat(playbackStateRef.get().getPosition()).isEqualTo(testCurrentPositionMs);
|
||||||
assertThat(playbackStateRef.get().getPlaybackSpeed())
|
assertThat(playbackStateRef.get().getPlaybackSpeed()).isEqualTo(playbackParameters.speed);
|
||||||
.isWithin(EPSILON)
|
|
||||||
.of(playbackParameters.speed);
|
|
||||||
|
|
||||||
assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(metadataRef.get().getString(METADATA_KEY_MEDIA_ID))
|
assertThat(metadataRef.get().getString(METADATA_KEY_MEDIA_ID))
|
||||||
@ -604,7 +603,10 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onPlaybackParametersChanged_notifiesPlaybackStateCompatChanges() throws Exception {
|
public void onPlaybackParametersChanged_notifiesPlaybackStateCompatChanges() throws Exception {
|
||||||
PlaybackParameters playbackParameters = new PlaybackParameters(/* speed= */ 1.5f);
|
PlaybackParameters playbackParameters = new PlaybackParameters(/* speed= */ 1.5f);
|
||||||
|
session.getMockPlayer().setPlaybackState(Player.STATE_READY);
|
||||||
|
session
|
||||||
|
.getMockPlayer()
|
||||||
|
.setPlayWhenReady(/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>();
|
AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>();
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
MediaControllerCompat.Callback callback =
|
MediaControllerCompat.Callback callback =
|
||||||
@ -619,12 +621,21 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
|
|
||||||
session.getMockPlayer().notifyPlaybackParametersChanged(playbackParameters);
|
session.getMockPlayer().notifyPlaybackParametersChanged(playbackParameters);
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(playbackStateRef.get().getPlaybackSpeed())
|
assertThat(playbackStateRef.get().getPlaybackSpeed()).isEqualTo(playbackParameters.speed);
|
||||||
.isWithin(EPSILON)
|
assertThat(
|
||||||
.of(playbackParameters.speed);
|
playbackStateRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(playbackParameters.speed);
|
||||||
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed())
|
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed())
|
||||||
.isWithin(EPSILON)
|
.isEqualTo(playbackParameters.speed);
|
||||||
.of(playbackParameters.speed);
|
assertThat(
|
||||||
|
controllerCompat
|
||||||
|
.getPlaybackState()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(playbackParameters.speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -632,11 +643,8 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
session
|
session
|
||||||
.getMockPlayer()
|
.getMockPlayer()
|
||||||
.setPlayWhenReady(
|
.setPlayWhenReady(/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
/* playWhenReady= */ true,
|
|
||||||
Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
|
||||||
session.getMockPlayer().notifyPlaybackStateChanged(STATE_READY);
|
session.getMockPlayer().notifyPlaybackStateChanged(STATE_READY);
|
||||||
session.getMockPlayer().notifyIsPlayingChanged(false);
|
|
||||||
|
|
||||||
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
@ -657,6 +665,28 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
|
|
||||||
assertThat(playbackStateCompatRef.get().getState()).isEqualTo(PlaybackStateCompat.STATE_PAUSED);
|
assertThat(playbackStateCompatRef.get().getState()).isEqualTo(PlaybackStateCompat.STATE_PAUSED);
|
||||||
|
assertThat(playbackStateCompatRef.get().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_PAUSED);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
controllerCompat
|
||||||
|
.getPlaybackState()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -666,7 +696,6 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
.getMockPlayer()
|
.getMockPlayer()
|
||||||
.setPlayWhenReady(/* playWhenReady= */ false, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
.setPlayWhenReady(/* playWhenReady= */ false, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
session.getMockPlayer().notifyPlaybackStateChanged(Player.STATE_BUFFERING);
|
session.getMockPlayer().notifyPlaybackStateChanged(Player.STATE_BUFFERING);
|
||||||
session.getMockPlayer().notifyIsPlayingChanged(false);
|
|
||||||
|
|
||||||
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
@ -687,17 +716,36 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
|
|
||||||
assertThat(playbackStateCompatRef.get().getState())
|
assertThat(playbackStateCompatRef.get().getState())
|
||||||
.isEqualTo(PlaybackStateCompat.STATE_BUFFERING);
|
.isEqualTo(PlaybackStateCompat.STATE_BUFFERING);
|
||||||
|
assertThat(playbackStateCompatRef.get().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_BUFFERING);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
controllerCompat
|
||||||
|
.getPlaybackState()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playbackStateChange_playbackStateBecomesEnded_notifiesPaused() throws Exception {
|
public void playbackStateChange_playbackStateBecomesEnded_notifiesStopped() throws Exception {
|
||||||
session
|
session
|
||||||
.getMockPlayer()
|
.getMockPlayer()
|
||||||
.setPlayWhenReady(
|
.setPlayWhenReady(/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
/* playWhenReady= */ true,
|
|
||||||
Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
|
||||||
session.getMockPlayer().notifyPlaybackStateChanged(STATE_READY);
|
session.getMockPlayer().notifyPlaybackStateChanged(STATE_READY);
|
||||||
session.getMockPlayer().notifyIsPlayingChanged(false);
|
|
||||||
|
|
||||||
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
@ -714,12 +762,39 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
session.getMockPlayer().notifyPlaybackStateChanged(STATE_ENDED);
|
session.getMockPlayer().notifyPlaybackStateChanged(STATE_ENDED);
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
|
|
||||||
assertThat(playbackStateCompatRef.get().getState()).isEqualTo(PlaybackStateCompat.STATE_PAUSED);
|
assertThat(playbackStateCompatRef.get().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_STOPPED);
|
||||||
|
assertThat(playbackStateCompatRef.get().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_STOPPED);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
controllerCompat
|
||||||
|
.getPlaybackState()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playbackStateChange_isPlayingBecomesTrue_notifiesPlaying() throws Exception {
|
public void playbackStateChange_withPlaybackSuppression_notifiesPlayingWithSpeedZero()
|
||||||
session.getMockPlayer().notifyIsPlayingChanged(false);
|
throws Exception {
|
||||||
|
session.getMockPlayer().setPlaybackState(Player.STATE_READY);
|
||||||
|
session
|
||||||
|
.getMockPlayer()
|
||||||
|
.setPlayWhenReady(/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
|
|
||||||
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
@ -733,11 +808,83 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
|
|||||||
};
|
};
|
||||||
controllerCompat.registerCallback(callback, handler);
|
controllerCompat.registerCallback(callback, handler);
|
||||||
|
|
||||||
session.getMockPlayer().notifyIsPlayingChanged(true);
|
session
|
||||||
|
.getMockPlayer()
|
||||||
|
.notifyPlayWhenReadyChanged(
|
||||||
|
/* playWhenReady= */ true,
|
||||||
|
Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
|
|
||||||
assertThat(playbackStateCompatRef.get().getState())
|
assertThat(playbackStateCompatRef.get().getState())
|
||||||
.isEqualTo(PlaybackStateCompat.STATE_PLAYING);
|
.isEqualTo(PlaybackStateCompat.STATE_PLAYING);
|
||||||
|
assertThat(playbackStateCompatRef.get().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_PLAYING);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed()).isEqualTo(0f);
|
||||||
|
assertThat(
|
||||||
|
controllerCompat
|
||||||
|
.getPlaybackState()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void playbackStateChange_playWhenReadyBecomesTrueWhenReady_notifiesPlaying()
|
||||||
|
throws Exception {
|
||||||
|
session.getMockPlayer().setPlaybackState(Player.STATE_READY);
|
||||||
|
session
|
||||||
|
.getMockPlayer()
|
||||||
|
.setPlayWhenReady(/* playWhenReady= */ false, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
|
|
||||||
|
AtomicReference<PlaybackStateCompat> playbackStateCompatRef = new AtomicReference<>();
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
MediaControllerCompat.Callback callback =
|
||||||
|
new MediaControllerCompat.Callback() {
|
||||||
|
@Override
|
||||||
|
public void onPlaybackStateChanged(PlaybackStateCompat playbackStateCompat) {
|
||||||
|
playbackStateCompatRef.set(playbackStateCompat);
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
controllerCompat.registerCallback(callback, handler);
|
||||||
|
|
||||||
|
session
|
||||||
|
.getMockPlayer()
|
||||||
|
.notifyPlayWhenReadyChanged(
|
||||||
|
/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
|
|
||||||
|
assertThat(playbackStateCompatRef.get().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_PLAYING);
|
||||||
|
assertThat(playbackStateCompatRef.get().getPlaybackSpeed()).isEqualTo(1f);
|
||||||
|
assertThat(
|
||||||
|
playbackStateCompatRef
|
||||||
|
.get()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getState())
|
||||||
|
.isEqualTo(PlaybackStateCompat.STATE_PLAYING);
|
||||||
|
assertThat(controllerCompat.getPlaybackState().getPlaybackSpeed()).isEqualTo(1f);
|
||||||
|
assertThat(
|
||||||
|
controllerCompat
|
||||||
|
.getPlaybackState()
|
||||||
|
.getExtras()
|
||||||
|
.getFloat(MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT))
|
||||||
|
.isEqualTo(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1818,8 +1818,9 @@ public class MediaControllerListenerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onIsPlayingChanged_isNotified() throws Exception {
|
public void onIsPlayingChanged_isNotified() throws Exception {
|
||||||
boolean testIsPlaying = true;
|
remoteSession
|
||||||
remoteSession.getMockPlayer().notifyIsPlayingChanged(false);
|
.getMockPlayer()
|
||||||
|
.setPlayWhenReady(/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
||||||
CountDownLatch latch = new CountDownLatch(2);
|
CountDownLatch latch = new CountDownLatch(2);
|
||||||
AtomicBoolean isPlayingGetterRef = new AtomicBoolean();
|
AtomicBoolean isPlayingGetterRef = new AtomicBoolean();
|
||||||
@ -1844,18 +1845,17 @@ public class MediaControllerListenerTest {
|
|||||||
};
|
};
|
||||||
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
||||||
|
|
||||||
remoteSession.getMockPlayer().notifyIsPlayingChanged(testIsPlaying);
|
remoteSession.getMockPlayer().notifyPlaybackStateChanged(Player.STATE_READY);
|
||||||
|
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(isPlayingParamRef.get()).isEqualTo(testIsPlaying);
|
assertThat(isPlayingParamRef.get()).isTrue();
|
||||||
assertThat(isPlayingGetterRef.get()).isEqualTo(testIsPlaying);
|
assertThat(isPlayingGetterRef.get()).isTrue();
|
||||||
assertThat(isPlayingOnEventsRef.get()).isEqualTo(testIsPlaying);
|
assertThat(isPlayingOnEventsRef.get()).isTrue();
|
||||||
assertThat(getEventsAsList(eventsRef.get())).containsExactly(Player.EVENT_IS_PLAYING_CHANGED);
|
assertThat(getEventsAsList(eventsRef.get())).contains(Player.EVENT_IS_PLAYING_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onIsPlayingChanged_updatesGetters() throws Exception {
|
public void onIsPlayingChanged_updatesGetters() throws Exception {
|
||||||
boolean testIsPlaying = true;
|
|
||||||
long testCurrentPositionMs = 11;
|
long testCurrentPositionMs = 11;
|
||||||
long testContentPositionMs = testCurrentPositionMs; // Not playing an ad
|
long testContentPositionMs = testCurrentPositionMs; // Not playing an ad
|
||||||
long testBufferedPositionMs = 100;
|
long testBufferedPositionMs = 100;
|
||||||
@ -1863,7 +1863,9 @@ public class MediaControllerListenerTest {
|
|||||||
long testTotalBufferedDurationMs = 120;
|
long testTotalBufferedDurationMs = 120;
|
||||||
long testCurrentLiveOffsetMs = 10;
|
long testCurrentLiveOffsetMs = 10;
|
||||||
long testContentBufferedPositionMs = 240;
|
long testContentBufferedPositionMs = 240;
|
||||||
remoteSession.getMockPlayer().notifyIsPlayingChanged(false);
|
remoteSession
|
||||||
|
.getMockPlayer()
|
||||||
|
.setPlayWhenReady(/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
||||||
threadTestRule.getHandler().postAndSync(() -> controller.setTimeDiffMs(/* timeDiff= */ 0L));
|
threadTestRule.getHandler().postAndSync(() -> controller.setTimeDiffMs(/* timeDiff= */ 0L));
|
||||||
CountDownLatch latch = new CountDownLatch(2);
|
CountDownLatch latch = new CountDownLatch(2);
|
||||||
@ -1906,10 +1908,10 @@ public class MediaControllerListenerTest {
|
|||||||
remoteSession.getMockPlayer().setTotalBufferedDuration(testTotalBufferedDurationMs);
|
remoteSession.getMockPlayer().setTotalBufferedDuration(testTotalBufferedDurationMs);
|
||||||
remoteSession.getMockPlayer().setCurrentLiveOffset(testCurrentLiveOffsetMs);
|
remoteSession.getMockPlayer().setCurrentLiveOffset(testCurrentLiveOffsetMs);
|
||||||
remoteSession.getMockPlayer().setContentBufferedPosition(testContentBufferedPositionMs);
|
remoteSession.getMockPlayer().setContentBufferedPosition(testContentBufferedPositionMs);
|
||||||
remoteSession.getMockPlayer().notifyIsPlayingChanged(testIsPlaying);
|
remoteSession.getMockPlayer().notifyPlaybackStateChanged(Player.STATE_READY);
|
||||||
|
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(isPlayingRef.get()).isEqualTo(testIsPlaying);
|
assertThat(isPlayingRef.get()).isEqualTo(true);
|
||||||
assertThat(currentPositionMsRef.get()).isEqualTo(testCurrentPositionMs);
|
assertThat(currentPositionMsRef.get()).isEqualTo(testCurrentPositionMs);
|
||||||
assertThat(contentPositionMsRef.get()).isEqualTo(testContentPositionMs);
|
assertThat(contentPositionMsRef.get()).isEqualTo(testContentPositionMs);
|
||||||
assertThat(bufferedPositionMsRef.get()).isEqualTo(testBufferedPositionMs);
|
assertThat(bufferedPositionMsRef.get()).isEqualTo(testBufferedPositionMs);
|
||||||
@ -1917,7 +1919,7 @@ public class MediaControllerListenerTest {
|
|||||||
assertThat(totalBufferedDurationMsRef.get()).isEqualTo(testTotalBufferedDurationMs);
|
assertThat(totalBufferedDurationMsRef.get()).isEqualTo(testTotalBufferedDurationMs);
|
||||||
assertThat(currentLiveOffsetMsRef.get()).isEqualTo(testCurrentLiveOffsetMs);
|
assertThat(currentLiveOffsetMsRef.get()).isEqualTo(testCurrentLiveOffsetMs);
|
||||||
assertThat(contentBufferedPositionMsRef.get()).isEqualTo(testContentBufferedPositionMs);
|
assertThat(contentBufferedPositionMsRef.get()).isEqualTo(testContentBufferedPositionMs);
|
||||||
assertThat(getEventsAsList(eventsRef.get())).containsExactly(Player.EVENT_IS_PLAYING_CHANGED);
|
assertThat(getEventsAsList(eventsRef.get())).contains(Player.EVENT_IS_PLAYING_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -279,7 +279,6 @@ public class MediaControllerTest {
|
|||||||
@Player.PlaybackSuppressionReason
|
@Player.PlaybackSuppressionReason
|
||||||
int playbackSuppressionReason = Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS;
|
int playbackSuppressionReason = Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS;
|
||||||
@Player.State int playbackState = Player.STATE_READY;
|
@Player.State int playbackState = Player.STATE_READY;
|
||||||
boolean isPlaying = true;
|
|
||||||
boolean isLoading = true;
|
boolean isLoading = true;
|
||||||
boolean isShuffleModeEnabled = true;
|
boolean isShuffleModeEnabled = true;
|
||||||
@RepeatMode int repeatMode = Player.REPEAT_MODE_ONE;
|
@RepeatMode int repeatMode = Player.REPEAT_MODE_ONE;
|
||||||
@ -327,7 +326,6 @@ public class MediaControllerTest {
|
|||||||
.setPlayWhenReady(playWhenReady)
|
.setPlayWhenReady(playWhenReady)
|
||||||
.setPlaybackSuppressionReason(playbackSuppressionReason)
|
.setPlaybackSuppressionReason(playbackSuppressionReason)
|
||||||
.setPlaybackState(playbackState)
|
.setPlaybackState(playbackState)
|
||||||
.setIsPlaying(isPlaying)
|
|
||||||
.setIsLoading(isLoading)
|
.setIsLoading(isLoading)
|
||||||
.setShuffleModeEnabled(isShuffleModeEnabled)
|
.setShuffleModeEnabled(isShuffleModeEnabled)
|
||||||
.setRepeatMode(repeatMode)
|
.setRepeatMode(repeatMode)
|
||||||
@ -360,7 +358,6 @@ public class MediaControllerTest {
|
|||||||
AtomicBoolean playWhenReadyRef = new AtomicBoolean();
|
AtomicBoolean playWhenReadyRef = new AtomicBoolean();
|
||||||
AtomicInteger playbackSuppressionReasonRef = new AtomicInteger();
|
AtomicInteger playbackSuppressionReasonRef = new AtomicInteger();
|
||||||
AtomicInteger playbackStateRef = new AtomicInteger();
|
AtomicInteger playbackStateRef = new AtomicInteger();
|
||||||
AtomicBoolean isPlayingRef = new AtomicBoolean();
|
|
||||||
AtomicBoolean isLoadingRef = new AtomicBoolean();
|
AtomicBoolean isLoadingRef = new AtomicBoolean();
|
||||||
AtomicBoolean isShuffleModeEnabledRef = new AtomicBoolean();
|
AtomicBoolean isShuffleModeEnabledRef = new AtomicBoolean();
|
||||||
AtomicInteger repeatModeRef = new AtomicInteger();
|
AtomicInteger repeatModeRef = new AtomicInteger();
|
||||||
@ -393,7 +390,6 @@ public class MediaControllerTest {
|
|||||||
playWhenReadyRef.set(controller.getPlayWhenReady());
|
playWhenReadyRef.set(controller.getPlayWhenReady());
|
||||||
playbackSuppressionReasonRef.set(controller.getPlaybackSuppressionReason());
|
playbackSuppressionReasonRef.set(controller.getPlaybackSuppressionReason());
|
||||||
playbackStateRef.set(controller.getPlaybackState());
|
playbackStateRef.set(controller.getPlaybackState());
|
||||||
isPlayingRef.set(controller.isPlaying());
|
|
||||||
isLoadingRef.set(controller.isLoading());
|
isLoadingRef.set(controller.isLoading());
|
||||||
isShuffleModeEnabledRef.set(controller.getShuffleModeEnabled());
|
isShuffleModeEnabledRef.set(controller.getShuffleModeEnabled());
|
||||||
repeatModeRef.set(controller.getRepeatMode());
|
repeatModeRef.set(controller.getRepeatMode());
|
||||||
@ -423,7 +419,6 @@ public class MediaControllerTest {
|
|||||||
assertThat(playWhenReadyRef.get()).isEqualTo(playWhenReady);
|
assertThat(playWhenReadyRef.get()).isEqualTo(playWhenReady);
|
||||||
assertThat(playbackSuppressionReasonRef.get()).isEqualTo(playbackSuppressionReason);
|
assertThat(playbackSuppressionReasonRef.get()).isEqualTo(playbackSuppressionReason);
|
||||||
assertThat(playbackStateRef.get()).isEqualTo(playbackState);
|
assertThat(playbackStateRef.get()).isEqualTo(playbackState);
|
||||||
assertThat(isPlayingRef.get()).isEqualTo(isPlaying);
|
|
||||||
assertThat(isLoadingRef.get()).isEqualTo(isLoading);
|
assertThat(isLoadingRef.get()).isEqualTo(isLoading);
|
||||||
assertThat(isShuffleModeEnabledRef.get()).isEqualTo(isShuffleModeEnabled);
|
assertThat(isShuffleModeEnabledRef.get()).isEqualTo(isShuffleModeEnabled);
|
||||||
assertThat(repeatModeRef.get()).isEqualTo(repeatMode);
|
assertThat(repeatModeRef.get()).isEqualTo(repeatMode);
|
||||||
@ -842,7 +837,7 @@ public class MediaControllerTest {
|
|||||||
long testCurrentPositionMs = 100L;
|
long testCurrentPositionMs = 100L;
|
||||||
Bundle playerConfig =
|
Bundle playerConfig =
|
||||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||||
.setIsPlaying(false)
|
.setPlaybackState(Player.STATE_BUFFERING)
|
||||||
.setCurrentPosition(testCurrentPositionMs)
|
.setCurrentPosition(testCurrentPositionMs)
|
||||||
.setDuration(10_000L)
|
.setDuration(10_000L)
|
||||||
.build();
|
.build();
|
||||||
@ -868,7 +863,8 @@ public class MediaControllerTest {
|
|||||||
long testTimeDiff = 50L;
|
long testTimeDiff = 50L;
|
||||||
Bundle playerConfig =
|
Bundle playerConfig =
|
||||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||||
.setIsPlaying(true)
|
.setPlaybackState(Player.STATE_READY)
|
||||||
|
.setPlayWhenReady(true)
|
||||||
.setCurrentPosition(testCurrentPosition)
|
.setCurrentPosition(testCurrentPosition)
|
||||||
.setDuration(10_000L)
|
.setDuration(10_000L)
|
||||||
.setPlaybackParameters(testPlaybackParameters)
|
.setPlaybackParameters(testPlaybackParameters)
|
||||||
@ -897,7 +893,8 @@ public class MediaControllerTest {
|
|||||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||||
.setContentPosition(testContentPosition)
|
.setContentPosition(testContentPosition)
|
||||||
.setDuration(10_000L)
|
.setDuration(10_000L)
|
||||||
.setIsPlaying(true)
|
.setPlaybackState(Player.STATE_READY)
|
||||||
|
.setPlayWhenReady(true)
|
||||||
.setIsPlayingAd(true)
|
.setIsPlayingAd(true)
|
||||||
.setCurrentAdGroupIndex(0)
|
.setCurrentAdGroupIndex(0)
|
||||||
.setCurrentAdIndexInAdGroup(0)
|
.setCurrentAdIndexInAdGroup(0)
|
||||||
@ -925,7 +922,8 @@ public class MediaControllerTest {
|
|||||||
.setCurrentPosition(100L)
|
.setCurrentPosition(100L)
|
||||||
.setContentPosition(100L) // Same as current position b/c not playing an ad
|
.setContentPosition(100L) // Same as current position b/c not playing an ad
|
||||||
.setDuration(10_000L)
|
.setDuration(10_000L)
|
||||||
.setIsPlaying(true)
|
.setPlayWhenReady(true)
|
||||||
|
.setPlaybackState(Player.STATE_READY)
|
||||||
.setIsPlayingAd(false)
|
.setIsPlayingAd(false)
|
||||||
.setPlaybackParameters(new PlaybackParameters(/* speed= */ 2.0f))
|
.setPlaybackParameters(new PlaybackParameters(/* speed= */ 2.0f))
|
||||||
.build();
|
.build();
|
||||||
@ -956,7 +954,8 @@ public class MediaControllerTest {
|
|||||||
.setCurrentPosition(10L)
|
.setCurrentPosition(10L)
|
||||||
.setContentPosition(50L)
|
.setContentPosition(50L)
|
||||||
.setDuration(10_000L)
|
.setDuration(10_000L)
|
||||||
.setIsPlaying(true)
|
.setPlayWhenReady(true)
|
||||||
|
.setPlaybackState(Player.STATE_READY)
|
||||||
.setIsPlayingAd(true)
|
.setIsPlayingAd(true)
|
||||||
.setCurrentAdGroupIndex(0)
|
.setCurrentAdGroupIndex(0)
|
||||||
.setCurrentAdIndexInAdGroup(0)
|
.setCurrentAdIndexInAdGroup(0)
|
||||||
|
@ -21,6 +21,7 @@ import static androidx.media3.test.session.common.TestUtils.LONG_TIMEOUT_MS;
|
|||||||
import static androidx.media3.test.session.common.TestUtils.TIMEOUT_MS;
|
import static androidx.media3.test.session.common.TestUtils.TIMEOUT_MS;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
@ -98,8 +99,14 @@ public class MediaSessionKeyEventTest {
|
|||||||
// Here's the requirement for an app to receive media key events via MediaSession.
|
// Here's the requirement for an app to receive media key events via MediaSession.
|
||||||
// - SDK < 26: Player should be playing for receiving key events
|
// - SDK < 26: Player should be playing for receiving key events
|
||||||
// - SDK >= 26: Play a media item in the same process of the session for receiving key events.
|
// - SDK >= 26: Play a media item in the same process of the session for receiving key events.
|
||||||
handler.postAndSync(() -> player.notifyIsPlayingChanged(/* isPlaying= */ true));
|
if (Util.SDK_INT < 26) {
|
||||||
if (Util.SDK_INT >= 26) {
|
handler.postAndSync(
|
||||||
|
() -> {
|
||||||
|
player.notifyPlayWhenReadyChanged(
|
||||||
|
/* playWhenReady= */ true, Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
|
player.notifyPlaybackStateChanged(Player.STATE_READY);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
handler.postAndSync(
|
handler.postAndSync(
|
||||||
() -> {
|
() -> {
|
||||||
@ -168,6 +175,10 @@ public class MediaSessionKeyEventTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playPauseKeyEvent_paused_play() throws Exception {
|
public void playPauseKeyEvent_paused_play() throws Exception {
|
||||||
|
// We don't receive media key events when we are not playing on API < 26, so we can't test this
|
||||||
|
// case as it's not supported.
|
||||||
|
assumeTrue(Util.SDK_INT >= 26);
|
||||||
|
|
||||||
handler.postAndSync(
|
handler.postAndSync(
|
||||||
() -> {
|
() -> {
|
||||||
player.playbackState = Player.STATE_READY;
|
player.playbackState = Player.STATE_READY;
|
||||||
@ -180,6 +191,10 @@ public class MediaSessionKeyEventTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playPauseKeyEvent_fromIdle_prepareAndPlay() throws Exception {
|
public void playPauseKeyEvent_fromIdle_prepareAndPlay() throws Exception {
|
||||||
|
// We don't receive media key events when we are not playing on API < 26, so we can't test this
|
||||||
|
// case as it's not supported.
|
||||||
|
assumeTrue(Util.SDK_INT >= 26);
|
||||||
|
|
||||||
handler.postAndSync(
|
handler.postAndSync(
|
||||||
() -> {
|
() -> {
|
||||||
player.playbackState = Player.STATE_IDLE;
|
player.playbackState = Player.STATE_IDLE;
|
||||||
@ -193,6 +208,10 @@ public class MediaSessionKeyEventTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playPauseKeyEvent_playWhenReadyAndEnded_seekAndPlay() throws Exception {
|
public void playPauseKeyEvent_playWhenReadyAndEnded_seekAndPlay() throws Exception {
|
||||||
|
// We don't receive media key events when we are not playing on API < 26, so we can't test this
|
||||||
|
// case as it's not supported.
|
||||||
|
assumeTrue(Util.SDK_INT >= 26);
|
||||||
|
|
||||||
handler.postAndSync(
|
handler.postAndSync(
|
||||||
() -> {
|
() -> {
|
||||||
player.playWhenReady = true;
|
player.playWhenReady = true;
|
||||||
|
@ -36,7 +36,6 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_DEVICE_MUT
|
|||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_DEVICE_VOLUME;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_DEVICE_VOLUME;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_DURATION;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_DURATION;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_LOADING;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_LOADING;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_PLAYING;
|
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_PLAYING_AD;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_PLAYING_AD;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_MEDIA_METADATA;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_MEDIA_METADATA;
|
||||||
@ -374,7 +373,6 @@ public class MediaSessionProviderService extends Service {
|
|||||||
player.playbackSuppressionReason =
|
player.playbackSuppressionReason =
|
||||||
config.getInt(KEY_PLAYBACK_SUPPRESSION_REASON, player.playbackSuppressionReason);
|
config.getInt(KEY_PLAYBACK_SUPPRESSION_REASON, player.playbackSuppressionReason);
|
||||||
player.playbackState = config.getInt(KEY_PLAYBACK_STATE, player.playbackState);
|
player.playbackState = config.getInt(KEY_PLAYBACK_STATE, player.playbackState);
|
||||||
player.isPlaying = config.getBoolean(KEY_IS_PLAYING, player.isPlaying);
|
|
||||||
player.isLoading = config.getBoolean(KEY_IS_LOADING, player.isLoading);
|
player.isLoading = config.getBoolean(KEY_IS_LOADING, player.isLoading);
|
||||||
player.repeatMode = config.getInt(KEY_REPEAT_MODE, player.repeatMode);
|
player.repeatMode = config.getInt(KEY_REPEAT_MODE, player.repeatMode);
|
||||||
player.shuffleModeEnabled =
|
player.shuffleModeEnabled =
|
||||||
@ -695,16 +693,6 @@ public class MediaSessionProviderService extends Service {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyIsPlayingChanged(String sessionId, boolean isPlaying) throws RemoteException {
|
|
||||||
runOnHandler(
|
|
||||||
() -> {
|
|
||||||
MediaSession session = sessionMap.get(sessionId);
|
|
||||||
MockPlayer player = (MockPlayer) session.getPlayer();
|
|
||||||
player.notifyIsPlayingChanged(isPlaying);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyIsLoadingChanged(String sessionId, boolean isLoading) throws RemoteException {
|
public void notifyIsLoadingChanged(String sessionId, boolean isLoading) throws RemoteException {
|
||||||
runOnHandler(
|
runOnHandler(
|
||||||
|
@ -245,7 +245,6 @@ public class MockPlayer implements Player {
|
|||||||
public boolean playWhenReady;
|
public boolean playWhenReady;
|
||||||
public @PlaybackSuppressionReason int playbackSuppressionReason;
|
public @PlaybackSuppressionReason int playbackSuppressionReason;
|
||||||
public @State int playbackState;
|
public @State int playbackState;
|
||||||
public boolean isPlaying;
|
|
||||||
public boolean isLoading;
|
public boolean isLoading;
|
||||||
public MediaMetadata mediaMetadata;
|
public MediaMetadata mediaMetadata;
|
||||||
public Commands commands;
|
public Commands commands;
|
||||||
@ -521,6 +520,12 @@ public class MockPlayer implements Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the values returned from {@link #getPlayWhenReady()} and {@link
|
||||||
|
* #getPlaybackSuppressionReason()}, and triggers {@link Player.Listener#onPlayWhenReadyChanged},
|
||||||
|
* {@link Player.Listener#onPlaybackSuppressionReasonChanged} or {@link
|
||||||
|
* Player.Listener#onIsPlayingChanged} as appropriate.
|
||||||
|
*/
|
||||||
public void notifyPlayWhenReadyChanged(
|
public void notifyPlayWhenReadyChanged(
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
boolean playWhenReadyChanged = (this.playWhenReady != playWhenReady);
|
boolean playWhenReadyChanged = (this.playWhenReady != playWhenReady);
|
||||||
@ -529,8 +534,10 @@ public class MockPlayer implements Player {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean wasPlaying = isPlaying();
|
||||||
this.playWhenReady = playWhenReady;
|
this.playWhenReady = playWhenReady;
|
||||||
this.playbackSuppressionReason = reason;
|
this.playbackSuppressionReason = reason;
|
||||||
|
boolean isPlaying = isPlaying();
|
||||||
for (Listener listener : listeners) {
|
for (Listener listener : listeners) {
|
||||||
if (playWhenReadyChanged) {
|
if (playWhenReadyChanged) {
|
||||||
listener.onPlayWhenReadyChanged(
|
listener.onPlayWhenReadyChanged(
|
||||||
@ -539,26 +546,29 @@ public class MockPlayer implements Player {
|
|||||||
if (playbackSuppressionReasonChanged) {
|
if (playbackSuppressionReasonChanged) {
|
||||||
listener.onPlaybackSuppressionReasonChanged(reason);
|
listener.onPlaybackSuppressionReasonChanged(reason);
|
||||||
}
|
}
|
||||||
|
if (isPlaying != wasPlaying) {
|
||||||
|
listener.onIsPlayingChanged(isPlaying);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the value returned from {@link #getPlaybackState()} and triggers {@link
|
||||||
|
* Player.Listener#onPlaybackStateChanged} and/or {@link Player.Listener#onIsPlayingChanged} as
|
||||||
|
* appropriate.
|
||||||
|
*/
|
||||||
public void notifyPlaybackStateChanged(@State int playbackState) {
|
public void notifyPlaybackStateChanged(@State int playbackState) {
|
||||||
if (this.playbackState == playbackState) {
|
if (this.playbackState == playbackState) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
boolean wasPlaying = isPlaying();
|
||||||
this.playbackState = playbackState;
|
this.playbackState = playbackState;
|
||||||
|
boolean isPlaying = isPlaying();
|
||||||
for (Listener listener : listeners) {
|
for (Listener listener : listeners) {
|
||||||
listener.onPlaybackStateChanged(playbackState);
|
listener.onPlaybackStateChanged(playbackState);
|
||||||
}
|
if (isPlaying != wasPlaying) {
|
||||||
}
|
listener.onIsPlayingChanged(isPlaying);
|
||||||
|
}
|
||||||
public void notifyIsPlayingChanged(boolean isPlaying) {
|
|
||||||
if (this.isPlaying == isPlaying) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.isPlaying = isPlaying;
|
|
||||||
for (Listener listener : listeners) {
|
|
||||||
listener.onIsPlayingChanged(isPlaying);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +708,9 @@ public class MockPlayer implements Player {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlaying() {
|
public boolean isPlaying() {
|
||||||
return isPlaying;
|
return playWhenReady
|
||||||
|
&& playbackState == Player.STATE_READY
|
||||||
|
&& playbackSuppressionReason == Player.PLAYBACK_SUPPRESSION_REASON_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,7 +35,6 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_DEVICE_MUT
|
|||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_DEVICE_VOLUME;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_DEVICE_VOLUME;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_DURATION;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_DURATION;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_LOADING;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_LOADING;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_PLAYING;
|
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_PLAYING_AD;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_IS_PLAYING_AD;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
||||||
import static androidx.media3.test.session.common.CommonConstants.KEY_MEDIA_METADATA;
|
import static androidx.media3.test.session.common.CommonConstants.KEY_MEDIA_METADATA;
|
||||||
@ -296,10 +295,6 @@ public class RemoteMediaSession {
|
|||||||
binder.notifyPlaybackStateChanged(sessionId, state);
|
binder.notifyPlaybackStateChanged(sessionId, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyIsPlayingChanged(boolean isPlaying) throws RemoteException {
|
|
||||||
binder.notifyIsPlayingChanged(sessionId, isPlaying);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyIsLoadingChanged(boolean isLoading) throws RemoteException {
|
public void notifyIsLoadingChanged(boolean isLoading) throws RemoteException {
|
||||||
binder.notifyIsLoadingChanged(sessionId, isLoading);
|
binder.notifyIsLoadingChanged(sessionId, isLoading);
|
||||||
}
|
}
|
||||||
@ -687,12 +682,6 @@ public class RemoteMediaSession {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@CanIgnoreReturnValue
|
|
||||||
public MockPlayerConfigBuilder setIsPlaying(boolean isPlaying) {
|
|
||||||
bundle.putBoolean(KEY_IS_PLAYING, isPlaying);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@CanIgnoreReturnValue
|
@CanIgnoreReturnValue
|
||||||
public MockPlayerConfigBuilder setIsLoading(boolean isLoading) {
|
public MockPlayerConfigBuilder setIsLoading(boolean isLoading) {
|
||||||
bundle.putBoolean(KEY_IS_LOADING, isLoading);
|
bundle.putBoolean(KEY_IS_LOADING, isLoading);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user