Skip to content

Commit 58d670d

Browse files
toniheimicrokatz
authored andcommitted
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 (cherry picked from commit c5e071e)
1 parent e05e319 commit 58d670d

File tree

13 files changed

+280
-102
lines changed

13 files changed

+280
-102
lines changed

libraries/session/src/main/java/androidx/media3/session/MediaConstants.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
public final class MediaConstants {
3333

3434
/**
35-
* The legacy error code for expired authentication.
35+
* {@link Bundle} key used for the error code for expired authentication.
3636
*
3737
*

Use this error code to indicate an expired authentication when {@linkplain

3838
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
@@ -43,7 +43,23 @@ public final class MediaConstants {
4343
public static final int ERROR_CODE_AUTHENTICATION_EXPIRED_COMPAT = 3;
4444

4545
/**
46-
* The extras key for the localized error resolution string.
46+
* {@link Bundle} key used for the value of {@code Player.getPlaybackParameters().speed}.
47+
*
48+
*

Use this key in the extras bundle of the legacy {@link PlaybackStateCompat}.

49+
*/
50+
@UnstableApi public static final String EXTRAS_KEY_PLAYBACK_SPEED_COMPAT = "EXO_SPEED";
51+
52+
/**
53+
* {@link Bundle} key used for the media id of the media being played.
54+
*
55+
*

Use this key in the extras bundle of the legacy {@link PlaybackStateCompat}.

56+
*/
57+
@UnstableApi
58+
public static final String EXTRAS_KEY_MEDIA_ID_COMPAT =
59+
androidx.media.utils.MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID;
60+
61+
/**
62+
* {@link Bundle} key used for a localized error resolution string.
4763
*
4864
*

Use this key to populate the extras bundle of the {@link LibraryParams} when {@linkplain

4965
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful
@@ -53,7 +69,7 @@ public final class MediaConstants {
5369
androidx.media.utils.MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL;
5470

5571
/**
56-
* The extras key for the error resolution intent.
72+
* {@link Bundle} key used for an error resolution intent.
5773
*
5874
*

Use this key to populate the extras bundle of the {@link LibraryParams} when {@linkplain

5975
* LibraryResult#ofError(int, LibraryParams) creating a library result} for an unsuccessful

libraries/session/src/main/java/androidx/media3/session/MediaUtils.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -728,20 +728,17 @@ public static RatingCompat convertToRatingCompat(@Nullable Rating rating) {
728728
public static int convertToPlaybackStateCompatState(
729729
@Nullable PlaybackException playerError,
730730
@Player.State int playbackState,
731-
boolean playWhenReady,
732-
boolean isPlaying) {
731+
boolean playWhenReady) {
733732
if (playerError != null) {
734733
return PlaybackStateCompat.STATE_ERROR;
735734
}
736-
if (isPlaying) {
737-
return PlaybackStateCompat.STATE_PLAYING;
738-
}
739735
switch (playbackState) {
740736
case Player.STATE_IDLE:
741737
return PlaybackStateCompat.STATE_NONE;
742738
case Player.STATE_READY:
739+
return playWhenReady ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
743740
case Player.STATE_ENDED:
744-
return PlaybackStateCompat.STATE_PAUSED;
741+
return PlaybackStateCompat.STATE_STOPPED;
745742
case Player.STATE_BUFFERING:
746743
return playWhenReady
747744
? PlaybackStateCompat.STATE_BUFFERING

libraries/session/src/main/java/androidx/media3/session/PlayerWrapper.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import static androidx.media3.common.util.Assertions.checkNotNull;
1919
import static androidx.media3.common.util.Assertions.checkState;
2020
import static androidx.media3.common.util.Util.postOrRun;
21+
import static androidx.media3.session.MediaConstants.EXTRAS_KEY_MEDIA_ID_COMPAT;
22+
import static androidx.media3.session.MediaConstants.EXTRAS_KEY_PLAYBACK_SPEED_COMPAT;
2123

2224
import android.media.AudioManager;
2325
import android.os.Bundle;
@@ -768,7 +770,7 @@ public PlaybackStateCompat createPlaybackStateCompat() {
768770
@Nullable PlaybackException playerError = getPlayerError();
769771
int state =
770772
MediaUtils.convertToPlaybackStateCompatState(
771-
playerError, getPlaybackState(), getPlayWhenReady(), isPlaying());
773+
playerError, getPlaybackState(), getPlayWhenReady());
772774
long allActions =
773775
PlaybackStateCompat.ACTION_STOP
774776
| PlaybackStateCompat.ACTION_PAUSE
@@ -798,16 +800,22 @@ public PlaybackStateCompat createPlaybackStateCompat() {
798800
allActions |= PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
799801
}
800802
long queueItemId = MediaUtils.convertToQueueItemId(getCurrentMediaItemIndex());
803+
float playbackSpeed = getPlaybackParameters().speed;
804+
float sessionPlaybackSpeed = isPlaying() ? playbackSpeed : 0f;
805+
Bundle extras = new Bundle();
806+
extras.putFloat(EXTRAS_KEY_PLAYBACK_SPEED_COMPAT, playbackSpeed);
807+
@Nullable MediaItem currentMediaItem = getCurrentMediaItem();
808+
if (currentMediaItem != null && !MediaItem.DEFAULT_MEDIA_ID.equals(currentMediaItem.mediaId)) {
809+
extras.putString(EXTRAS_KEY_MEDIA_ID_COMPAT, currentMediaItem.mediaId);
810+
}
801811
PlaybackStateCompat.Builder builder =
802812
new PlaybackStateCompat.Builder()
803813
.setState(
804-
state,
805-
getCurrentPosition(),
806-
getPlaybackParameters().speed,
807-
SystemClock.elapsedRealtime())
814+
state, getCurrentPosition(), sessionPlaybackSpeed, SystemClock.elapsedRealtime())
808815
.setActions(allActions)
809816
.setActiveQueueItemId(queueItemId)
810-
.setBufferedPosition(getBufferedPosition());
817+
.setBufferedPosition(getBufferedPosition())
818+
.setExtras(extras);
811819

812820
for (int i = 0; i < customLayout.size(); i++) {
813821
CommandButton commandButton = customLayout.get(i);

libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaSession.aidl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ interface IRemoteMediaSession {
5555
void notifyPlayerError(String sessionId, in Bundle playerErrorBundle);
5656
void notifyPlayWhenReadyChanged(String sessionId, boolean playWhenReady, int reason);
5757
void notifyPlaybackStateChanged(String sessionId, int state);
58-
void notifyIsPlayingChanged(String sessionId, boolean isPlaying);
5958
void notifyIsLoadingChanged(String sessionId, boolean isLoading);
6059
void notifyPositionDiscontinuity(String sessionId,
6160
in Bundle oldPositionBundle, in Bundle newPositionBundle, int reason);

libraries/test_session_common/src/main/java/androidx/media3/test/session/common/CommonConstants.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ public class CommonConstants {
9090
public static final String KEY_PLAY_WHEN_READY = "playWhenReady";
9191
public static final String KEY_PLAYBACK_SUPPRESSION_REASON = "playbackSuppressionReason";
9292
public static final String KEY_PLAYBACK_STATE = "playbackState";
93-
public static final String KEY_IS_PLAYING = "isPlaying";
9493
public static final String KEY_IS_LOADING = "isLoading";
9594
public static final String KEY_REPEAT_MODE = "repeatMode";
9695
public static final String KEY_SHUFFLE_MODE_ENABLED = "shuffleModeEnabled";

libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ public void onError(String parentId) {
338338
}
339339
});
340340
assertThat(errorLatch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
341-
assertThat(lastReportedPlaybackStateCompat).isNotNull();
342341
assertThat(lastReportedPlaybackStateCompat.getState())
343342
.isEqualTo(PlaybackStateCompat.STATE_ERROR);
344343
assertThat(
@@ -361,7 +360,11 @@ public void onChildrenLoaded(String parentId, List children) {
361360
// Any successful calls remove the error state,
362361
assertThat(lastReportedPlaybackStateCompat.getState())
363362
.isNotEqualTo(PlaybackStateCompat.STATE_ERROR);
364-
assertThat(lastReportedPlaybackStateCompat.getExtras()).isNull();
363+
assertThat(
364+
lastReportedPlaybackStateCompat
365+
.getExtras()
366+
.getString(MediaConstants.EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL_COMPAT))
367+
.isNull();
365368
}
366369

367370
@Test

0 commit comments

Comments
 (0)