diff --git a/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java b/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java index f0006efcf64..ee008a5dc18 100644 --- a/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java +++ b/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java @@ -36,6 +36,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -612,6 +613,10 @@ public Builder populate(@Nullable MediaMetadata mediaMetadata) { setExtras(mediaMetadata.extras); } + if (!mediaMetadata.supportedCommands.isEmpty()) { + setSupportedCommands(mediaMetadata.supportedCommands); + } + return this; } @@ -1250,6 +1255,7 @@ public boolean equals(@Nullable Object obj) { && Util.areEqual(compilation, that.compilation) && Util.areEqual(station, that.station) && Util.areEqual(mediaType, that.mediaType) + && Util.areEqual(supportedCommands, that.supportedCommands) && ((extras == null) == (that.extras == null)); } @@ -1290,7 +1296,8 @@ public int hashCode() { compilation, station, mediaType, - extras == null); + extras == null, + supportedCommands); } private static final String FIELD_TITLE = Util.intToStringMaxRadix(0); @@ -1327,6 +1334,7 @@ public int hashCode() { private static final String FIELD_MEDIA_TYPE = Util.intToStringMaxRadix(31); private static final String FIELD_IS_BROWSABLE = Util.intToStringMaxRadix(32); private static final String FIELD_DURATION_MS = Util.intToStringMaxRadix(33); + private static final String FIELD_SUPPORTED_COMMANDS = Util.intToStringMaxRadix(34); private static final String FIELD_EXTRAS = Util.intToStringMaxRadix(1000); @SuppressWarnings("deprecation") // Bundling deprecated fields. @@ -1432,6 +1440,9 @@ public Bundle toBundle() { if (mediaType != null) { bundle.putInt(FIELD_MEDIA_TYPE, mediaType); } + if (!supportedCommands.isEmpty()) { + bundle.putStringArrayList(FIELD_SUPPORTED_COMMANDS, new ArrayList<>(supportedCommands)); + } if (extras != null) { bundle.putBundle(FIELD_EXTRAS, extras); } @@ -1522,6 +1533,11 @@ public static MediaMetadata fromBundle(Bundle bundle) { if (bundle.containsKey(FIELD_MEDIA_TYPE)) { builder.setMediaType(bundle.getInt(FIELD_MEDIA_TYPE)); } + @Nullable + ArrayList supportedCommands = bundle.getStringArrayList(FIELD_SUPPORTED_COMMANDS); + if (supportedCommands != null) { + builder.setSupportedCommands(supportedCommands); + } return builder.build(); } diff --git a/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java b/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java index d3553fc9d91..54904024028 100644 --- a/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java @@ -20,6 +20,7 @@ import android.net.Uri; import android.os.Bundle; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.common.collect.ImmutableList; import org.junit.Test; import org.junit.runner.RunWith; @@ -68,6 +69,7 @@ public void builder_minimal_correctDefaults() { assertThat(mediaMetadata.compilation).isNull(); assertThat(mediaMetadata.station).isNull(); assertThat(mediaMetadata.mediaType).isNull(); + assertThat(mediaMetadata.supportedCommands).isEmpty(); assertThat(mediaMetadata.extras).isNull(); } @@ -278,6 +280,7 @@ private static MediaMetadata getFullyPopulatedMediaMetadata() { .setCompilation("Amazing songs.") .setStation("radio station") .setMediaType(MediaMetadata.MEDIA_TYPE_MIXED) + .setSupportedCommands(ImmutableList.of("command1", "command2")) .setExtras(extras) .build(); } diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java index f42a2b9b7c8..6311d791552 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java @@ -934,24 +934,14 @@ public void getCommandButtonsForMediaItem() throws Exception { .setSessionCommand( new SessionCommand(MediaBrowserConstants.COMMAND_RADIO, Bundle.EMPTY)) .build(); - MediaItem mediaItem = - new MediaItem.Builder() - .setMediaId("mediaId") - .setMediaMetadata( - new MediaMetadata.Builder() - .setSupportedCommands( - ImmutableList.of( - MediaBrowserConstants.COMMAND_PLAYLIST_ADD, - MediaBrowserConstants.COMMAND_RADIO, - "invalid")) - .build()) - .build(); MediaController controller = controllerTestRule.createController(session.getToken()); + MediaItem currentMediaItem = + threadTestRule.getHandler().postAndSync(controller::getCurrentMediaItem); ImmutableList commandButtons = threadTestRule .getHandler() - .postAndSync(() -> controller.getCommandButtonsForMediaItem(mediaItem)); + .postAndSync(() -> controller.getCommandButtonsForMediaItem(currentMediaItem)); assertThat(commandButtons).containsExactly(playlistAddButton, radioButton).inOrder(); session.cleanUp(); diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java index fc55b0dbb8d..18b4d13b8e7 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java @@ -253,6 +253,20 @@ public MediaSession.ConnectionResult onConnect( .build(); builder.setCommandButtonsForMediaItems( ImmutableList.of(playlistAddButton, radioButton)); + mockPlayer.timeline = + new PlaylistTimeline( + ImmutableList.of( + new MediaItem.Builder() + .setMediaId("mediaIdWithSupportedCommands") + .setMediaMetadata( + new MediaMetadata.Builder() + .setSupportedCommands( + ImmutableList.of( + MediaBrowserConstants.COMMAND_PLAYLIST_ADD, + MediaBrowserConstants.COMMAND_RADIO, + "invalid")) + .build()) + .build())); builder.setCallback( new MediaSession.Callback() { @Override