mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
Add injection of BitmapLoader from MediaSession.
* Add `BitmapLoader` in `MediaSession.Builder` and `MediaLibrarySession.Builder`.
* Pass `BitmapLoader` into the constructor of `MediaSession`, `MediaSessionImpl`, `MediaLibrarySession` and `MediaLibrarySessionImpl`.
* Add an interface method `loadBitmapFromMetadata(MediaMetadata)` in `BitmapLoader`.
* Remove the reference of `BitmapLoader` in `DefaultMediaNotificationProvider`.
PiperOrigin-RevId: 483654596
(cherry picked from commit 3f69df72db)
This commit is contained in:
parent
373c23c11b
commit
88a413b2cb
8 changed files with 207 additions and 50 deletions
|
|
@ -21,6 +21,7 @@ import static org.junit.Assert.assertThrows;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.test.utils.TestUtil;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
|
@ -166,6 +167,64 @@ public class SimpleBitmapLoaderTest {
|
|||
/* messagePart= */ "unknown protocol");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadBitmapFromMetadata_decodeFromArtworkData() throws Exception {
|
||||
byte[] imageData =
|
||||
TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TEST_IMAGE_PATH);
|
||||
MockWebServer mockWebServer = new MockWebServer();
|
||||
Uri uri = Uri.parse(mockWebServer.url("test_path").toString());
|
||||
// Set both artworkData and artworkUri
|
||||
MediaMetadata metadata =
|
||||
new MediaMetadata.Builder()
|
||||
.setArtworkData(imageData, MediaMetadata.PICTURE_TYPE_FRONT_COVER)
|
||||
.setArtworkUri(uri)
|
||||
.build();
|
||||
SimpleBitmapLoader bitmapLoader =
|
||||
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
|
||||
|
||||
Bitmap bitmap = bitmapLoader.loadBitmapFromMetadata(metadata).get();
|
||||
|
||||
assertThat(
|
||||
bitmap.sameAs(
|
||||
BitmapFactory.decodeByteArray(imageData, /* offset= */ 0, imageData.length)))
|
||||
.isTrue();
|
||||
assertThat(mockWebServer.getRequestCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadBitmapFromMetadata_loadFromArtworkUri() throws Exception {
|
||||
byte[] imageData =
|
||||
TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TEST_IMAGE_PATH);
|
||||
MockWebServer mockWebServer = new MockWebServer();
|
||||
Buffer responseBody = new Buffer().write(imageData);
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(responseBody));
|
||||
Uri uri = Uri.parse(mockWebServer.url("test_path").toString());
|
||||
// Just set artworkUri
|
||||
MediaMetadata metadata = new MediaMetadata.Builder().setArtworkUri(uri).build();
|
||||
SimpleBitmapLoader bitmapLoader =
|
||||
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
|
||||
|
||||
Bitmap bitmap = bitmapLoader.loadBitmapFromMetadata(metadata).get();
|
||||
|
||||
assertThat(
|
||||
bitmap.sameAs(
|
||||
BitmapFactory.decodeByteArray(imageData, /* offset= */ 0, imageData.length)))
|
||||
.isTrue();
|
||||
assertThat(mockWebServer.getRequestCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadBitmapFromMetadata_returnNull() throws Exception {
|
||||
// Neither artworkData nor artworkUri is set
|
||||
MediaMetadata metadata = new MediaMetadata.Builder().build();
|
||||
SimpleBitmapLoader bitmapLoader =
|
||||
new SimpleBitmapLoader(MoreExecutors.newDirectExecutorService());
|
||||
|
||||
ListenableFuture<Bitmap> bitmapFuture = bitmapLoader.loadBitmapFromMetadata(metadata);
|
||||
|
||||
assertThat(bitmapFuture).isNull();
|
||||
}
|
||||
|
||||
private static void assertException(
|
||||
ThrowingRunnable runnable, Class<? extends Exception> clazz, String messagePart) {
|
||||
ExecutionException executionException = assertThrows(ExecutionException.class, runnable);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ package androidx.media3.session;
|
|||
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
|
|
@ -25,6 +27,29 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
public interface BitmapLoader {
|
||||
/** Decodes an image from compressed binary data. */
|
||||
ListenableFuture<Bitmap> decodeBitmap(byte[] data);
|
||||
|
||||
/** Loads an image from {@code uri}. */
|
||||
ListenableFuture<Bitmap> loadBitmap(Uri uri);
|
||||
|
||||
/**
|
||||
* Loads an image from {@link MediaMetadata}. Returns null if {@code metadata} doesn't contain
|
||||
* bitmap information.
|
||||
*
|
||||
* <p>By default, the method will try to decode an image from {@link MediaMetadata#artworkData} if
|
||||
* it is present. Otherwise, the method will try to load an image from {@link
|
||||
* MediaMetadata#artworkUri} if it is present. The method will return null if neither {@link
|
||||
* MediaMetadata#artworkData} nor {@link MediaMetadata#artworkUri} is present.
|
||||
*/
|
||||
@Nullable
|
||||
default ListenableFuture<Bitmap> loadBitmapFromMetadata(MediaMetadata metadata) {
|
||||
@Nullable ListenableFuture<Bitmap> future;
|
||||
if (metadata.artworkData != null) {
|
||||
future = decodeBitmap(metadata.artworkData);
|
||||
} else if (metadata.artworkUri != null) {
|
||||
future = loadBitmap(metadata.artworkUri);
|
||||
} else {
|
||||
future = null;
|
||||
}
|
||||
return future;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,6 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
private NotificationIdProvider notificationIdProvider;
|
||||
private String channelId;
|
||||
@StringRes private int channelNameResourceId;
|
||||
private BitmapLoader bitmapLoader;
|
||||
private boolean built;
|
||||
|
||||
/**
|
||||
|
|
@ -136,7 +135,6 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
notificationIdProvider = session -> DEFAULT_NOTIFICATION_ID;
|
||||
channelId = DEFAULT_CHANNEL_ID;
|
||||
channelNameResourceId = DEFAULT_CHANNEL_NAME_RESOURCE_ID;
|
||||
bitmapLoader = new SimpleBitmapLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -196,19 +194,6 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link BitmapLoader} used load artwork. By default, a {@link CacheBitmapLoader} with
|
||||
* a {@link SimpleBitmapLoader} inside will be used.
|
||||
*
|
||||
* @param bitmapLoader The bitmap loader.
|
||||
* @return This builder.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setBitmapLoader(BitmapLoader bitmapLoader) {
|
||||
this.bitmapLoader = new CacheBitmapLoader(bitmapLoader);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link DefaultMediaNotificationProvider}. The method can be called at most once.
|
||||
*/
|
||||
|
|
@ -259,7 +244,6 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
private final String channelId;
|
||||
@StringRes private final int channelNameResourceId;
|
||||
private final NotificationManager notificationManager;
|
||||
private final BitmapLoader bitmapLoader;
|
||||
// Cache the last bitmap load request to avoid reloading the bitmap again, particularly useful
|
||||
// when showing a notification for the same item (e.g. when switching from playing to paused).
|
||||
private final Handler mainHandler;
|
||||
|
|
@ -272,7 +256,6 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
this.notificationIdProvider = builder.notificationIdProvider;
|
||||
this.channelId = builder.channelId;
|
||||
this.channelNameResourceId = builder.channelNameResourceId;
|
||||
this.bitmapLoader = new CacheBitmapLoader(builder.bitmapLoader);
|
||||
notificationManager =
|
||||
checkStateNotNull(
|
||||
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
|
||||
|
|
@ -312,7 +295,9 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
builder
|
||||
.setContentTitle(getNotificationContentTitle(metadata))
|
||||
.setContentText(getNotificationContentText(metadata));
|
||||
@Nullable ListenableFuture<Bitmap> bitmapFuture = loadArtworkBitmap(metadata);
|
||||
@Nullable
|
||||
ListenableFuture<Bitmap> bitmapFuture =
|
||||
mediaSession.getBitmapLoader().loadBitmapFromMetadata(metadata);
|
||||
if (bitmapFuture != null) {
|
||||
if (pendingOnBitmapLoadedFutureCallback != null) {
|
||||
pendingOnBitmapLoadedFutureCallback.discardIfPending();
|
||||
|
|
@ -578,23 +563,6 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
|
|||
notificationManager, channelId, context.getString(channelNameResourceId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests from the bitmapLoader to load artwork or returns null if the metadata don't include
|
||||
* artwork.
|
||||
*/
|
||||
@Nullable
|
||||
private ListenableFuture<Bitmap> loadArtworkBitmap(MediaMetadata metadata) {
|
||||
@Nullable ListenableFuture<Bitmap> future;
|
||||
if (metadata.artworkData != null) {
|
||||
future = bitmapLoader.decodeBitmap(metadata.artworkData);
|
||||
} else if (metadata.artworkUri != null) {
|
||||
future = bitmapLoader.loadBitmap(metadata.artworkUri);
|
||||
} else {
|
||||
future = null;
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
private static long getPlaybackStartTimeEpochMs(Player player) {
|
||||
// Changing "showWhen" causes notification flicker if SDK_INT < 21.
|
||||
if (Util.SDK_INT >= 21
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import static java.lang.annotation.ElementType.TYPE_USE;
|
|||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import androidx.annotation.IntDef;
|
||||
|
|
@ -420,6 +421,28 @@ public abstract class MediaLibraryService extends MediaSessionService {
|
|||
return super.setExtras(extras);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a {@link BitmapLoader} for the {@link MediaLibrarySession} to decode bitmaps from
|
||||
* compressed binary data or load bitmaps from {@link Uri}. If not set, a {@link
|
||||
* CacheBitmapLoader} with a {@link SimpleBitmapLoader} inside will be used.
|
||||
*
|
||||
* <p>The provided instance will likely be called repeatedly with the same request, so it
|
||||
* would be best if any provided instance does some caching. Simple caching can be added to
|
||||
* any {@link BitmapLoader} implementation by wrapping it in {@link CacheBitmapLoader} before
|
||||
* passing it to this method.
|
||||
*
|
||||
* <p>If no instance is set, a {@link CacheBitmapLoader} with a {@link SimpleBitmapLoader}
|
||||
* inside will be used.
|
||||
*
|
||||
* @param bitmapLoader The bitmap loader {@link BitmapLoader}.
|
||||
* @return The builder to allow chaining.
|
||||
*/
|
||||
@UnstableApi
|
||||
@Override
|
||||
public Builder setBitmapLoader(BitmapLoader bitmapLoader) {
|
||||
return super.setBitmapLoader(bitmapLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link MediaLibrarySession}.
|
||||
*
|
||||
|
|
@ -429,7 +452,11 @@ public abstract class MediaLibraryService extends MediaSessionService {
|
|||
*/
|
||||
@Override
|
||||
public MediaLibrarySession build() {
|
||||
return new MediaLibrarySession(context, id, player, sessionActivity, callback, extras);
|
||||
if (bitmapLoader == null) {
|
||||
bitmapLoader = new CacheBitmapLoader(new SimpleBitmapLoader());
|
||||
}
|
||||
return new MediaLibrarySession(
|
||||
context, id, player, sessionActivity, callback, extras, checkNotNull(bitmapLoader));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -439,8 +466,9 @@ public abstract class MediaLibraryService extends MediaSessionService {
|
|||
Player player,
|
||||
@Nullable PendingIntent sessionActivity,
|
||||
MediaSession.Callback callback,
|
||||
Bundle tokenExtras) {
|
||||
super(context, id, player, sessionActivity, callback, tokenExtras);
|
||||
Bundle tokenExtras,
|
||||
BitmapLoader bitmapLoader) {
|
||||
super(context, id, player, sessionActivity, callback, tokenExtras, bitmapLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -450,9 +478,17 @@ public abstract class MediaLibraryService extends MediaSessionService {
|
|||
Player player,
|
||||
@Nullable PendingIntent sessionActivity,
|
||||
MediaSession.Callback callback,
|
||||
Bundle tokenExtras) {
|
||||
Bundle tokenExtras,
|
||||
BitmapLoader bitmapLoader) {
|
||||
return new MediaLibrarySessionImpl(
|
||||
this, context, id, player, sessionActivity, (Callback) callback, tokenExtras);
|
||||
this,
|
||||
context,
|
||||
id,
|
||||
player,
|
||||
sessionActivity,
|
||||
(Callback) callback,
|
||||
tokenExtras,
|
||||
bitmapLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ import java.util.concurrent.Future;
|
|||
Player player,
|
||||
@Nullable PendingIntent sessionActivity,
|
||||
MediaLibrarySession.Callback callback,
|
||||
Bundle tokenExtras) {
|
||||
super(instance, context, id, player, sessionActivity, callback, tokenExtras);
|
||||
Bundle tokenExtras,
|
||||
BitmapLoader bitmapLoader) {
|
||||
super(instance, context, id, player, sessionActivity, callback, tokenExtras, bitmapLoader);
|
||||
this.instance = instance;
|
||||
this.callback = callback;
|
||||
subscriptions = new ArrayMap<>();
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import com.google.common.util.concurrent.Futures;
|
|||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* A session that allows a media app to expose its transport controls and playback information in a
|
||||
|
|
@ -307,6 +308,28 @@ public class MediaSession {
|
|||
return super.setExtras(extras);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a {@link BitmapLoader} for the {@link MediaSession} to decode bitmaps from compressed
|
||||
* binary data or load bitmaps from {@link Uri}. If not set, a {@link CacheBitmapLoader} with a
|
||||
* {@link SimpleBitmapLoader} inside will be used.
|
||||
*
|
||||
* <p>The provided instance will likely be called repeatedly with the same request, so it would
|
||||
* be best if any provided instance does some caching. Simple caching can be added to any {@link
|
||||
* BitmapLoader} implementation by wrapping it in {@link CacheBitmapLoader} before passing it to
|
||||
* this method.
|
||||
*
|
||||
* <p>If no instance is set, a {@link CacheBitmapLoader} with a {@link SimpleBitmapLoader}
|
||||
* inside will be used.
|
||||
*
|
||||
* @param bitmapLoader The bitmap loader {@link BitmapLoader}.
|
||||
* @return The builder to allow chaining.
|
||||
*/
|
||||
@UnstableApi
|
||||
@Override
|
||||
public Builder setBitmapLoader(BitmapLoader bitmapLoader) {
|
||||
return super.setBitmapLoader(bitmapLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link MediaSession}.
|
||||
*
|
||||
|
|
@ -316,7 +339,11 @@ public class MediaSession {
|
|||
*/
|
||||
@Override
|
||||
public MediaSession build() {
|
||||
return new MediaSession(context, id, player, sessionActivity, callback, extras);
|
||||
if (bitmapLoader == null) {
|
||||
bitmapLoader = new CacheBitmapLoader(new SimpleBitmapLoader());
|
||||
}
|
||||
return new MediaSession(
|
||||
context, id, player, sessionActivity, callback, extras, checkNotNull(bitmapLoader));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -487,14 +514,15 @@ public class MediaSession {
|
|||
Player player,
|
||||
@Nullable PendingIntent sessionActivity,
|
||||
Callback callback,
|
||||
Bundle tokenExtras) {
|
||||
Bundle tokenExtras,
|
||||
BitmapLoader bitmapLoader) {
|
||||
synchronized (STATIC_LOCK) {
|
||||
if (SESSION_ID_TO_SESSION_MAP.containsKey(id)) {
|
||||
throw new IllegalStateException("Session ID must be unique. ID=" + id);
|
||||
}
|
||||
SESSION_ID_TO_SESSION_MAP.put(id, this);
|
||||
}
|
||||
impl = createImpl(context, id, player, sessionActivity, callback, tokenExtras);
|
||||
impl = createImpl(context, id, player, sessionActivity, callback, tokenExtras, bitmapLoader);
|
||||
}
|
||||
|
||||
/* package */ MediaSessionImpl createImpl(
|
||||
|
|
@ -503,8 +531,10 @@ public class MediaSession {
|
|||
Player player,
|
||||
@Nullable PendingIntent sessionActivity,
|
||||
Callback callback,
|
||||
Bundle tokenExtras) {
|
||||
return new MediaSessionImpl(this, context, id, player, sessionActivity, callback, tokenExtras);
|
||||
Bundle tokenExtras,
|
||||
BitmapLoader bitmapLoader) {
|
||||
return new MediaSessionImpl(
|
||||
this, context, id, player, sessionActivity, callback, tokenExtras, bitmapLoader);
|
||||
}
|
||||
|
||||
/* package */ MediaSessionImpl getImpl() {
|
||||
|
|
@ -741,6 +771,12 @@ public class MediaSession {
|
|||
impl.setSessionExtras(controller, sessionExtras);
|
||||
}
|
||||
|
||||
/** Returns the {@link BitmapLoader}. */
|
||||
@UnstableApi
|
||||
public BitmapLoader getBitmapLoader() {
|
||||
return impl.getBitmapLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a custom command to a specific controller.
|
||||
*
|
||||
|
|
@ -1218,6 +1254,7 @@ public class MediaSession {
|
|||
/* package */ C callback;
|
||||
/* package */ @Nullable PendingIntent sessionActivity;
|
||||
/* package */ Bundle extras;
|
||||
/* package */ @MonotonicNonNull BitmapLoader bitmapLoader;
|
||||
|
||||
public BuilderBase(Context context, Player player, C callback) {
|
||||
this.context = checkNotNull(context);
|
||||
|
|
@ -1252,6 +1289,12 @@ public class MediaSession {
|
|||
return (U) this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public U setBitmapLoader(BitmapLoader bitmapLoader) {
|
||||
this.bitmapLoader = bitmapLoader;
|
||||
return (U) this;
|
||||
}
|
||||
|
||||
public abstract T build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||
private final PendingIntent mediaButtonIntent;
|
||||
@Nullable private final BroadcastReceiver broadcastReceiver;
|
||||
private final Handler applicationHandler;
|
||||
private final BitmapLoader bitmapLoader;
|
||||
|
||||
@Nullable private PlayerListener playerListener;
|
||||
|
||||
|
|
@ -139,7 +140,8 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||
Player player,
|
||||
@Nullable PendingIntent sessionActivity,
|
||||
MediaSession.Callback callback,
|
||||
Bundle tokenExtras) {
|
||||
Bundle tokenExtras,
|
||||
BitmapLoader bitmapLoader) {
|
||||
this.context = context;
|
||||
this.instance = instance;
|
||||
|
||||
|
|
@ -152,6 +154,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||
|
||||
applicationHandler = new Handler(player.getApplicationLooper());
|
||||
this.callback = callback;
|
||||
this.bitmapLoader = bitmapLoader;
|
||||
|
||||
playerInfo = PlayerInfo.DEFAULT;
|
||||
onPlayerInfoChangedHandler = new PlayerInfoChangedHandler(player.getApplicationLooper());
|
||||
|
|
@ -357,6 +360,10 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||
}
|
||||
}
|
||||
|
||||
public BitmapLoader getBitmapLoader() {
|
||||
return bitmapLoader;
|
||||
}
|
||||
|
||||
public void setAvailableCommands(
|
||||
ControllerInfo controller, SessionCommands sessionCommands, Player.Commands playerCommands) {
|
||||
if (sessionStub.getConnectedControllersManager().isConnected(controller)) {
|
||||
|
|
|
|||
|
|
@ -418,10 +418,10 @@ public class DefaultMediaNotificationProviderTest {
|
|||
new DefaultActionFactory(Robolectric.setupService(TestService.class));
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
SettableFuture<Bitmap> bitmapFuture = SettableFuture.create();
|
||||
when(mockBitmapLoader.loadBitmap(any())).thenReturn(bitmapFuture);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(bitmapFuture);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
DefaultMediaNotificationProvider defaultMediaNotificationProvider =
|
||||
new DefaultMediaNotificationProvider.Builder(ApplicationProvider.getApplicationContext())
|
||||
.setBitmapLoader(mockBitmapLoader)
|
||||
.build();
|
||||
|
||||
// Ask the notification provider to create a notification twice. Use separate callback instances
|
||||
|
|
@ -456,6 +456,9 @@ public class DefaultMediaNotificationProviderTest {
|
|||
DefaultMediaNotificationProvider defaultMediaNotificationProvider =
|
||||
new DefaultMediaNotificationProvider.Builder(context).build();
|
||||
MediaSession mockMediaSession = createMockMediaSessionForNotification(MediaMetadata.EMPTY);
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
DefaultActionFactory defaultActionFactory =
|
||||
new DefaultActionFactory(Robolectric.setupService(TestService.class));
|
||||
|
||||
|
|
@ -487,6 +490,9 @@ public class DefaultMediaNotificationProviderTest {
|
|||
.setChannelName(/* channelNameResourceId= */ R.string.media3_controls_play_description)
|
||||
.build();
|
||||
MediaSession mockMediaSession = createMockMediaSessionForNotification(MediaMetadata.EMPTY);
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
DefaultActionFactory defaultActionFactory =
|
||||
new DefaultActionFactory(Robolectric.setupService(TestService.class));
|
||||
|
||||
|
|
@ -521,6 +527,9 @@ public class DefaultMediaNotificationProviderTest {
|
|||
.setChannelName(/* channelNameResourceId= */ R.string.media3_controls_play_description)
|
||||
.build();
|
||||
MediaSession mockMediaSession = createMockMediaSessionForNotification(MediaMetadata.EMPTY);
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
DefaultActionFactory defaultActionFactory =
|
||||
new DefaultActionFactory(Robolectric.setupService(TestService.class));
|
||||
|
||||
|
|
@ -542,6 +551,9 @@ public class DefaultMediaNotificationProviderTest {
|
|||
DefaultActionFactory defaultActionFactory =
|
||||
new DefaultActionFactory(Robolectric.setupService(TestService.class));
|
||||
MediaSession mockMediaSession = createMockMediaSessionForNotification(MediaMetadata.EMPTY);
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
|
||||
MediaNotification notification =
|
||||
defaultMediaNotificationProvider.createNotification(
|
||||
|
|
@ -574,6 +586,9 @@ public class DefaultMediaNotificationProviderTest {
|
|||
MediaSession mockMediaSession =
|
||||
createMockMediaSessionForNotification(
|
||||
new MediaMetadata.Builder().setTitle("title").build());
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
|
||||
MediaNotification notification =
|
||||
defaultMediaNotificationProvider.createNotification(
|
||||
|
|
@ -597,6 +612,9 @@ public class DefaultMediaNotificationProviderTest {
|
|||
MediaSession mockMediaSession =
|
||||
createMockMediaSessionForNotification(
|
||||
new MediaMetadata.Builder().setArtist("artist").build());
|
||||
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
|
||||
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
|
||||
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
|
||||
|
||||
MediaNotification notification =
|
||||
defaultMediaNotificationProvider.createNotification(
|
||||
|
|
|
|||
Loading…
Reference in a new issue