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
This commit is contained in:
tonihei 2022-12-02 10:11:04 +00:00 committed by Ian Baker
parent 85c48c481e
commit ca4c6efdb7
4 changed files with 95 additions and 10 deletions

View File

@ -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 =

View File

@ -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);
}
if (hasFolderType) {
extras.putLong(
MediaDescriptionCompat.EXTRA_BT_FOLDER_TYPE,
convertToExtraBtFolderType(metadata.folderType));
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();
}

View File

@ -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<Bitmap> 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));

View File

@ -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 =