Commit 4ce171a3 by tianyifeng Committed by microkatz

Load bitmaps for `MediaBrowserCompat`.

* Transforms the `ListenableFuture<LibraryResult<MediaItem>>` and `ListenableFuture<LibraryResult<List<MediaItem>>>` to `ListenableFuture<MediaBrowserCompat.MediaItem>` and `ListenableFuture<List<MediaBrowserCompat.MediaItem>>`, and the result will be sent out when `ListenableFuture` the `MediaBrowserCompat.MediaItem` (or the list of it) is fulfilled.
* Add `artworkData` to the tests in `MediaBrowserCompatWithMediaLibraryServiceTest`.

PiperOrigin-RevId: 489205547
parent 6e73fc54
......@@ -136,9 +136,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
errorMessage, /* cause= */ null, PlaybackException.ERROR_CODE_REMOTE_ERROR);
}
/** Converts a {@link MediaItem} to a {@link MediaBrowserCompat.MediaItem}. */
public static MediaBrowserCompat.MediaItem convertToBrowserItem(MediaItem item) {
MediaDescriptionCompat description = convertToMediaDescriptionCompat(item);
public static MediaBrowserCompat.MediaItem convertToBrowserItem(
MediaItem item, @Nullable Bitmap artworkBitmap) {
MediaDescriptionCompat description = convertToMediaDescriptionCompat(item, artworkBitmap);
MediaMetadata metadata = item.mediaMetadata;
int flags = 0;
if (metadata.folderType != null && metadata.folderType != MediaMetadata.FOLDER_TYPE_NONE) {
......@@ -150,15 +150,6 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return new MediaBrowserCompat.MediaItem(description, flags);
}
/** Converts a list of {@link MediaItem} to a list of {@link MediaBrowserCompat.MediaItem}. */
public static List<MediaBrowserCompat.MediaItem> convertToBrowserItemList(List<MediaItem> items) {
List<MediaBrowserCompat.MediaItem> result = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
result.add(convertToBrowserItem(items.get(i)));
}
return result;
}
/** Converts a {@link MediaBrowserCompat.MediaItem} to a {@link MediaItem}. */
public static MediaItem convertToMediaItem(MediaBrowserCompat.MediaItem item) {
return convertToMediaItem(item.getDescription(), item.isBrowsable(), item.isPlayable());
......@@ -320,16 +311,32 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return result;
}
/** Converts a {@link MediaItem} to a {@link MediaDescriptionCompat}. */
/**
* Converts a {@link MediaItem} to a {@link MediaDescriptionCompat}.
*
* @deprecated Use {@link #convertToMediaDescriptionCompat(MediaItem, Bitmap)} instead.
*/
@Deprecated
public static MediaDescriptionCompat convertToMediaDescriptionCompat(MediaItem item) {
MediaMetadata metadata = item.mediaMetadata;
@Nullable Bitmap artworkBitmap = null;
if (metadata.artworkData != null) {
artworkBitmap =
BitmapFactory.decodeByteArray(metadata.artworkData, 0, metadata.artworkData.length);
}
return convertToMediaDescriptionCompat(item, artworkBitmap);
}
/** Converts a {@link MediaItem} to a {@link MediaDescriptionCompat} */
public static MediaDescriptionCompat convertToMediaDescriptionCompat(
MediaItem item, @Nullable Bitmap artworkBitmap) {
MediaDescriptionCompat.Builder builder =
new MediaDescriptionCompat.Builder()
.setMediaId(item.mediaId.equals(MediaItem.DEFAULT_MEDIA_ID) ? null : item.mediaId);
MediaMetadata metadata = item.mediaMetadata;
if (metadata.artworkData != null) {
Bitmap artwork =
BitmapFactory.decodeByteArray(metadata.artworkData, 0, metadata.artworkData.length);
builder.setIconBitmap(artwork);
if (artworkBitmap != null) {
builder.setIconBitmap(artworkBitmap);
}
@Nullable Bundle extras = metadata.extras;
if (metadata.folderType != null && metadata.folderType != MediaMetadata.FOLDER_TYPE_NONE) {
......
......@@ -129,6 +129,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(itemRef.get().getMediaId()).isEqualTo(mediaId);
assertThat(itemRef.get().isBrowsable()).isTrue();
assertThat(itemRef.get().getDescription().getIconBitmap()).isNotNull();
}
@Test
......@@ -151,6 +152,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(itemRef.get().getMediaId()).isEqualTo(mediaId);
assertThat(itemRef.get().isPlayable()).isTrue();
assertThat(itemRef.get().getDescription().getIconBitmap()).isNotNull();
}
@Test
......@@ -181,6 +183,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
BundleSubject.assertThat(description.getExtras())
.string(METADATA_EXTRA_KEY)
.isEqualTo(METADATA_EXTRA_VALUE);
assertThat(description.getIconBitmap()).isNotNull();
}
@Test
......@@ -245,6 +248,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
EXTRAS_KEY_COMPLETION_STATUS,
/* defaultValue= */ EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED + 1))
.isEqualTo(EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED);
assertThat(mediaItem.getDescription().getIconBitmap()).isNotNull();
}
}
......@@ -311,6 +315,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest
int relativeIndex = originalIndex - fromIndex;
assertThat(children.get(relativeIndex).getMediaId())
.isEqualTo(GET_CHILDREN_RESULT.get(originalIndex));
assertThat(children.get(relativeIndex).getDescription().getIconBitmap()).isNotNull();
}
latch.countDown();
}
......
......@@ -32,7 +32,6 @@ import android.support.v4.media.RatingCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.media.AudioAttributesCompat;
import androidx.media3.common.AudioAttributes;
......@@ -72,23 +71,6 @@ public final class MediaUtilsTest {
}
@Test
public void convertToBrowserItem() {
String mediaId = "testId";
CharSequence trackTitle = "testTitle";
MediaItem mediaItem =
new MediaItem.Builder()
.setMediaId(mediaId)
.setMediaMetadata(new MediaMetadata.Builder().setTitle(trackTitle).build())
.build();
MediaBrowserCompat.MediaItem browserItem = MediaUtils.convertToBrowserItem(mediaItem);
assertThat(browserItem.getDescription()).isNotNull();
assertThat(browserItem.getDescription().getMediaId()).isEqualTo(mediaId);
assertThat(TextUtils.equals(browserItem.getDescription().getTitle(), trackTitle)).isTrue();
}
@Test
public void convertToMediaItem_browserItemToMediaItem() {
String mediaId = "testId";
String title = "testTitle";
......@@ -116,18 +98,6 @@ public final class MediaUtilsTest {
}
@Test
public void convertToBrowserItemList() {
int size = 3;
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(size);
List<MediaBrowserCompat.MediaItem> browserItems =
MediaUtils.convertToBrowserItemList(mediaItems);
assertThat(browserItems).hasSize(size);
for (int i = 0; i < size; ++i) {
assertThat(browserItems.get(i).getMediaId()).isEqualTo(mediaItems.get(i).mediaId);
}
}
@Test
public void convertBrowserItemListToMediaItemList() {
int size = 3;
List<MediaBrowserCompat.MediaItem> browserItems = MediaTestUtils.createBrowserItems(size);
......
......@@ -51,6 +51,7 @@ import static androidx.media3.test.session.common.MediaBrowserConstants.SUBSCRIB
import static androidx.media3.test.session.common.MediaBrowserConstants.SUBSCRIBE_ID_NOTIFY_CHILDREN_CHANGED_TO_ONE;
import static androidx.media3.test.session.common.MediaBrowserConstants.SUBSCRIBE_ID_NOTIFY_CHILDREN_CHANGED_TO_ONE_WITH_NON_SUBSCRIBED_ID;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.Assert.fail;
import android.app.PendingIntent;
import android.app.Service;
......@@ -72,6 +73,7 @@ import androidx.media3.test.session.common.TestUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
......@@ -92,6 +94,8 @@ public class MockMediaLibraryService extends MediaLibraryService {
public static final String CONNECTION_HINTS_KEY_REMOVE_COMMAND_CODE_LIBRARY_SEARCH =
"CONNECTION_HINTS_KEY_REMOVE_SEARCH_SESSION_COMMAND";
private static final String TEST_IMAGE_PATH = "media/png/non-motion-photo-shortened.png";
public static final MediaItem ROOT_ITEM =
new MediaItem.Builder()
.setMediaId(ROOT_ID)
......@@ -115,6 +119,8 @@ public class MockMediaLibraryService extends MediaLibraryService {
@Nullable
private static LibraryParams expectedParams;
@Nullable private static byte[] testArtworkData;
MediaLibrarySession session;
TestHandler handler;
HandlerThread handlerThread;
......@@ -238,7 +244,8 @@ public class MockMediaLibraryService extends MediaLibraryService {
LibraryResult.ofItem(createBrowsableMediaItem(mediaId), /* params= */ null));
case MEDIA_ID_GET_PLAYABLE_ITEM:
return Futures.immediateFuture(
LibraryResult.ofItem(createPlayableMediaItem(mediaId), /* params= */ null));
LibraryResult.ofItem(
createPlayableMediaItemWithArtworkData(mediaId), /* params= */ null));
case MEDIA_ID_GET_ITEM_WITH_METADATA:
return Futures.immediateFuture(
LibraryResult.ofItem(createMediaItemWithMetadata(mediaId), /* params= */ null));
......@@ -445,20 +452,32 @@ public class MockMediaLibraryService extends MediaLibraryService {
// Create a list of MediaItem from the list of media IDs.
List<MediaItem> result = new ArrayList<>();
for (int i = 0; i < paginatedMediaIdList.size(); i++) {
result.add(createPlayableMediaItem(paginatedMediaIdList.get(i)));
result.add(createPlayableMediaItemWithArtworkData(paginatedMediaIdList.get(i)));
}
return result;
}
private static MediaItem createBrowsableMediaItem(String mediaId) {
private MediaItem createBrowsableMediaItem(String mediaId) {
MediaMetadata mediaMetadata =
new MediaMetadata.Builder()
.setFolderType(MediaMetadata.FOLDER_TYPE_MIXED)
.setIsPlayable(false)
.setArtworkData(getArtworkData(), MediaMetadata.PICTURE_TYPE_FRONT_COVER)
.build();
return new MediaItem.Builder().setMediaId(mediaId).setMediaMetadata(mediaMetadata).build();
}
private MediaItem createPlayableMediaItemWithArtworkData(String mediaId) {
MediaItem mediaItem = createPlayableMediaItem(mediaId);
MediaMetadata mediaMetadataWithArtwork =
mediaItem
.mediaMetadata
.buildUpon()
.setArtworkData(getArtworkData(), MediaMetadata.PICTURE_TYPE_FRONT_COVER)
.build();
return mediaItem.buildUpon().setMediaMetadata(mediaMetadataWithArtwork).build();
}
private static MediaItem createPlayableMediaItem(String mediaId) {
Bundle extras = new Bundle();
extras.putInt(EXTRAS_KEY_COMPLETION_STATUS, EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED);
......@@ -471,15 +490,32 @@ public class MockMediaLibraryService extends MediaLibraryService {
return new MediaItem.Builder().setMediaId(mediaId).setMediaMetadata(mediaMetadata).build();
}
private static MediaItem createMediaItemWithMetadata(String mediaId) {
MediaMetadata mediaMetadata = MediaTestUtils.createMediaMetadata();
private MediaItem createMediaItemWithMetadata(String mediaId) {
MediaMetadata mediaMetadataWithArtwork =
MediaTestUtils.createMediaMetadata()
.buildUpon()
.setArtworkData(getArtworkData(), MediaMetadata.PICTURE_TYPE_FRONT_COVER)
.build();
return new MediaItem.Builder()
.setMediaId(mediaId)
.setRequestMetadata(
new MediaItem.RequestMetadata.Builder()
.setMediaUri(CommonConstants.METADATA_MEDIA_URI)
.build())
.setMediaMetadata(mediaMetadata)
.setMediaMetadata(mediaMetadataWithArtwork)
.build();
}
private byte[] getArtworkData() {
if (testArtworkData != null) {
return testArtworkData;
}
try {
testArtworkData =
TestUtils.getByteArrayForScaledBitmap(getApplicationContext(), TEST_IMAGE_PATH);
} catch (IOException e) {
fail(e.getMessage());
}
return testArtworkData;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment