Add command check for metadata in DefaultMediaNotificationProvider

PiperOrigin-RevId: 503172986
(cherry picked from commit 052c4b3c1a6b72efd7fcbf433c646fed9ea91748)
This commit is contained in:
tonihei 2023-01-19 16:32:14 +00:00 committed by christosts
parent 28e37808ed
commit 43677b95eb
2 changed files with 71 additions and 28 deletions

View File

@ -319,33 +319,35 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
mediaStyle.setShowActionsInCompactView(compactViewIndices); mediaStyle.setShowActionsInCompactView(compactViewIndices);
// Set metadata info in the notification. // Set metadata info in the notification.
MediaMetadata metadata = player.getMediaMetadata(); if (player.isCommandAvailable(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)) {
builder MediaMetadata metadata = player.getMediaMetadata();
.setContentTitle(getNotificationContentTitle(metadata)) builder
.setContentText(getNotificationContentText(metadata)); .setContentTitle(getNotificationContentTitle(metadata))
@Nullable .setContentText(getNotificationContentText(metadata));
ListenableFuture<Bitmap> bitmapFuture = @Nullable
mediaSession.getBitmapLoader().loadBitmapFromMetadata(metadata); ListenableFuture<Bitmap> bitmapFuture =
if (bitmapFuture != null) { mediaSession.getBitmapLoader().loadBitmapFromMetadata(metadata);
if (pendingOnBitmapLoadedFutureCallback != null) { if (bitmapFuture != null) {
pendingOnBitmapLoadedFutureCallback.discardIfPending(); if (pendingOnBitmapLoadedFutureCallback != null) {
} pendingOnBitmapLoadedFutureCallback.discardIfPending();
if (bitmapFuture.isDone()) { }
try { if (bitmapFuture.isDone()) {
builder.setLargeIcon(Futures.getDone(bitmapFuture)); try {
} catch (ExecutionException e) { builder.setLargeIcon(Futures.getDone(bitmapFuture));
Log.w(TAG, getBitmapLoadErrorMessage(e)); } catch (ExecutionException e) {
Log.w(TAG, getBitmapLoadErrorMessage(e));
}
} else {
pendingOnBitmapLoadedFutureCallback =
new OnBitmapLoadedFutureCallback(
notificationId, builder, onNotificationChangedCallback);
Futures.addCallback(
bitmapFuture,
pendingOnBitmapLoadedFutureCallback,
// This callback must be executed on the next looper iteration, after this method has
// returned a media notification.
mainHandler::post);
} }
} else {
pendingOnBitmapLoadedFutureCallback =
new OnBitmapLoadedFutureCallback(
notificationId, builder, onNotificationChangedCallback);
Futures.addCallback(
bitmapFuture,
pendingOnBitmapLoadedFutureCallback,
// This callback must be executed on the next looper iteration, after this method has
// returned a media notification.
mainHandler::post);
} }
} }

View File

@ -20,6 +20,7 @@ import static androidx.media3.session.DefaultMediaNotificationProvider.DEFAULT_C
import static androidx.media3.session.DefaultMediaNotificationProvider.DEFAULT_NOTIFICATION_ID; import static androidx.media3.session.DefaultMediaNotificationProvider.DEFAULT_NOTIFICATION_ID;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@ -628,6 +629,33 @@ public class DefaultMediaNotificationProviderTest {
assertThat(isMediaMetadataArtistEqualToNotificationContentText).isTrue(); assertThat(isMediaMetadataArtistEqualToNotificationContentText).isTrue();
} }
@Test
public void
setMediaMetadata_withoutAvailableCommandToGetMetadata_doesNotUseMetadataForNotification() {
Context context = ApplicationProvider.getApplicationContext();
DefaultMediaNotificationProvider defaultMediaNotificationProvider =
new DefaultMediaNotificationProvider.Builder(context).build();
DefaultActionFactory defaultActionFactory =
new DefaultActionFactory(Robolectric.setupService(TestService.class));
MediaSession mockMediaSession =
createMockMediaSessionForNotification(
new MediaMetadata.Builder().setArtist("artist").setTitle("title").build(),
/* getMetadataCommandAvailable= */ false);
BitmapLoader mockBitmapLoader = mock(BitmapLoader.class);
when(mockBitmapLoader.loadBitmapFromMetadata(any())).thenReturn(null);
when(mockMediaSession.getBitmapLoader()).thenReturn(mockBitmapLoader);
MediaNotification notification =
defaultMediaNotificationProvider.createNotification(
mockMediaSession,
ImmutableList.of(),
defaultActionFactory,
mock(MediaNotification.Provider.Callback.class));
assertThat(NotificationCompat.getContentText(notification.notification)).isNull();
assertThat(NotificationCompat.getContentTitle(notification.notification)).isNull();
}
/** /**
* {@link DefaultMediaNotificationProvider} is designed to be extendable. Public constructor * {@link DefaultMediaNotificationProvider} is designed to be extendable. Public constructor
* should not be removed. * should not be removed.
@ -720,9 +748,22 @@ public class DefaultMediaNotificationProviderTest {
} }
private static MediaSession createMockMediaSessionForNotification(MediaMetadata mediaMetadata) { private static MediaSession createMockMediaSessionForNotification(MediaMetadata mediaMetadata) {
return createMockMediaSessionForNotification(
mediaMetadata, /* getMetadataCommandAvailable= */ true);
}
private static MediaSession createMockMediaSessionForNotification(
MediaMetadata mediaMetadata, boolean getMetadataCommandAvailable) {
Player mockPlayer = mock(Player.class); Player mockPlayer = mock(Player.class);
when(mockPlayer.getAvailableCommands()).thenReturn(Commands.EMPTY); when(mockPlayer.isCommandAvailable(anyInt())).thenReturn(false);
when(mockPlayer.getMediaMetadata()).thenReturn(mediaMetadata); if (getMetadataCommandAvailable) {
when(mockPlayer.getAvailableCommands())
.thenReturn(new Commands.Builder().add(Player.COMMAND_GET_MEDIA_ITEMS_METADATA).build());
when(mockPlayer.isCommandAvailable(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)).thenReturn(true);
when(mockPlayer.getMediaMetadata()).thenReturn(mediaMetadata);
} else {
when(mockPlayer.getAvailableCommands()).thenReturn(Commands.EMPTY);
}
MediaSession mockMediaSession = mock(MediaSession.class); MediaSession mockMediaSession = mock(MediaSession.class);
when(mockMediaSession.getPlayer()).thenReturn(mockPlayer); when(mockMediaSession.getPlayer()).thenReturn(mockPlayer);
MediaSessionImpl mockMediaSessionImpl = mock(MediaSessionImpl.class); MediaSessionImpl mockMediaSessionImpl = mock(MediaSessionImpl.class);