Load bitmaps for MediaSessionCompat.QueueItem.

When receiving the `onTimelineChanged` callback, we convert the timeline to the list of `QueueItem`s, where decoding a bitmap is needed for building each of the `QueueItem`s. The strategy is similar to what we did in <unknown commit> for list of `MediaBrowserCompat.MediaItem` - set the queue item list until the bitmaps decoding for all the `MediaItem`s are completed.

PiperOrigin-RevId: 490283587
This commit is contained in:
tianyifeng 2022-11-22 18:55:24 +00:00 committed by Ian Baker
parent af1d7b9b1b
commit 8ce1213ddd
9 changed files with 197 additions and 57 deletions

View file

@ -89,11 +89,14 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import org.checkerframework.checker.initialization.qual.Initialized;
import org.checkerframework.checker.nullness.compatqual.NullableType;
// Getting the commands from MediaControllerCompat'
/* package */ class MediaSessionLegacyStub extends MediaSessionCompat.Callback {
@ -394,7 +397,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
controller -> {
PlayerWrapper playerWrapper = sessionImpl.getPlayerWrapper();
// Use queueId as an index as we've published {@link QueueItem} as so.
// see: {@link MediaUtils#convertToQueueItemList}.
// see: {@link MediaUtils#convertToQueueItem}.
playerWrapper.seekToDefaultPosition((int) queueId);
},
sessionCompat.getCurrentControllerInfo());
@ -1011,8 +1014,59 @@ import org.checkerframework.checker.initialization.qual.Initialized;
setQueue(sessionCompat, null);
return;
}
updateQueue(timeline);
// Duration might be unknown at onMediaItemTransition and become available afterward.
updateMetadataIfChanged();
}
private void updateQueue(Timeline timeline) {
List<MediaItem> mediaItemList = MediaUtils.convertToMediaItemList(timeline);
List<QueueItem> queueItemList = MediaUtils.convertToQueueItemList(mediaItemList);
List<@NullableType ListenableFuture<Bitmap>> bitmapFutures = new ArrayList<>();
final AtomicInteger resultCount = new AtomicInteger(0);
Runnable handleBitmapFuturesTask =
() -> {
int completedBitmapFutureCount = resultCount.incrementAndGet();
if (completedBitmapFutureCount == mediaItemList.size()) {
handleBitmapFuturesAllCompletedAndSetQueue(bitmapFutures, timeline, mediaItemList);
}
};
for (int i = 0; i < mediaItemList.size(); i++) {
MediaItem mediaItem = mediaItemList.get(i);
MediaMetadata metadata = mediaItem.mediaMetadata;
if (metadata.artworkData == null) {
bitmapFutures.add(null);
handleBitmapFuturesTask.run();
} else {
ListenableFuture<Bitmap> bitmapFuture =
sessionImpl.getBitmapLoader().decodeBitmap(metadata.artworkData);
bitmapFutures.add(bitmapFuture);
bitmapFuture.addListener(
handleBitmapFuturesTask, sessionImpl.getApplicationHandler()::post);
}
}
}
private void handleBitmapFuturesAllCompletedAndSetQueue(
List<@NullableType ListenableFuture<Bitmap>> bitmapFutures,
Timeline timeline,
List<MediaItem> mediaItems) {
List<QueueItem> queueItemList = new ArrayList<>();
for (int i = 0; i < bitmapFutures.size(); i++) {
@Nullable ListenableFuture<Bitmap> future = bitmapFutures.get(i);
@Nullable Bitmap bitmap = null;
if (future != null) {
try {
bitmap = Futures.getDone(future);
} catch (CancellationException | ExecutionException e) {
Log.d(TAG, "Failed to get bitmap");
}
}
queueItemList.add(MediaUtils.convertToQueueItem(mediaItems.get(i), i, bitmap));
}
if (Util.SDK_INT < 21) {
// In order to avoid TransactionTooLargeException for below API 21, we need to
// cut the list so that it doesn't exceed the binder transaction limit.
@ -1029,9 +1083,6 @@ import org.checkerframework.checker.initialization.qual.Initialized;
// which means we can safely send long lists.
sessionCompat.setQueue(queueItemList);
}
// Duration might be unknown at onMediaItemTransition and become available afterward.
updateMetadataIfChanged();
}
@Override

View file

@ -230,18 +230,14 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
}
/**
* Converts a list of {@link MediaItem} to a list of {@link QueueItem}. The index of the item
* Converts a {@link MediaItem} to a {@link QueueItem}. The index of the item in the playlist
* would be used as the queue ID to match the behavior of {@link MediaController}.
*/
public static List<QueueItem> convertToQueueItemList(List<MediaItem> items) {
List<QueueItem> result = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
MediaItem item = items.get(i);
MediaDescriptionCompat description = convertToMediaDescriptionCompat(item);
long id = convertToQueueItemId(i);
result.add(new QueueItem(description, id));
}
return result;
public static QueueItem convertToQueueItem(
MediaItem item, int mediaItemIndex, @Nullable Bitmap artworkBitmap) {
MediaDescriptionCompat description = convertToMediaDescriptionCompat(item, artworkBitmap);
long id = convertToQueueItemId(mediaItemIndex);
return new QueueItem(description, id);
}
/** Converts the index of a {@link MediaItem} in a playlist into id of {@link QueueItem}. */

View file

@ -1121,7 +1121,7 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
MediaItem mediaItem =
new MediaItem.Builder()
.setMediaId("mediaItem_withSampleMediaMetadata")
.setMediaMetadata(MediaTestUtils.createMediaMetadata())
.setMediaMetadata(MediaTestUtils.createMediaMetadataWithArtworkData())
.build();
Timeline timeline = new PlaylistTimeline(ImmutableList.of(mediaItem));
@ -1140,6 +1140,7 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
.isTrue();
assertThat(description.getIconUri()).isEqualTo(mediaItem.mediaMetadata.artworkUri);
assertThat(description.getMediaUri()).isEqualTo(mediaItem.requestMetadata.mediaUri);
assertThat(description.getIconBitmap()).isNotNull();
assertThat(TestUtils.equals(description.getExtras(), mediaItem.mediaMetadata.extras)).isTrue();
}

View file

@ -26,8 +26,11 @@ import static androidx.media3.test.session.common.TestUtils.TIMEOUT_MS;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.RatingCompat;
import android.support.v4.media.session.MediaSessionCompat;
@ -42,6 +45,7 @@ import androidx.media3.common.Player.Events;
import androidx.media3.common.Player.PositionInfo;
import androidx.media3.common.Timeline;
import androidx.media3.common.Timeline.Window;
import androidx.media3.common.util.Util;
import androidx.media3.test.session.common.HandlerThreadTestRule;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@ -73,11 +77,13 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
private Context context;
private RemoteMediaSessionCompat session;
private BitmapLoader bitmapLoader;
@Before
public void setUp() throws Exception {
context = ApplicationProvider.getApplicationContext();
session = new RemoteMediaSessionCompat(DEFAULT_TEST_NAME, context);
bitmapLoader = new CacheBitmapLoader(new SimpleBitmapLoader());
}
@After
@ -88,8 +94,8 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
@Test
public void getters_withValidQueueAndQueueIdAndMetadata() throws Exception {
int testSize = 3;
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(testSize);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testMediaItems);
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItemsWithArtworkData(testSize);
List<QueueItem> testQueue = convertToQueueItems(testMediaItems);
int testMediaItemIndex = 1;
MediaMetadataCompat testMediaMetadataCompat = createMediaMetadataCompat();
@RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART;
@ -173,8 +179,28 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(mediaItemRef.get()).isEqualTo(testCurrentMediaItem);
for (int i = 0; i < timelineRef.get().getWindowCount(); i++) {
assertThat(timelineRef.get().getWindow(i, new Window()).mediaItem)
.isEqualTo(i == testMediaItemIndex ? testCurrentMediaItem : testMediaItems.get(i));
MediaItem mediaItem = timelineRef.get().getWindow(i, new Window()).mediaItem;
MediaItem expectedMediaItem =
(i == testMediaItemIndex) ? testCurrentMediaItem : testMediaItems.get(i);
if (Util.SDK_INT < 21) {
// Bitmap conversion and back gives not exactly the same byte array below API 21
MediaMetadata mediaMetadata =
mediaItem
.mediaMetadata
.buildUpon()
.setArtworkData(/* artworkData= */ null, /* artworkDataType= */ null)
.build();
MediaMetadata expectedMediaMetadata =
expectedMediaItem
.mediaMetadata
.buildUpon()
.setArtworkData(/* artworkData= */ null, /* artworkDataType= */ null)
.build();
mediaItem = mediaItem.buildUpon().setMediaMetadata(mediaMetadata).build();
expectedMediaItem =
expectedMediaItem.buildUpon().setMediaMetadata(expectedMediaMetadata).build();
}
assertThat(mediaItem).isEqualTo(expectedMediaItem);
}
assertThat(timelineChangeReasonRef.get()).isEqualTo(TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED);
assertThat(mediaItemTransitionReasonRef.get())
@ -202,7 +228,7 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
public void getters_withValidQueueAndMetadataButWithInvalidQueueId() throws Exception {
int testSize = 3;
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(testSize);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testMediaItems);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testMediaItems);
MediaMetadataCompat testMediaMetadataCompat = createMediaMetadataCompat();
@RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART;
MediaMetadata testMediaMetadata =
@ -306,7 +332,7 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
public void getters_withValidQueueAndQueueIdWithoutMetadata() throws Exception {
int testSize = 3;
List<MediaItem> testMediaItems = MediaTestUtils.createMediaItems(testSize);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testMediaItems);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testMediaItems);
@RatingCompat.Style int testRatingType = RatingCompat.RATING_HEART;
Events testEvents =
new Events(
@ -511,4 +537,18 @@ public class MediaControllerMediaSessionCompatCallbackAggregationTest {
.isEqualTo(mediaItems.get(i));
}
}
private List<MediaSessionCompat.QueueItem> convertToQueueItems(List<MediaItem> mediaItems)
throws Exception {
List<MediaSessionCompat.QueueItem> list = new ArrayList<>();
for (int i = 0; i < mediaItems.size(); i++) {
MediaItem item = mediaItems.get(i);
@Nullable
Bitmap bitmap = bitmapLoader.decodeBitmap(item.mediaMetadata.artworkData).get(10, SECONDS);
MediaDescriptionCompat description = MediaUtils.convertToMediaDescriptionCompat(item, bitmap);
long id = MediaUtils.convertToQueueItemId(i);
list.add(new MediaSessionCompat.QueueItem(description, id));
}
return list;
}
}

View file

@ -418,7 +418,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
@Test
public void seekTo_withNewMediaItemIndex() throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(3);
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long initialPosition = 8_000;
long initialBufferedPosition = 9_200;
int initialIndex = 0;
@ -701,7 +701,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
@Test
public void addMediaItems() throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems("a", "b", "c");
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int testCurrentMediaItemIndex = 1;
MediaItem testCurrentMediaItem = mediaItems.get(testCurrentMediaItemIndex);
@ -767,7 +767,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
public void addMediaItems_beforeCurrentMediaItemIndex_shiftsCurrentMediaItemIndex()
throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems("a", "b", "c");
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int initialMediaItemIndex = 2;
MediaItem testCurrentMediaItem = mediaItems.get(initialMediaItemIndex);
@ -833,7 +833,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
@Test
public void removeMediaItems() throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(5);
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int testCurrentMediaItemIndex = 0;
MediaItem testCurrentMediaItem = mediaItems.get(testCurrentMediaItemIndex);
@ -898,7 +898,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
public void removeMediaItems_beforeCurrentMediaItemIndex_shiftsCurrentMediaItemIndex()
throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(5);
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int initialMediaItemIndex = 4;
MediaItem testCurrentMediaItem = mediaItems.get(initialMediaItemIndex);
@ -963,7 +963,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
@Test
public void removeMediaItems_includeCurrentMediaItem_movesCurrentItem() throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(5);
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int initialMediaItemIndex = 2;
MediaItem testCurrentMediaItem = mediaItems.get(initialMediaItemIndex);
@ -1025,7 +1025,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
@Test
public void moveMediaItems() throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(5);
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int testCurrentMediaItemIndex = 0;
MediaItem testCurrentMediaItem = mediaItems.get(testCurrentMediaItemIndex);
@ -1090,7 +1090,7 @@ public class MediaControllerStateMaskingWithMediaSessionCompatTest {
@Test
public void moveMediaItems_withMovingCurrentMediaItem_changesCurrentItem() throws Exception {
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(5);
List<QueueItem> queue = MediaUtils.convertToQueueItemList(mediaItems);
List<QueueItem> queue = MediaTestUtils.convertToQueueItemsWithoutBitmap(mediaItems);
long testPosition = 200L;
int initialCurrentMediaItemIndex = 1;
session.setPlaybackState(

View file

@ -106,6 +106,8 @@ public class MediaControllerWithMediaSessionCompatTest {
@ClassRule public static MainLooperTestRule mainLooperTestRule = new MainLooperTestRule();
private static final String TEST_IMAGE_PATH = "media/png/non-motion-photo-shortened.png";
private final HandlerThreadTestRule threadTestRule = new HandlerThreadTestRule(TAG);
private final MediaControllerTestRule controllerTestRule =
new MediaControllerTestRule(threadTestRule);
@ -373,12 +375,13 @@ public class MediaControllerWithMediaSessionCompatTest {
Timeline testTimeline = MediaTestUtils.createTimeline(/* windowCount= */ 2);
List<QueueItem> testQueue =
MediaUtils.convertToQueueItemList(MediaUtils.convertToMediaItemList(testTimeline));
MediaTestUtils.convertToQueueItemsWithoutBitmap(
MediaUtils.convertToMediaItemList(testTimeline));
session.setQueue(testQueue);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
MediaTestUtils.assertMediaIdEquals(testTimeline, timelineFromParamRef.get());
MediaTestUtils.assertMediaIdEquals(testTimeline, timelineFromParamRef.get());
MediaTestUtils.assertMediaIdEquals(testTimeline, timelineFromGetterRef.get());
assertThat(reasonRef.get()).isEqualTo(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED);
}
@ -386,7 +389,8 @@ public class MediaControllerWithMediaSessionCompatTest {
public void setQueue_withNull_notifiesEmptyTimeline() throws Exception {
Timeline timeline = MediaTestUtils.createTimeline(/* windowCount= */ 2);
List<QueueItem> queue =
MediaUtils.convertToQueueItemList(MediaUtils.convertToMediaItemList(timeline));
MediaTestUtils.convertToQueueItemsWithoutBitmap(
MediaUtils.convertToMediaItemList(timeline));
session.setQueue(queue);
CountDownLatch latch = new CountDownLatch(1);
@ -433,6 +437,9 @@ public class MediaControllerWithMediaSessionCompatTest {
Uri testIconUri = Uri.parse("androidx://media3-session/icon");
Uri testMediaUri = Uri.parse("androidx://media3-session/media");
Bundle testExtras = TestUtils.createTestBundle();
byte[] testArtworkData =
TestUtils.getByteArrayForScaledBitmap(context.getApplicationContext(), TEST_IMAGE_PATH);
@Nullable Bitmap testBitmap = bitmapLoader.decodeBitmap(testArtworkData).get(10, SECONDS);
MediaDescriptionCompat description =
new MediaDescriptionCompat.Builder()
.setMediaId(testMediaId)
@ -442,6 +449,7 @@ public class MediaControllerWithMediaSessionCompatTest {
.setIconUri(testIconUri)
.setMediaUri(testMediaUri)
.setExtras(testExtras)
.setIconBitmap(testBitmap)
.build();
QueueItem queueItem = new QueueItem(description, /* id= */ 0);
session.setQueue(ImmutableList.of(queueItem));
@ -455,6 +463,10 @@ public class MediaControllerWithMediaSessionCompatTest {
assertThat(TextUtils.equals(metadata.subtitle, testSubtitle)).isTrue();
assertThat(TextUtils.equals(metadata.description, testDescription)).isTrue();
assertThat(metadata.artworkUri).isEqualTo(testIconUri);
if (Util.SDK_INT >= 21) {
// Bitmap conversion and back gives not exactly the same byte array below API 21
assertThat(metadata.artworkData).isEqualTo(testArtworkData);
}
if (Util.SDK_INT < 21 || Util.SDK_INT >= 23) {
// TODO(b/199055952): Test mediaUri for all API levels once the bug is fixed.
assertThat(mediaItem.requestMetadata.mediaUri).isEqualTo(testMediaUri);
@ -579,7 +591,7 @@ public class MediaControllerWithMediaSessionCompatTest {
public void seekToDefaultPosition_withMediaItemIndex_updatesExpectedMediaItemIndex()
throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setPlaybackState(/* state= */ null);
int testMediaItemIndex = 2;
@ -613,7 +625,7 @@ public class MediaControllerWithMediaSessionCompatTest {
@Test
public void seekTo_withMediaItemIndex_updatesExpectedMediaItemIndex() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setPlaybackState(/* state= */ null);
long testPositionMs = 23L;
@ -652,7 +664,7 @@ public class MediaControllerWithMediaSessionCompatTest {
@Test
public void getMediaItemCount_withValidQueueAndQueueId_returnsQueueSize() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setPlaybackState(
new PlaybackStateCompat.Builder()
@ -686,7 +698,7 @@ public class MediaControllerWithMediaSessionCompatTest {
public void getMediaItemCount_withInvalidQueueIdWithoutMetadata_returnsAdjustedCount()
throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
MediaController controller = controllerTestRule.createController(session.getSessionToken());
@ -698,7 +710,7 @@ public class MediaControllerWithMediaSessionCompatTest {
public void getMediaItemCount_withInvalidQueueIdWithMetadata_returnsAdjustedCount()
throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
MediaItem testRemoveMediaItem = MediaTestUtils.createMediaItem("removed");
MediaMetadataCompat testMetadataCompat =
MediaUtils.convertToMediaMetadataCompat(
@ -716,7 +728,7 @@ public class MediaControllerWithMediaSessionCompatTest {
public void getMediaItemCount_whenQueueIdIsChangedFromInvalidToValid_returnOriginalCount()
throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
MediaItem testRemoveMediaItem = MediaTestUtils.createMediaItem("removed");
MediaMetadataCompat testMetadataCompat =
MediaUtils.convertToMediaMetadataCompat(
@ -751,7 +763,7 @@ public class MediaControllerWithMediaSessionCompatTest {
public void getCurrentMediaItemIndex_withInvalidQueueIdWithMetadata_returnsEndOfList()
throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
MediaItem testRemoveMediaItem = MediaTestUtils.createMediaItem("removed");
MediaMetadataCompat testMetadataCompat =
MediaUtils.convertToMediaMetadataCompat(
@ -888,7 +900,7 @@ public class MediaControllerWithMediaSessionCompatTest {
public void getMediaMetadata_withoutMediaMetadataCompatWithQueue_returnsEmptyMediaMetadata()
throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(3);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
int testIndex = 1;
long testActiveQueueId = testQueue.get(testIndex).getQueueId();
session.setQueue(testQueue);
@ -904,7 +916,7 @@ public class MediaControllerWithMediaSessionCompatTest {
@Test
public void setPlaybackState_withActiveQueueItemId_notifiesCurrentMediaItem() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(/* size= */ 2);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();

View file

@ -120,7 +120,7 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
@Test
public void play() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(/* size= */ 2);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setFlags(FLAG_HANDLES_QUEUE_COMMANDS);
setPlaybackState(PlaybackStateCompat.STATE_PAUSED);
@ -135,7 +135,7 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
@Test
public void pause() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(/* size= */ 2);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setFlags(FLAG_HANDLES_QUEUE_COMMANDS);
setPlaybackState(PlaybackStateCompat.STATE_PLAYING);
@ -150,7 +150,7 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
@Test
public void prepare() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(/* size= */ 2);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setFlags(FLAG_HANDLES_QUEUE_COMMANDS);
RemoteMediaController controller = createControllerAndWaitConnection();
@ -165,7 +165,7 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
@Test
public void stop() throws Exception {
List<MediaItem> testList = MediaTestUtils.createMediaItems(/* size= */ 2);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setFlags(FLAG_HANDLES_QUEUE_COMMANDS);
RemoteMediaController controller = createControllerAndWaitConnection();
@ -328,7 +328,7 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
public void addMediaItems() throws Exception {
int size = 2;
List<MediaItem> testList = MediaTestUtils.createMediaItems(size);
List<QueueItem> testQueue = MediaUtils.convertToQueueItemList(testList);
List<QueueItem> testQueue = MediaTestUtils.convertToQueueItemsWithoutBitmap(testList);
session.setQueue(testQueue);
session.setFlags(FLAG_HANDLES_QUEUE_COMMANDS);
@ -355,7 +355,7 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
int toIndex = 3;
int count = toIndex - fromIndex;
session.setQueue(MediaUtils.convertToQueueItemList(testList));
session.setQueue(MediaTestUtils.convertToQueueItemsWithoutBitmap(testList));
session.setFlags(FLAG_HANDLES_QUEUE_COMMANDS);
setPlaybackState(PlaybackStateCompat.STATE_BUFFERING);
RemoteMediaController controller = createControllerAndWaitConnection();

View file

@ -109,15 +109,21 @@ public final class MediaUtilsTest {
}
@Test
public void convertToQueueItemList() {
int size = 3;
List<MediaItem> mediaItems = MediaTestUtils.createMediaItems(size);
List<MediaSessionCompat.QueueItem> queueItems = MediaUtils.convertToQueueItemList(mediaItems);
assertThat(queueItems).hasSize(mediaItems.size());
for (int i = 0; i < size; ++i) {
assertThat(queueItems.get(i).getDescription().getMediaId())
.isEqualTo(mediaItems.get(i).mediaId);
}
public void convertToQueueItem_withArtworkData() throws Exception {
MediaItem mediaItem = MediaTestUtils.createMediaItemWithArtworkData("testId");
MediaMetadata mediaMetadata = mediaItem.mediaMetadata;
ListenableFuture<Bitmap> bitmapFuture = bitmapLoader.decodeBitmap(mediaMetadata.artworkData);
@Nullable Bitmap bitmap = bitmapFuture.get(10, SECONDS);
MediaSessionCompat.QueueItem queueItem =
MediaUtils.convertToQueueItem(
mediaItem,
/** mediaItemIndex= */
100,
bitmap);
assertThat(queueItem.getQueueId()).isEqualTo(100);
assertThat(queueItem.getDescription().getIconBitmap()).isNotNull();
}
@Test

View file

@ -115,6 +115,28 @@ public final class MediaTestUtils {
.build();
}
public static MediaMetadata createMediaMetadataWithArtworkData() {
MediaMetadata.Builder mediaMetadataBuilder =
new MediaMetadata.Builder()
.setFolderType(MediaMetadata.FOLDER_TYPE_NONE)
.setIsPlayable(false)
.setTitle(METADATA_TITLE)
.setSubtitle(METADATA_SUBTITLE)
.setDescription(METADATA_DESCRIPTION)
.setArtworkUri(METADATA_ARTWORK_URI)
.setExtras(METADATA_EXTRAS);
try {
byte[] artworkData =
TestUtils.getByteArrayForScaledBitmap(
ApplicationProvider.getApplicationContext(), TEST_IMAGE_PATH);
mediaMetadataBuilder.setArtworkData(artworkData, MediaMetadata.PICTURE_TYPE_FRONT_COVER);
} catch (IOException e) {
fail(e.getMessage());
}
return mediaMetadataBuilder.build();
}
public static List<ControllerInfo> getTestControllerInfos(MediaSession session) {
List<ControllerInfo> infos = new ArrayList<>();
if (session != null) {
@ -163,6 +185,18 @@ public final class MediaTestUtils {
return list;
}
public static List<MediaSessionCompat.QueueItem> convertToQueueItemsWithoutBitmap(
List<MediaItem> mediaItems) {
List<MediaSessionCompat.QueueItem> list = new ArrayList<>();
for (int i = 0; i < mediaItems.size(); i++) {
MediaItem item = mediaItems.get(i);
MediaDescriptionCompat description = MediaUtils.convertToMediaDescriptionCompat(item, null);
long id = MediaUtils.convertToQueueItemId(i);
list.add(new MediaSessionCompat.QueueItem(description, id));
}
return list;
}
public static Timeline createTimeline(int windowCount) {
return new PlaylistTimeline(createMediaItems(/* size= */ windowCount));
}