Handle displayTitle and title in legacy conversions

When converting `MediaMetadata` to the legacy `MediaDescriptionCompat`
the selection and order of properties to use has been aligned with the
behavior of media1. This selection is relevant for users that use a
platform or legacy controller or browser. Before and up to the current
API version 34, this includes System UI, Android Auto/Automotive and
AVRCP (Bluetooth).

PiperOrigin-RevId: 630999535
This commit is contained in:
bachinger 2024-05-06 04:19:18 -07:00 committed by Copybara-Service
parent 1ef0b7c616
commit 2c912aa697
10 changed files with 308 additions and 50 deletions

View File

@ -73,6 +73,9 @@
* Hide seekbar in the media notification for live streams by not setting * Hide seekbar in the media notification for live streams by not setting
the duration into the platform session metadata the duration into the platform session metadata
([#1256](https://github.com/androidx/media/issues/1256)). ([#1256](https://github.com/androidx/media/issues/1256)).
* Align conversion of `MediaMetadata` to `MediaDescriptionCompat`, to use
the same preferred order and logic when selecting metadata properties as
in media1.
* UI: * UI:
* Downloads: * Downloads:
* OkHttp Extension: * OkHttp Extension:

View File

@ -43,6 +43,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.constrainValue; import static androidx.media3.common.util.Util.constrainValue;
import static androidx.media3.session.MediaConstants.EXTRA_KEY_ROOT_CHILDREN_BROWSABLE_ONLY; import static androidx.media3.session.MediaConstants.EXTRA_KEY_ROOT_CHILDREN_BROWSABLE_ONLY;
import static androidx.media3.session.legacy.MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS; import static androidx.media3.session.legacy.MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS;
import static androidx.media3.session.legacy.MediaMetadataCompat.PREFERRED_DESCRIPTION_ORDER;
import static androidx.media3.session.legacy.MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS; import static androidx.media3.session.legacy.MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -342,7 +343,6 @@ import java.util.concurrent.TimeoutException;
MediaMetadata.Builder builder = new MediaMetadata.Builder(); MediaMetadata.Builder builder = new MediaMetadata.Builder();
builder builder
.setTitle(descriptionCompat.getTitle())
.setSubtitle(descriptionCompat.getSubtitle()) .setSubtitle(descriptionCompat.getSubtitle())
.setDescription(descriptionCompat.getDescription()) .setDescription(descriptionCompat.getDescription())
.setArtworkUri(descriptionCompat.getIconUri()) .setArtworkUri(descriptionCompat.getIconUri())
@ -373,6 +373,17 @@ import java.util.concurrent.TimeoutException;
builder.setMediaType((int) extras.getLong(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT)); builder.setMediaType((int) extras.getLong(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT));
extras.remove(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT); extras.remove(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT);
} }
if (extras != null
&& extras.containsKey(MediaConstants.EXTRAS_KEY_MEDIA_DESCRIPTION_COMPAT_TITLE)) {
builder.setTitle(
extras.getCharSequence(MediaConstants.EXTRAS_KEY_MEDIA_DESCRIPTION_COMPAT_TITLE));
builder.setDisplayTitle(descriptionCompat.getTitle());
extras.remove(MediaConstants.EXTRAS_KEY_MEDIA_DESCRIPTION_COMPAT_TITLE);
} else {
builder.setTitle(descriptionCompat.getTitle());
}
if (extras != null && !extras.isEmpty()) { if (extras != null && !extras.isEmpty()) {
builder.setExtras(extras); builder.setExtras(extras);
} }
@ -392,12 +403,12 @@ import java.util.concurrent.TimeoutException;
MediaMetadata.Builder builder = new MediaMetadata.Builder(); MediaMetadata.Builder builder = new MediaMetadata.Builder();
CharSequence title = metadataCompat.getText(MediaMetadataCompat.METADATA_KEY_TITLE);
CharSequence displayTitle =
metadataCompat.getText(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE);
builder builder
.setTitle( .setTitle(title != null ? title : displayTitle)
getFirstText( .setDisplayTitle(title != null ? displayTitle : null)
metadataCompat,
MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE,
MediaMetadataCompat.METADATA_KEY_TITLE))
.setSubtitle(metadataCompat.getText(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE)) .setSubtitle(metadataCompat.getText(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE))
.setDescription( .setDescription(
metadataCompat.getText(MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION)) metadataCompat.getText(MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION))
@ -502,17 +513,6 @@ import java.util.concurrent.TimeoutException;
return null; return null;
} }
@Nullable
private static CharSequence getFirstText(
MediaMetadataCompat mediaMetadataCompat, String... keys) {
for (String key : keys) {
if (mediaMetadataCompat.containsKey(key)) {
return mediaMetadataCompat.getText(key);
}
}
return null;
}
/** /**
* Converts a {@link MediaMetadata} to a {@link MediaMetadataCompat}. * Converts a {@link MediaMetadata} to a {@link MediaMetadataCompat}.
* *
@ -538,7 +538,10 @@ import java.util.concurrent.TimeoutException;
if (metadata.title != null) { if (metadata.title != null) {
builder.putText(MediaMetadataCompat.METADATA_KEY_TITLE, metadata.title); builder.putText(MediaMetadataCompat.METADATA_KEY_TITLE, metadata.title);
builder.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, metadata.title); }
if (metadata.displayTitle != null) {
builder.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, metadata.displayTitle);
} }
if (metadata.subtitle != null) { if (metadata.subtitle != null) {
@ -638,14 +641,15 @@ import java.util.concurrent.TimeoutException;
builder.setIconBitmap(artworkBitmap); builder.setIconBitmap(artworkBitmap);
} }
@Nullable Bundle extras = metadata.extras; @Nullable Bundle extras = metadata.extras;
if (extras != null) {
extras = new Bundle(extras);
}
boolean hasFolderType = boolean hasFolderType =
metadata.folderType != null && metadata.folderType != MediaMetadata.FOLDER_TYPE_NONE; metadata.folderType != null && metadata.folderType != MediaMetadata.FOLDER_TYPE_NONE;
boolean hasMediaType = metadata.mediaType != null; boolean hasMediaType = metadata.mediaType != null;
if (hasFolderType || hasMediaType) { if (hasFolderType || hasMediaType) {
if (extras == null) { if (extras == null) {
extras = new Bundle(); extras = new Bundle();
} else {
extras = new Bundle(extras);
} }
if (hasFolderType) { if (hasFolderType) {
extras.putLong( extras.putLong(
@ -657,18 +661,67 @@ import java.util.concurrent.TimeoutException;
MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT, checkNotNull(metadata.mediaType)); MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT, checkNotNull(metadata.mediaType));
} }
} }
return builder CharSequence title;
.setTitle(metadata.title) CharSequence subtitle;
CharSequence description;
if (metadata.displayTitle != null) {
title = metadata.displayTitle;
subtitle = metadata.subtitle;
description = metadata.description;
if (extras == null) {
extras = new Bundle();
}
extras.putCharSequence(
MediaConstants.EXTRAS_KEY_MEDIA_DESCRIPTION_COMPAT_TITLE, metadata.title);
} else {
// The BT AVRPC service expects the subtitle of the media description to be the artist // The BT AVRPC service expects the subtitle of the media description to be the artist
// (see https://github.com/androidx/media/issues/148). // (see https://github.com/androidx/media/issues/148). This can be achieved by NOT setting the
.setSubtitle(metadata.artist != null ? metadata.artist : metadata.subtitle) // `displayTitle` when setting the `artist`, or by setting the `displayTitle` and writing the
.setDescription(metadata.description) // artist into the `subtitle`. When `displayTitle` is set, the artist is always ignored.
CharSequence[] texts = new CharSequence[3];
int textIndex = 0;
int keyIndex = 0;
while (textIndex < texts.length && keyIndex < PREFERRED_DESCRIPTION_ORDER.length) {
CharSequence next = getText(PREFERRED_DESCRIPTION_ORDER[keyIndex++], metadata);
if (!TextUtils.isEmpty(next)) {
// Fill in the next empty bit of text
texts[textIndex++] = next;
}
}
title = texts[0];
subtitle = texts[1];
description = texts[2];
}
return builder
.setTitle(title)
.setSubtitle(subtitle)
.setDescription(description)
.setIconUri(metadata.artworkUri) .setIconUri(metadata.artworkUri)
.setMediaUri(item.requestMetadata.mediaUri) .setMediaUri(item.requestMetadata.mediaUri)
.setExtras(extras) .setExtras(extras)
.build(); .build();
} }
@Nullable
private static CharSequence getText(String key, MediaMetadata metadata) {
switch (key) {
case MediaMetadataCompat.METADATA_KEY_TITLE:
return metadata.title;
case MediaMetadataCompat.METADATA_KEY_ARTIST:
return metadata.artist;
case MediaMetadataCompat.METADATA_KEY_ALBUM:
return metadata.albumTitle;
case MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST:
return metadata.albumArtist;
case MediaMetadataCompat.METADATA_KEY_WRITER:
return metadata.writer;
case MediaMetadataCompat.METADATA_KEY_COMPOSER:
return metadata.composer;
default:
return null;
}
}
@SuppressWarnings("deprecation") // Converting to deprecated constants. @SuppressWarnings("deprecation") // Converting to deprecated constants.
@MediaMetadata.FolderType @MediaMetadata.FolderType
private static int convertToFolderType(long extraBtFolderType) { private static int convertToFolderType(long extraBtFolderType) {

View File

@ -479,6 +479,14 @@ public final class MediaConstants {
public static final String EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT = public static final String EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT =
"androidx.media3.session.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT"; "androidx.media3.session.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT";
/**
* {@link Bundle} key used to store the title in case there was a display title that was given
* precedence when converting to a {@code MediaDescriptionCompat}. This key is only used to be
* able to convert back to the Media3 {@link MediaMetadata}.
*/
/* package */ static final String EXTRAS_KEY_MEDIA_DESCRIPTION_COMPAT_TITLE =
"androidx.media3.mediadescriptioncompat.title";
/* package */ static final String SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED = /* package */ static final String SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED =
"androidx.media3.session.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED"; "androidx.media3.session.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED";
/* package */ static final String SESSION_COMMAND_REQUEST_SESSION3_TOKEN = /* package */ static final String SESSION_COMMAND_REQUEST_SESSION3_TOKEN =

View File

@ -310,7 +310,7 @@ public final class MediaMetadataCompat implements Parcelable {
METADATA_KEYS_TYPE.put(METADATA_KEY_DOWNLOAD_STATUS, METADATA_TYPE_LONG); METADATA_KEYS_TYPE.put(METADATA_KEY_DOWNLOAD_STATUS, METADATA_TYPE_LONG);
} }
private static final @TextKey String[] PREFERRED_DESCRIPTION_ORDER = { public static final @TextKey String[] PREFERRED_DESCRIPTION_ORDER = {
METADATA_KEY_TITLE, METADATA_KEY_TITLE,
METADATA_KEY_ARTIST, METADATA_KEY_ARTIST,
METADATA_KEY_ALBUM, METADATA_KEY_ALBUM,

View File

@ -150,29 +150,186 @@ public final class LegacyConversionsTest {
@Test @Test
public void convertToMediaDescriptionCompat_setsExpectedValues() { public void convertToMediaDescriptionCompat_setsExpectedValues() {
String mediaId = "testId";
String title = "testTitle";
String description = "testDesc";
MediaMetadata metadata = MediaMetadata metadata =
new MediaMetadata.Builder() new MediaMetadata.Builder()
.setTitle(title) .setTitle("testTitle")
.setDescription(description) .setArtist("testArtist")
.setAlbumTitle("testAlbumTitle")
.setWriter("testWriter")
.setMediaType(MediaMetadata.MEDIA_TYPE_MUSIC) .setMediaType(MediaMetadata.MEDIA_TYPE_MUSIC)
.setDurationMs(10_000L) .setDurationMs(10_000L)
.build(); .build();
MediaItem mediaItem = MediaItem mediaItem =
new MediaItem.Builder().setMediaId(mediaId).setMediaMetadata(metadata).build(); new MediaItem.Builder().setMediaId("testId").setMediaMetadata(metadata).build();
MediaDescriptionCompat descriptionCompat = MediaDescriptionCompat descriptionCompat =
LegacyConversions.convertToMediaDescriptionCompat(mediaItem, /* artworkBitmap= */ null); LegacyConversions.convertToMediaDescriptionCompat(mediaItem, /* artworkBitmap= */ null);
assertThat(descriptionCompat.getMediaId()).isEqualTo(mediaId); assertThat(descriptionCompat.getMediaId()).isEqualTo("testId");
assertThat(descriptionCompat.getTitle().toString()).isEqualTo(title); assertThat(descriptionCompat.getTitle().toString()).isEqualTo("testTitle");
assertThat(descriptionCompat.getDescription().toString()).isEqualTo(description); assertThat(descriptionCompat.getSubtitle().toString()).isEqualTo("testArtist");
assertThat(descriptionCompat.getDescription().toString()).isEqualTo("testAlbumTitle");
assertThat(descriptionCompat.getExtras().getLong(EXTRAS_KEY_MEDIA_TYPE_COMPAT)) assertThat(descriptionCompat.getExtras().getLong(EXTRAS_KEY_MEDIA_TYPE_COMPAT))
.isEqualTo(MediaMetadata.MEDIA_TYPE_MUSIC); .isEqualTo(MediaMetadata.MEDIA_TYPE_MUSIC);
} }
@Test
public void convertToMediaDescriptionCompat_displayTitleAndTitleHandledCorrectly() {
MediaMetadata metadataWithTitleOnly =
new MediaMetadata.Builder()
.setTitle("title")
.setSubtitle("subtitle")
.setDescription("description")
.setArtist("artist")
.setAlbumTitle("albumTitle")
.setIsBrowsable(false)
.setIsPlayable(true)
.build();
MediaItem mediaItemWithTitleOnly =
new MediaItem.Builder().setMediaMetadata(metadataWithTitleOnly).build();
MediaMetadata metadataWithDisplayTitleOnly =
new MediaMetadata.Builder()
.setDisplayTitle("displayTitle")
.setSubtitle("subtitle")
.setDescription("description")
.setArtist("artist")
.setAlbumTitle("albumTitle")
.setIsBrowsable(false)
.setIsPlayable(true)
.build();
MediaItem mediaItemWithDisplayTitleOnly =
new MediaItem.Builder().setMediaMetadata(metadataWithDisplayTitleOnly).build();
MediaMetadata metadataWithDisplayTitleAndTitle =
new MediaMetadata.Builder()
.setDisplayTitle("displayTitle")
.setTitle("title")
.setSubtitle("subtitle")
.setDescription("description")
.setArtist("artist")
.setAlbumTitle("albumTitle")
.setIsBrowsable(false)
.setIsPlayable(true)
.build();
MediaItem mediaItemWithDisplayTitleAndTitle =
new MediaItem.Builder().setMediaMetadata(metadataWithDisplayTitleAndTitle).build();
MediaDescriptionCompat descriptionCompatWithTitleOnly =
LegacyConversions.convertToMediaDescriptionCompat(
mediaItemWithTitleOnly, /* artworkBitmap= */ null);
MediaDescriptionCompat descriptionCompatWithDisplayTitleOnly =
LegacyConversions.convertToMediaDescriptionCompat(
mediaItemWithDisplayTitleOnly, /* artworkBitmap= */ null);
MediaDescriptionCompat descriptionCompatWithDisplayTitleAndTitle =
LegacyConversions.convertToMediaDescriptionCompat(
mediaItemWithDisplayTitleAndTitle, /* artworkBitmap= */ null);
MediaItem convertedMediaItemWithTitleOnly =
LegacyConversions.convertToMediaItem(descriptionCompatWithTitleOnly);
MediaItem convertedMediaItemWithDisplayTitleOnly =
LegacyConversions.convertToMediaItem(descriptionCompatWithDisplayTitleOnly);
MediaItem convertedMediaItemWithDisplayTitleAndTitle =
LegacyConversions.convertToMediaItem(descriptionCompatWithDisplayTitleAndTitle);
assertThat(convertedMediaItemWithTitleOnly.mediaMetadata.title.toString()).isEqualTo("title");
assertThat(convertedMediaItemWithTitleOnly.mediaMetadata.subtitle.toString())
.isEqualTo("artist");
assertThat(convertedMediaItemWithTitleOnly.mediaMetadata.description.toString())
.isEqualTo("albumTitle");
assertThat(convertedMediaItemWithTitleOnly.mediaMetadata.displayTitle).isNull();
assertThat(convertedMediaItemWithTitleOnly.mediaMetadata.artist).isNull();
assertThat(convertedMediaItemWithTitleOnly.mediaMetadata.albumTitle).isNull();
assertThat(convertedMediaItemWithDisplayTitleOnly.mediaMetadata.title).isNull();
assertThat(convertedMediaItemWithDisplayTitleOnly.mediaMetadata.subtitle.toString())
.isEqualTo("subtitle");
assertThat(convertedMediaItemWithDisplayTitleOnly.mediaMetadata.description.toString())
.isEqualTo("description");
assertThat(convertedMediaItemWithDisplayTitleOnly.mediaMetadata.displayTitle.toString())
.isEqualTo("displayTitle");
assertThat(convertedMediaItemWithDisplayTitleOnly.mediaMetadata.artist).isNull();
assertThat(convertedMediaItemWithDisplayTitleOnly.mediaMetadata.albumTitle).isNull();
assertThat(convertedMediaItemWithDisplayTitleAndTitle.mediaMetadata.title.toString())
.isEqualTo("title");
assertThat(convertedMediaItemWithDisplayTitleAndTitle.mediaMetadata.subtitle.toString())
.isEqualTo("subtitle");
assertThat(convertedMediaItemWithDisplayTitleAndTitle.mediaMetadata.description.toString())
.isEqualTo("description");
assertThat(convertedMediaItemWithDisplayTitleAndTitle.mediaMetadata.displayTitle.toString())
.isEqualTo("displayTitle");
assertThat(convertedMediaItemWithDisplayTitleAndTitle.mediaMetadata.artist).isNull();
assertThat(convertedMediaItemWithDisplayTitleAndTitle.mediaMetadata.albumTitle).isNull();
}
@Test
public void convertToMediaMetadataCompat_displayTitleAndTitleHandledCorrectly() {
MediaMetadata mediaMetadataWithTitleOnly =
new MediaMetadata.Builder()
.setTitle("title")
.setSubtitle("subtitle")
.setDescription("description")
.setArtist("artist")
.setAlbumArtist("albumArtist")
.build();
MediaMetadata mediaMetadataWithDisplayTitleOnly =
new MediaMetadata.Builder()
.setDisplayTitle("displayTitle")
.setSubtitle("subtitle")
.setDescription("description")
.setArtist("artist")
.setAlbumArtist("albumArtist")
.build();
MediaMetadata mediaMetadataWithDisplayTitleAndTitle =
new MediaMetadata.Builder()
.setTitle("title")
.setDisplayTitle("displayTitle")
.setSubtitle("subtitle")
.setDescription("description")
.setArtist("artist")
.setAlbumArtist("albumArtist")
.build();
MediaDescriptionCompat mediaDescriptionCompatFromDisplayTitleAndTitle =
LegacyConversions.convertToMediaMetadataCompat(
mediaMetadataWithDisplayTitleAndTitle,
"mediaId",
/* mediaUri= */ null,
/* durationMs= */ 10_000L,
/* artworkBitmap= */ null)
.getDescription();
MediaDescriptionCompat mediaDescriptionCompatFromDisplayTitleOnly =
LegacyConversions.convertToMediaMetadataCompat(
mediaMetadataWithDisplayTitleOnly,
"mediaId",
/* mediaUri= */ null,
/* durationMs= */ 10_000L,
/* artworkBitmap= */ null)
.getDescription();
MediaDescriptionCompat mediaDescriptionCompatFromTitleOnly =
LegacyConversions.convertToMediaMetadataCompat(
mediaMetadataWithTitleOnly,
"mediaId",
/* mediaUri= */ null,
/* durationMs= */ 10_000L,
/* artworkBitmap= */ null)
.getDescription();
assertThat(mediaDescriptionCompatFromDisplayTitleAndTitle.getTitle().toString())
.isEqualTo("displayTitle");
assertThat(mediaDescriptionCompatFromDisplayTitleAndTitle.getSubtitle().toString())
.isEqualTo("subtitle");
assertThat(mediaDescriptionCompatFromDisplayTitleAndTitle.getDescription().toString())
.isEqualTo("description");
assertThat(mediaDescriptionCompatFromDisplayTitleOnly.getTitle().toString())
.isEqualTo("displayTitle");
assertThat(mediaDescriptionCompatFromDisplayTitleOnly.getSubtitle().toString())
.isEqualTo("subtitle");
assertThat(mediaDescriptionCompatFromDisplayTitleOnly.getDescription().toString())
.isEqualTo("description");
assertThat(mediaDescriptionCompatFromTitleOnly.getTitle().toString()).isEqualTo("title");
assertThat(mediaDescriptionCompatFromTitleOnly.getSubtitle().toString()).isEqualTo("artist");
assertThat(mediaDescriptionCompatFromTitleOnly.getDescription().toString())
.isEqualTo("albumArtist");
}
@Test @Test
public void convertToQueueItemId() { public void convertToQueueItemId() {
assertThat(LegacyConversions.convertToQueueItemId(C.INDEX_UNSET)) assertThat(LegacyConversions.convertToQueueItemId(C.INDEX_UNSET))
@ -237,6 +394,20 @@ public final class LegacyConversionsTest {
assertThat(mediaMetadata.artworkData).isNotNull(); assertThat(mediaMetadata.artworkData).isNotNull();
} }
@Test
public void convertToMediaMetadata_displayTitleKeyOnly_movedToTitle() {
MediaMetadataCompat testMediaMetadataCompat =
new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "displayTitle")
.build();
MediaMetadata mediaMetadata =
LegacyConversions.convertToMediaMetadata(testMediaMetadataCompat, RatingCompat.RATING_NONE);
assertThat(mediaMetadata.title).isEqualTo("displayTitle");
assertThat(mediaMetadata.displayTitle).isNull();
}
@Test @Test
public void public void
convertToMediaMetadata_roundTripViaMediaDescriptionCompat_returnsEqualMediaItemMetadata() convertToMediaMetadata_roundTripViaMediaDescriptionCompat_returnsEqualMediaItemMetadata()
@ -1162,6 +1333,8 @@ public final class LegacyConversionsTest {
MediaMetadata.Builder mediaMetadataBuilder = MediaMetadata.Builder mediaMetadataBuilder =
new MediaMetadata.Builder() new MediaMetadata.Builder()
.setMediaType(MediaMetadata.MEDIA_TYPE_PLAYLIST) .setMediaType(MediaMetadata.MEDIA_TYPE_PLAYLIST)
.setTitle("title")
.setDisplayTitle("displayTitle")
.setIsBrowsable(false) .setIsBrowsable(false)
.setIsPlayable(true) .setIsPlayable(true)
.setExtras(extras); .setExtras(extras);

View File

@ -20,12 +20,12 @@ import static androidx.media3.session.MediaConstants.EXTRAS_KEY_COMPLETION_STATU
import static androidx.media3.session.MediaConstants.EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED; import static androidx.media3.session.MediaConstants.EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED;
import static androidx.media3.session.MockMediaLibraryService.CONNECTION_HINTS_CUSTOM_LIBRARY_ROOT; import static androidx.media3.session.MockMediaLibraryService.CONNECTION_HINTS_CUSTOM_LIBRARY_ROOT;
import static androidx.media3.session.MockMediaLibraryService.createNotifyChildrenChangedBundle; import static androidx.media3.session.MockMediaLibraryService.createNotifyChildrenChangedBundle;
import static androidx.media3.test.session.common.CommonConstants.METADATA_ALBUM_TITLE;
import static androidx.media3.test.session.common.CommonConstants.METADATA_ARTIST;
import static androidx.media3.test.session.common.CommonConstants.METADATA_ARTWORK_URI; import static androidx.media3.test.session.common.CommonConstants.METADATA_ARTWORK_URI;
import static androidx.media3.test.session.common.CommonConstants.METADATA_DESCRIPTION;
import static androidx.media3.test.session.common.CommonConstants.METADATA_EXTRA_KEY; import static androidx.media3.test.session.common.CommonConstants.METADATA_EXTRA_KEY;
import static androidx.media3.test.session.common.CommonConstants.METADATA_EXTRA_VALUE; import static androidx.media3.test.session.common.CommonConstants.METADATA_EXTRA_VALUE;
import static androidx.media3.test.session.common.CommonConstants.METADATA_MEDIA_URI; import static androidx.media3.test.session.common.CommonConstants.METADATA_MEDIA_URI;
import static androidx.media3.test.session.common.CommonConstants.METADATA_SUBTITLE;
import static androidx.media3.test.session.common.CommonConstants.METADATA_TITLE; import static androidx.media3.test.session.common.CommonConstants.METADATA_TITLE;
import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_LIBRARY_SERVICE; import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_LIBRARY_SERVICE;
import static androidx.media3.test.session.common.MediaBrowserConstants.CHILDREN_COUNT; import static androidx.media3.test.session.common.MediaBrowserConstants.CHILDREN_COUNT;
@ -181,8 +181,8 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
assertThat(itemRef.get().getMediaId()).isEqualTo(mediaId); assertThat(itemRef.get().getMediaId()).isEqualTo(mediaId);
MediaDescriptionCompat description = itemRef.get().getDescription(); MediaDescriptionCompat description = itemRef.get().getDescription();
assertThat(TextUtils.equals(description.getTitle(), METADATA_TITLE)).isTrue(); assertThat(TextUtils.equals(description.getTitle(), METADATA_TITLE)).isTrue();
assertThat(TextUtils.equals(description.getSubtitle(), METADATA_SUBTITLE)).isTrue(); assertThat(TextUtils.equals(description.getSubtitle(), METADATA_ARTIST)).isTrue();
assertThat(TextUtils.equals(description.getDescription(), METADATA_DESCRIPTION)).isTrue(); assertThat(TextUtils.equals(description.getDescription(), METADATA_ALBUM_TITLE)).isTrue();
assertThat(description.getIconUri()).isEqualTo(METADATA_ARTWORK_URI); assertThat(description.getIconUri()).isEqualTo(METADATA_ARTWORK_URI);
assertThat(description.getMediaUri()).isEqualTo(METADATA_MEDIA_URI); assertThat(description.getMediaUri()).isEqualTo(METADATA_MEDIA_URI);
BundleSubject.assertThat(description.getExtras()) BundleSubject.assertThat(description.getExtras())

View File

@ -1081,12 +1081,13 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
throws Exception { throws Exception {
int testItemIndex = 3; int testItemIndex = 3;
long testPosition = 1234; long testPosition = 1234;
String testTitle = "title";
String testDisplayTitle = "displayTitle"; String testDisplayTitle = "displayTitle";
long testDurationMs = 30_000; long testDurationMs = 30_000;
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(/* size= */ 5); List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(/* size= */ 5);
String testCurrentMediaId = testMediaItems.get(testItemIndex).mediaId; String testCurrentMediaId = testMediaItems.get(testItemIndex).mediaId;
MediaMetadata testMediaMetadata = MediaMetadata testMediaMetadata =
new MediaMetadata.Builder().setTitle(testDisplayTitle).build(); new MediaMetadata.Builder().setTitle(testTitle).setDisplayTitle(testDisplayTitle).build();
testMediaItems.set( testMediaItems.set(
testItemIndex, testItemIndex,
new MediaItem.Builder() new MediaItem.Builder()
@ -1129,6 +1130,10 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
MediaMetadataCompat parameterMetadataCompat = metadataRef.get(); MediaMetadataCompat parameterMetadataCompat = metadataRef.get();
MediaMetadataCompat getterMetadataCompat = controllerCompat.getMetadata(); MediaMetadataCompat getterMetadataCompat = controllerCompat.getMetadata();
assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
.isEqualTo(testTitle);
assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
.isEqualTo(testTitle);
assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)) assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
.isEqualTo(testDisplayTitle); .isEqualTo(testDisplayTitle);
assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)) assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
@ -1154,12 +1159,13 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
onMediaMetadataChanged_withGetMetadataAndGetCurrentMediaItemCommand_updatesLegacyMetadata() onMediaMetadataChanged_withGetMetadataAndGetCurrentMediaItemCommand_updatesLegacyMetadata()
throws Exception { throws Exception {
int testItemIndex = 3; int testItemIndex = 3;
String testTitle = "title";
String testDisplayTitle = "displayTitle"; String testDisplayTitle = "displayTitle";
long testDurationMs = 30_000; long testDurationMs = 30_000;
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(/* size= */ 5); List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(/* size= */ 5);
String testCurrentMediaId = testMediaItems.get(testItemIndex).mediaId; String testCurrentMediaId = testMediaItems.get(testItemIndex).mediaId;
MediaMetadata testMediaMetadata = MediaMetadata testMediaMetadata =
new MediaMetadata.Builder().setTitle(testDisplayTitle).build(); new MediaMetadata.Builder().setTitle(testTitle).setDisplayTitle(testDisplayTitle).build();
testMediaItems.set( testMediaItems.set(
testItemIndex, testItemIndex,
new MediaItem.Builder() new MediaItem.Builder()
@ -1192,6 +1198,10 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
MediaMetadataCompat parameterMetadataCompat = metadataRef.get(); MediaMetadataCompat parameterMetadataCompat = metadataRef.get();
MediaMetadataCompat getterMetadataCompat = controllerCompat.getMetadata(); MediaMetadataCompat getterMetadataCompat = controllerCompat.getMetadata();
assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
.isEqualTo(testTitle);
assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
.isEqualTo(testTitle);
assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)) assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
.isEqualTo(testDisplayTitle); .isEqualTo(testDisplayTitle);
assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)) assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
@ -1207,10 +1217,11 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
public void onMediaMetadataChanged_withGetMetadataCommandOnly_updatesLegacyMetadata() public void onMediaMetadataChanged_withGetMetadataCommandOnly_updatesLegacyMetadata()
throws Exception { throws Exception {
int testItemIndex = 3; int testItemIndex = 3;
String testDisplayTitle = "displayTitle"; String testTitle = "title";
String testDisplayTitle = "title";
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(/* size= */ 5); List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(/* size= */ 5);
MediaMetadata testMediaMetadata = MediaMetadata testMediaMetadata =
new MediaMetadata.Builder().setTitle(testDisplayTitle).build(); new MediaMetadata.Builder().setTitle(testTitle).setDisplayTitle(testDisplayTitle).build();
testMediaItems.set( testMediaItems.set(
testItemIndex, testItemIndex,
new MediaItem.Builder() new MediaItem.Builder()
@ -1240,6 +1251,10 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); assertThat(latchForMetadata.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
MediaMetadataCompat parameterMetadataCompat = metadataRef.get(); MediaMetadataCompat parameterMetadataCompat = metadataRef.get();
MediaMetadataCompat getterMetadataCompat = controllerCompat.getMetadata(); MediaMetadataCompat getterMetadataCompat = controllerCompat.getMetadata();
assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
.isEqualTo(testTitle);
assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
.isEqualTo(testTitle);
assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)) assertThat(parameterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
.isEqualTo(testDisplayTitle); .isEqualTo(testDisplayTitle);
assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)) assertThat(getterMetadataCompat.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE))
@ -1345,9 +1360,9 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
MediaDescriptionCompat description = queueFromParam.get(0).getDescription(); MediaDescriptionCompat description = queueFromParam.get(0).getDescription();
assertThat(description.getMediaId()).isEqualTo(mediaItem.mediaId); assertThat(description.getMediaId()).isEqualTo(mediaItem.mediaId);
assertThat(TextUtils.equals(description.getTitle(), mediaItem.mediaMetadata.title)).isTrue(); assertThat(TextUtils.equals(description.getTitle(), mediaItem.mediaMetadata.title)).isTrue();
assertThat(TextUtils.equals(description.getSubtitle(), mediaItem.mediaMetadata.subtitle)) assertThat(TextUtils.equals(description.getSubtitle(), mediaItem.mediaMetadata.artist))
.isTrue(); .isTrue();
assertThat(TextUtils.equals(description.getDescription(), mediaItem.mediaMetadata.description)) assertThat(TextUtils.equals(description.getDescription(), mediaItem.mediaMetadata.albumTitle))
.isTrue(); .isTrue();
assertThat(description.getIconUri()).isEqualTo(mediaItem.mediaMetadata.artworkUri); assertThat(description.getIconUri()).isEqualTo(mediaItem.mediaMetadata.artworkUri);
assertThat(description.getMediaUri()).isEqualTo(mediaItem.requestMetadata.mediaUri); assertThat(description.getMediaUri()).isEqualTo(mediaItem.requestMetadata.mediaUri);

View File

@ -105,8 +105,8 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
int testMediaItemIndex = 1; int testMediaItemIndex = 1;
MediaMetadataCompat testMediaMetadataCompat = MediaMetadataCompat testMediaMetadataCompat =
new MediaMetadataCompat.Builder() new MediaMetadataCompat.Builder()
.putText(MediaMetadataCompat.METADATA_KEY_TITLE, "title")
.putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "artist") .putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "artist")
.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "title")
.putLong(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT, MEDIA_TYPE_PLAYLIST) .putLong(MediaConstants.EXTRAS_KEY_MEDIA_TYPE_COMPAT, MEDIA_TYPE_PLAYLIST)
.build(); .build();
@RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART; @RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART;
@ -250,7 +250,7 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
MediaMetadataCompat testMediaMetadataCompat = MediaMetadataCompat testMediaMetadataCompat =
new MediaMetadataCompat.Builder() new MediaMetadataCompat.Builder()
.putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "artist") .putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "artist")
.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "title") .putText(MediaMetadataCompat.METADATA_KEY_TITLE, "title")
.build(); .build();
@RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART; @RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART;
MediaMetadata testMediaMetadata = MediaMetadata testMediaMetadata =
@ -453,7 +453,7 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
MediaMetadataCompat testMediaMetadataCompat = MediaMetadataCompat testMediaMetadataCompat =
new MediaMetadataCompat.Builder() new MediaMetadataCompat.Builder()
.putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "artist") .putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "artist")
.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "title") .putText(MediaMetadataCompat.METADATA_KEY_TITLE, "title")
.build(); .build();
@RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART; @RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART;
MediaMetadata testMediaMetadata = MediaMetadata testMediaMetadata =

View File

@ -21,7 +21,6 @@ import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ARTIST;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION; import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI; import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE; import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION; import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_ID; import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_ID;
import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_URI; import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_URI;
@ -32,6 +31,7 @@ import static androidx.media3.common.Player.STATE_READY;
import static androidx.media3.session.MediaConstants.ARGUMENT_CAPTIONING_ENABLED; import static androidx.media3.session.MediaConstants.ARGUMENT_CAPTIONING_ENABLED;
import static androidx.media3.session.MediaConstants.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED; import static androidx.media3.session.MediaConstants.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED;
import static androidx.media3.session.SessionResult.RESULT_SUCCESS; import static androidx.media3.session.SessionResult.RESULT_SUCCESS;
import static androidx.media3.session.legacy.MediaMetadataCompat.METADATA_KEY_TITLE;
import static androidx.media3.test.session.common.CommonConstants.DEFAULT_TEST_NAME; import static androidx.media3.test.session.common.CommonConstants.DEFAULT_TEST_NAME;
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.METADATA_ALBUM_TITLE; import static androidx.media3.test.session.common.CommonConstants.METADATA_ALBUM_TITLE;
@ -654,7 +654,7 @@ public class MediaControllerWithMediaSessionCompatTest {
MediaMetadataCompat metadataCompat = MediaMetadataCompat metadataCompat =
new MediaMetadataCompat.Builder() new MediaMetadataCompat.Builder()
.putText(METADATA_KEY_MEDIA_ID, testMediaId) .putText(METADATA_KEY_MEDIA_ID, testMediaId)
.putText(METADATA_KEY_DISPLAY_TITLE, testTitle) .putText(METADATA_KEY_TITLE, testTitle)
.putText(METADATA_KEY_DISPLAY_SUBTITLE, testSubtitle) .putText(METADATA_KEY_DISPLAY_SUBTITLE, testSubtitle)
.putText(METADATA_KEY_DISPLAY_DESCRIPTION, testDescription) .putText(METADATA_KEY_DISPLAY_DESCRIPTION, testDescription)
.putString(METADATA_KEY_DISPLAY_ICON_URI, testIconUri) .putString(METADATA_KEY_DISPLAY_ICON_URI, testIconUri)

View File

@ -15,6 +15,8 @@
*/ */
package androidx.media3.session; package androidx.media3.session;
import static androidx.media3.test.session.common.CommonConstants.METADATA_ALBUM_TITLE;
import static androidx.media3.test.session.common.CommonConstants.METADATA_ARTIST;
import static androidx.media3.test.session.common.CommonConstants.METADATA_ARTWORK_URI; import static androidx.media3.test.session.common.CommonConstants.METADATA_ARTWORK_URI;
import static androidx.media3.test.session.common.CommonConstants.METADATA_DESCRIPTION; import static androidx.media3.test.session.common.CommonConstants.METADATA_DESCRIPTION;
import static androidx.media3.test.session.common.CommonConstants.METADATA_EXTRAS; import static androidx.media3.test.session.common.CommonConstants.METADATA_EXTRAS;
@ -161,6 +163,8 @@ public final class MediaTestUtils {
.setTitle(METADATA_TITLE) .setTitle(METADATA_TITLE)
.setSubtitle(METADATA_SUBTITLE) .setSubtitle(METADATA_SUBTITLE)
.setDescription(METADATA_DESCRIPTION) .setDescription(METADATA_DESCRIPTION)
.setArtist(METADATA_ARTIST)
.setAlbumTitle(METADATA_ALBUM_TITLE)
.setArtworkUri(METADATA_ARTWORK_URI) .setArtworkUri(METADATA_ARTWORK_URI)
.setExtras(METADATA_EXTRAS) .setExtras(METADATA_EXTRAS)
.build(); .build();
@ -173,6 +177,8 @@ public final class MediaTestUtils {
.setIsPlayable(true) .setIsPlayable(true)
.setTitle(METADATA_TITLE) .setTitle(METADATA_TITLE)
.setSubtitle(METADATA_SUBTITLE) .setSubtitle(METADATA_SUBTITLE)
.setArtist(METADATA_ARTIST)
.setAlbumTitle(METADATA_ALBUM_TITLE)
.setDescription(METADATA_DESCRIPTION) .setDescription(METADATA_DESCRIPTION)
.setArtworkUri(METADATA_ARTWORK_URI) .setArtworkUri(METADATA_ARTWORK_URI)
.setExtras(METADATA_EXTRAS); .setExtras(METADATA_EXTRAS);