mirror of
https://github.com/androidx/media.git
synced 2025-04-29 22:36:54 +08:00
Ensure media notification provider can be updated
Some interactions create a default notification provider if no custom one is set yet (e.g. setForegroundServiceTimeoutMs). This means a later call to setMediaNotificationProvider will silently fail to apply the new provider. This can be fixed by making the media notification provider updatable. Issue: androidx/media#2305 PiperOrigin-RevId: 746428193
This commit is contained in:
parent
45bcf3ff92
commit
9ca8540f85
@ -73,6 +73,11 @@
|
||||
player doesn't have `COMMAND_GET_TIMELINE` available while
|
||||
`COMMAND_GET_CURRENT_MEDIA_ITEM` is available and the wrapped player is
|
||||
empty ([#2320](https://github.com/androidx/media/issues/2320)).
|
||||
* Fix a bug where calling
|
||||
`MediaSessionService.setMediaNotificationProvider` is silently ignored
|
||||
after other interactions with the service like
|
||||
`setForegroundServiceTimeoutMs`
|
||||
([#2305](https://github.com/androidx/media/issues/2305)).
|
||||
* UI:
|
||||
* Enable `PlayerSurface` to work with `ExoPlayer.setVideoEffects` and
|
||||
`CompositionPlayer`.
|
||||
|
@ -60,7 +60,7 @@ import java.util.concurrent.TimeoutException;
|
||||
private static final int MSG_USER_ENGAGED_TIMEOUT = 1;
|
||||
|
||||
private final MediaSessionService mediaSessionService;
|
||||
private final MediaNotification.Provider mediaNotificationProvider;
|
||||
|
||||
private final MediaNotification.ActionFactory actionFactory;
|
||||
private final NotificationManagerCompat notificationManagerCompat;
|
||||
private final Handler mainHandler;
|
||||
@ -68,6 +68,7 @@ import java.util.concurrent.TimeoutException;
|
||||
private final Intent startSelfIntent;
|
||||
private final Map<MediaSession, ControllerInfo> controllerMap;
|
||||
|
||||
private MediaNotification.Provider mediaNotificationProvider;
|
||||
private int totalNotificationCount;
|
||||
@Nullable private MediaNotification mediaNotification;
|
||||
private boolean startedInForeground;
|
||||
@ -146,6 +147,15 @@ import java.util.concurrent.TimeoutException;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the media notification provider.
|
||||
*
|
||||
* @param mediaNotificationProvider The {@link MediaNotification.Provider}.
|
||||
*/
|
||||
public void setMediaNotificationProvider(MediaNotification.Provider mediaNotificationProvider) {
|
||||
this.mediaNotificationProvider = mediaNotificationProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the notification.
|
||||
*
|
||||
|
@ -180,9 +180,6 @@ public abstract class MediaSessionService extends Service {
|
||||
@GuardedBy("lock")
|
||||
private @MonotonicNonNull MediaNotificationManager mediaNotificationManager;
|
||||
|
||||
@GuardedBy("lock")
|
||||
private MediaNotification.@MonotonicNonNull Provider mediaNotificationProvider;
|
||||
|
||||
@GuardedBy("lock")
|
||||
private @MonotonicNonNull DefaultActionFactory actionFactory;
|
||||
|
||||
@ -637,8 +634,6 @@ public abstract class MediaSessionService extends Service {
|
||||
/**
|
||||
* Sets the {@link MediaNotification.Provider} to customize notifications.
|
||||
*
|
||||
* <p>This should be called before {@link #onCreate()} returns.
|
||||
*
|
||||
* <p>This method can be called from any thread.
|
||||
*/
|
||||
@UnstableApi
|
||||
@ -646,7 +641,8 @@ public abstract class MediaSessionService extends Service {
|
||||
MediaNotification.Provider mediaNotificationProvider) {
|
||||
checkNotNull(mediaNotificationProvider);
|
||||
synchronized (lock) {
|
||||
this.mediaNotificationProvider = mediaNotificationProvider;
|
||||
getMediaNotificationManager(/* initialMediaNotificationProvider= */ mediaNotificationProvider)
|
||||
.setMediaNotificationProvider(mediaNotificationProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@ -679,16 +675,23 @@ public abstract class MediaSessionService extends Service {
|
||||
}
|
||||
|
||||
private MediaNotificationManager getMediaNotificationManager() {
|
||||
return getMediaNotificationManager(/* initialMediaNotificationProvider= */ null);
|
||||
}
|
||||
|
||||
private MediaNotificationManager getMediaNotificationManager(
|
||||
@Nullable MediaNotification.Provider initialMediaNotificationProvider) {
|
||||
synchronized (lock) {
|
||||
if (mediaNotificationManager == null) {
|
||||
if (mediaNotificationProvider == null) {
|
||||
if (initialMediaNotificationProvider == null) {
|
||||
checkStateNotNull(getBaseContext(), "Accessing service context before onCreate()");
|
||||
mediaNotificationProvider =
|
||||
initialMediaNotificationProvider =
|
||||
new DefaultMediaNotificationProvider.Builder(getApplicationContext()).build();
|
||||
}
|
||||
mediaNotificationManager =
|
||||
new MediaNotificationManager(
|
||||
/* mediaSessionService= */ this, mediaNotificationProvider, getActionFactory());
|
||||
/* mediaSessionService= */ this,
|
||||
initialMediaNotificationProvider,
|
||||
getActionFactory());
|
||||
}
|
||||
return mediaNotificationManager;
|
||||
}
|
||||
|
@ -504,6 +504,36 @@ public class MediaSessionServiceTest {
|
||||
serviceController.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMediaNotificationProvider_afterSetForegroundServiceTimeoutMs_usesCustomProvider()
|
||||
throws TimeoutException {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
ExoPlayer player = new TestExoPlayerBuilder(context).build();
|
||||
MediaSession session = new MediaSession.Builder(context, player).build();
|
||||
ServiceController<TestService> serviceController = Robolectric.buildService(TestService.class);
|
||||
TestService service = serviceController.create().get();
|
||||
|
||||
service.setForegroundServiceTimeoutMs(100);
|
||||
service.setMediaNotificationProvider(
|
||||
new DefaultMediaNotificationProvider(
|
||||
service,
|
||||
/* notificationIdProvider= */ mediaSession -> 2000,
|
||||
DefaultMediaNotificationProvider.DEFAULT_CHANNEL_ID,
|
||||
DefaultMediaNotificationProvider.DEFAULT_CHANNEL_NAME_RESOURCE_ID));
|
||||
service.addSession(session);
|
||||
// Start a player to trigger notification creation.
|
||||
player.setMediaItem(MediaItem.fromUri("asset:///media/mp4/sample.mp4"));
|
||||
player.prepare();
|
||||
player.play();
|
||||
runMainLooperUntil(() -> notificationManager.getActiveNotifications().length == 1);
|
||||
|
||||
assertThat(getStatusBarNotification(/* notificationId= */ 2000)).isNotNull();
|
||||
|
||||
session.release();
|
||||
player.release();
|
||||
serviceController.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStartCommand_mediaButtonEvent_pausedByMediaNotificationController()
|
||||
throws InterruptedException {
|
||||
|
Loading…
x
Reference in New Issue
Block a user