From ca4c6efdb7fdb50cef116d26360b79ed75a6401e Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 2 Dec 2022 10:11:04 +0000 Subject: [PATCH] Write media type with a custom key to legacy components. This allows legacy media controllers and browsers to access this information and legacy sessions and browser services to set this information. PiperOrigin-RevId: 492414716 --- .../media3/session/MediaConstants.java | 10 ++++ .../androidx/media3/session/MediaUtils.java | 31 ++++++++-- .../media3/session/MediaUtilsTest.java | 58 +++++++++++++++++-- .../media3/session/MediaTestUtils.java | 6 +- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaConstants.java b/libraries/session/src/main/java/androidx/media3/session/MediaConstants.java index d79385f5e4..8dda126ce4 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaConstants.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaConstants.java @@ -19,6 +19,7 @@ import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; +import android.support.v4.media.MediaDescriptionCompat; import android.support.v4.media.session.MediaControllerCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; @@ -455,6 +456,15 @@ public final class MediaConstants { androidx.media.utils.MediaConstants .BROWSER_SERVICE_EXTRAS_KEY_APPLICATION_PREFERENCES_USING_CAR_APP_LIBRARY_INTENT; + /** + * {@link Bundle} key used to indicate the {@link MediaMetadata.MediaType} in the legacy {@link + * MediaDescriptionCompat} as a long {@link MediaDescriptionCompat#getExtras() extra} and as a + * long value in {@link android.support.v4.media.MediaMetadataCompat}. + */ + @UnstableApi + public static final String EXTRAS_KEY_MEDIA_TYPE_COMPAT = + "androidx.media3.session.EXTRAS_KEY_MEDIA_TYPE_COMPAT"; + /* package */ static final String SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED = "androidx.media3.session.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED"; /* package */ static final String SESSION_COMMAND_REQUEST_SESSION3_TOKEN = diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java b/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java index 7caf715ea5..c805129dd4 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java @@ -339,15 +339,24 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; builder.setIconBitmap(artworkBitmap); } @Nullable Bundle extras = metadata.extras; - if (metadata.folderType != null && metadata.folderType != MediaMetadata.FOLDER_TYPE_NONE) { + boolean hasFolderType = + metadata.folderType != null && metadata.folderType != MediaMetadata.FOLDER_TYPE_NONE; + boolean hasMediaType = metadata.mediaType != null; + if (hasFolderType || hasMediaType) { if (extras == null) { extras = new Bundle(); } else { extras = new Bundle(extras); } - extras.putLong( - MediaDescriptionCompat.EXTRA_BT_FOLDER_TYPE, - convertToExtraBtFolderType(metadata.folderType)); + if (hasFolderType) { + extras.putLong( + MediaDescriptionCompat.EXTRA_BT_FOLDER_TYPE, + convertToExtraBtFolderType(checkNotNull(metadata.folderType))); + } + if (hasMediaType) { + extras.putLong( + MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT, checkNotNull(metadata.mediaType)); + } } return builder .setTitle(metadata.title) @@ -420,6 +429,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; builder.setFolderType(MediaMetadata.FOLDER_TYPE_NONE); } + if (extras != null && extras.containsKey(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)) { + builder.setMediaType((int) extras.getLong(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)); + } + builder.setIsPlayable(playable); return builder.build(); @@ -496,6 +509,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; builder.setFolderType(MediaMetadata.FOLDER_TYPE_NONE); } + if (metadataCompat.containsKey(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)) { + builder.setMediaType( + (int) metadataCompat.getLong(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)); + } + builder.setIsPlayable(true); return builder.build(); @@ -610,6 +628,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; builder.putRating(MediaMetadataCompat.METADATA_KEY_RATING, overallRatingCompat); } + if (mediaItem.mediaMetadata.mediaType != null) { + builder.putLong( + MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT, mediaItem.mediaMetadata.mediaType); + } + return builder.build(); } diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaUtilsTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaUtilsTest.java index 83c5a4e3f8..59209c334a 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaUtilsTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaUtilsTest.java @@ -142,20 +142,29 @@ public final class MediaUtilsTest { } @Test - public void convertToMediaDescriptionCompat() { + public void convertToMediaDescriptionCompat_setsExpectedValues() { String mediaId = "testId"; String title = "testTitle"; String description = "testDesc"; MediaMetadata metadata = - new MediaMetadata.Builder().setTitle(title).setDescription(description).build(); + new MediaMetadata.Builder() + .setTitle(title) + .setDescription(description) + .setMediaType(MediaMetadata.MEDIA_TYPE_MUSIC) + .build(); MediaItem mediaItem = new MediaItem.Builder().setMediaId(mediaId).setMediaMetadata(metadata).build(); MediaDescriptionCompat descriptionCompat = - MediaUtils.convertToMediaDescriptionCompat(mediaItem); + MediaUtils.convertToMediaDescriptionCompat(mediaItem, /* artworkBitmap= */ null); assertThat(descriptionCompat.getMediaId()).isEqualTo(mediaId); assertThat(descriptionCompat.getTitle()).isEqualTo(title); assertThat(descriptionCompat.getDescription()).isEqualTo(description); + assertThat( + descriptionCompat + .getExtras() + .getLong(androidx.media3.session.MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)) + .isEqualTo(MediaMetadata.MEDIA_TYPE_MUSIC); } @Test @@ -196,7 +205,8 @@ public final class MediaUtilsTest { } @Test - public void convertToMediaMetadata_roundTrip_returnsEqualMediaItem() throws Exception { + public void convertToMediaMetadata_roundTripViaMediaMetadataCompat_returnsEqualMediaItemMetadata() + throws Exception { MediaItem testMediaItem = MediaTestUtils.createMediaItemWithArtworkData("testZZZ"); MediaMetadata testMediaMetadata = testMediaItem.mediaMetadata; @Nullable Bitmap testArtworkBitmap = null; @@ -216,6 +226,46 @@ public final class MediaUtilsTest { assertThat(mediaMetadata.artworkData).isNotNull(); } + @Test + public void + convertToMediaMetadata_roundTripViaMediaDescriptionCompat_returnsEqualMediaItemMetadata() + throws Exception { + MediaItem testMediaItem = MediaTestUtils.createMediaItemWithArtworkData("testZZZ"); + MediaMetadata testMediaMetadata = testMediaItem.mediaMetadata; + @Nullable Bitmap testArtworkBitmap = null; + @Nullable + ListenableFuture bitmapFuture = bitmapLoader.loadBitmapFromMetadata(testMediaMetadata); + if (bitmapFuture != null) { + testArtworkBitmap = bitmapFuture.get(10, SECONDS); + } + MediaDescriptionCompat mediaDescriptionCompat = + MediaUtils.convertToMediaDescriptionCompat(testMediaItem, testArtworkBitmap); + + MediaMetadata mediaMetadata = + MediaUtils.convertToMediaMetadata(mediaDescriptionCompat, RatingCompat.RATING_NONE); + + assertThat(mediaMetadata).isEqualTo(testMediaMetadata); + assertThat(mediaMetadata.artworkData).isNotNull(); + } + + @Test + public void convertToMediaMetadataCompat_withMediaType_setsMediaType() { + MediaItem mediaItem = + new MediaItem.Builder() + .setMediaMetadata( + new MediaMetadata.Builder().setMediaType(MediaMetadata.MEDIA_TYPE_MUSIC).build()) + .build(); + + MediaMetadataCompat mediaMetadataCompat = + MediaUtils.convertToMediaMetadataCompat( + mediaItem, /* durotionsMs= */ C.TIME_UNSET, /* artworkBitmap= */ null); + + assertThat( + mediaMetadataCompat.getLong( + androidx.media3.session.MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)) + .isEqualTo(MediaMetadata.MEDIA_TYPE_MUSIC); + } + @Test public void convertBetweenRatingAndRatingCompat() { assertRatingEquals(MediaUtils.convertToRating(null), MediaUtils.convertToRatingCompat(null)); diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaTestUtils.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaTestUtils.java index 5d9e56a7c7..2a6af52728 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaTestUtils.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaTestUtils.java @@ -56,7 +56,8 @@ public final class MediaTestUtils { public static MediaItem createMediaItem(String mediaId) { MediaMetadata mediaMetadata = new MediaMetadata.Builder() - .setFolderType(MediaMetadata.FOLDER_TYPE_NONE) + .setFolderType(MediaMetadata.FOLDER_TYPE_TITLES) + .setMediaType(MediaMetadata.MEDIA_TYPE_PLAYLIST) .setIsPlayable(true) .build(); return new MediaItem.Builder().setMediaId(mediaId).setMediaMetadata(mediaMetadata).build(); @@ -65,7 +66,8 @@ public final class MediaTestUtils { public static MediaItem createMediaItemWithArtworkData(String mediaId) { MediaMetadata.Builder mediaMetadataBuilder = new MediaMetadata.Builder() - .setFolderType(MediaMetadata.FOLDER_TYPE_NONE) + .setFolderType(MediaMetadata.FOLDER_TYPE_TITLES) + .setMediaType(MediaMetadata.MEDIA_TYPE_PLAYLIST) .setIsPlayable(true); try { byte[] artworkData =