Show notification even in STATE_IDLE

Currently the notification disappears immediately when the player
enters an error or stopped state, but still has its media and
could resume on user request.

This can be fixed by only checking the existence of media and not
the state when deciding to show a notification.

PiperOrigin-RevId: 726901050
This commit is contained in:
tonihei 2025-02-14 06:15:08 -08:00 committed by Copybara-Service
parent e9df85b48d
commit f0da364d3f
3 changed files with 53 additions and 3 deletions

View File

@ -35,6 +35,9 @@
* Muxers: * Muxers:
* IMA extension: * IMA extension:
* Session: * Session:
* Keep notification visible when playback enters an error or stopped
state. The notification is only removed if the playlist is cleared or
the player is released.
* UI: * UI:
* Downloads: * Downloads:
* OkHttp Extension: * OkHttp Extension:

View File

@ -251,9 +251,7 @@ import java.util.concurrent.TimeoutException;
private boolean shouldShowNotification(MediaSession session) { private boolean shouldShowNotification(MediaSession session) {
MediaController controller = getConnectedControllerForSession(session); MediaController controller = getConnectedControllerForSession(session);
return controller != null return controller != null && !controller.getCurrentTimeline().isEmpty();
&& !controller.getCurrentTimeline().isEmpty()
&& controller.getPlaybackState() != Player.STATE_IDLE;
} }
@Nullable @Nullable

View File

@ -67,6 +67,55 @@ public class MediaSessionServiceTest {
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
} }
@Test
public void service_sessionIdleNoMedia_createsNoNotification() {
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.setMediaNotificationProvider(
new DefaultMediaNotificationProvider(
service,
/* notificationIdProvider= */ unused -> 2000,
DefaultMediaNotificationProvider.DEFAULT_CHANNEL_ID,
DefaultMediaNotificationProvider.DEFAULT_CHANNEL_NAME_RESOURCE_ID));
service.addSession(session);
// Give the service a chance to create a notification.
ShadowLooper.idleMainLooper();
assertThat(getStatusBarNotification(2000)).isNull();
session.release();
player.release();
serviceController.destroy();
}
@Test
public void service_sessionIdleWithMedia_createsNotification() {
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.setMediaNotificationProvider(
new DefaultMediaNotificationProvider(
service,
/* notificationIdProvider= */ unused -> 2000,
DefaultMediaNotificationProvider.DEFAULT_CHANNEL_ID,
DefaultMediaNotificationProvider.DEFAULT_CHANNEL_NAME_RESOURCE_ID));
service.addSession(session);
// Add media and give the service a chance to create a notification.
player.setMediaItem(MediaItem.fromUri("asset:///media/mp4/sample.mp4"));
ShadowLooper.idleMainLooper();
assertThat(getStatusBarNotification(2000)).isNotNull();
session.release();
player.release();
serviceController.destroy();
}
@Test @Test
public void service_multipleSessionsOnMainThread_createsNotificationForEachSession() { public void service_multipleSessionsOnMainThread_createsNotificationForEachSession() {
ExoPlayer player1 = new TestExoPlayerBuilder(context).build(); ExoPlayer player1 = new TestExoPlayerBuilder(context).build();