Skip to content

Commit fd18cf0

Browse files
committed
Add notification for empty player setting
1 parent 8faee05 commit fd18cf0

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed

libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import androidx.media3.common.Player;
3838
import androidx.media3.common.util.Log;
3939
import androidx.media3.common.util.Util;
40+
import androidx.media3.session.MediaSessionService.ShowNotificationForEmptyPlayerMode;
4041
import androidx.media3.session.MediaSessionService.ShowNotificationForIdlePlayerMode;
4142
import com.google.common.collect.ImmutableList;
4243
import com.google.common.util.concurrent.FutureCallback;
@@ -79,6 +80,7 @@
7980
private boolean isUserEngagedTimeoutEnabled;
8081
private long userEngagedTimeoutMs;
8182
@ShowNotificationForIdlePlayerMode int showNotificationForIdlePlayerMode;
83+
@ShowNotificationForEmptyPlayerMode int showNotificationForEmptyPlayerMode;
8284

8385
public MediaNotificationManager(
8486
MediaSessionService mediaSessionService,
@@ -97,6 +99,8 @@ public MediaNotificationManager(
9799
userEngagedTimeoutMs = MediaSessionService.DEFAULT_FOREGROUND_SERVICE_TIMEOUT_MS;
98100
showNotificationForIdlePlayerMode =
99101
MediaSessionService.SHOW_NOTIFICATION_FOR_IDLE_PLAYER_AFTER_STOP_OR_ERROR;
102+
showNotificationForEmptyPlayerMode =
103+
MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER;
100104
}
101105

102106
public void addSession(MediaSession session) {
@@ -212,6 +216,16 @@ public void setShowNotificationForIdlePlayer(
212216
}
213217
}
214218

219+
public void setShowNotificationForEmptyPlayer(
220+
@ShowNotificationForEmptyPlayerMode int showNotificationForEmptyPlayerMode) {
221+
this.showNotificationForEmptyPlayerMode = showNotificationForEmptyPlayerMode;
222+
List<MediaSession> sessions = mediaSessionService.getSessions();
223+
for (int i = 0; i < sessions.size(); i++) {
224+
mediaSessionService.onUpdateNotificationInternal(
225+
sessions.get(i), /* startInForegroundWhenPaused= */ false);
226+
}
227+
}
228+
215229
@Override
216230
public boolean handleMessage(Message msg) {
217231
if (msg.what == MSG_USER_ENGAGED_TIMEOUT) {
@@ -322,10 +336,25 @@ private void removeNotification() {
322336

323337
private boolean shouldShowNotification(MediaSession session) {
324338
MediaController controller = getConnectedControllerForSession(session);
325-
if (controller == null || controller.getCurrentTimeline().isEmpty()) {
339+
if (controller == null) {
326340
return false;
327341
}
328342
ControllerInfo controllerInfo = checkNotNull(controllerMap.get(session));
343+
if (controller.getCurrentTimeline().isEmpty()) {
344+
switch (showNotificationForEmptyPlayerMode) {
345+
case MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_ALWAYS:
346+
break;
347+
case MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER:
348+
return false;
349+
case MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_AFTER_STOP_OR_ERROR:
350+
if (!controllerInfo.hasBeenPrepared) {
351+
return false;
352+
}
353+
break;
354+
default:
355+
throw new IllegalStateException();
356+
}
357+
}
329358
if (controller.getPlaybackState() != Player.STATE_IDLE) {
330359
// Playback first prepared or restarted, reset previous notification dismissed flag.
331360
controllerInfo.wasNotificationDismissed = false;

libraries/session/src/main/java/androidx/media3/session/MediaSessionService.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ default void onForegroundServiceStartNotAllowedException() {}
194194
public @interface ShowNotificationForIdlePlayerMode {}
195195

196196
/**
197-
* Always show a notification when the {@link Player} is in {@link Player#STATE_IDLE}, has media,
198-
* and the notification wasn't explicitly dismissed.
197+
* Always show a notification when the {@link Player} is in {@link Player#STATE_IDLE} and the
198+
* notification wasn't explicitly dismissed.
199199
*/
200200
@UnstableApi public static final int SHOW_NOTIFICATION_FOR_IDLE_PLAYER_ALWAYS = 1;
201201

@@ -204,10 +204,45 @@ default void onForegroundServiceStartNotAllowedException() {}
204204

205205
/**
206206
* Shows a notification when the {@link Player} is in {@link Player#STATE_IDLE} due to {@link
207-
* Player#stop} or an error, has media, and the notification wasn't explicitly dismissed.
207+
* Player#stop} or an error, and the notification wasn't explicitly dismissed.
208208
*/
209209
@UnstableApi public static final int SHOW_NOTIFICATION_FOR_IDLE_PLAYER_AFTER_STOP_OR_ERROR = 3;
210210

211+
/**
212+
* The behavior for showing notifications when the {@link Player} has no media.
213+
*
214+
* <p>One of {@link #SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_ALWAYS}, {@link
215+
* #SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER}, {@link
216+
* #SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_AFTER_STOP_OR_ERROR}.
217+
*
218+
* <p>The default value is {@link #SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER}.
219+
*/
220+
@UnstableApi
221+
@Documented
222+
@Retention(RetentionPolicy.SOURCE)
223+
@Target(TYPE_USE)
224+
@IntDef({
225+
SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_ALWAYS,
226+
SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER,
227+
SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_AFTER_STOP_OR_ERROR
228+
})
229+
public @interface ShowNotificationForEmptyPlayerMode {}
230+
231+
/**
232+
* Always show a notification when the {@link Player} is empty and the notification wasn't
233+
* explicitly dismissed.
234+
*/
235+
@UnstableApi public static final int SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_ALWAYS = 1;
236+
237+
/** Never show a notification when the {@link Player} is empty. */
238+
@UnstableApi public static final int SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER = 2;
239+
240+
/**
241+
* Shows a notification when the {@link Player} is empty, in {@link Player#STATE_IDLE} due to
242+
* {@link Player#stop} or an error, and the notification wasn't explicitly dismissed.
243+
*/
244+
@UnstableApi public static final int SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_AFTER_STOP_OR_ERROR = 3;
245+
211246
private static final String TAG = "MSessionService";
212247

213248
private final Object lock;
@@ -547,6 +582,18 @@ public final void setShowNotificationForIdlePlayer(
547582
.setShowNotificationForIdlePlayer(showNotificationForIdlePlayerMode);
548583
}
549584

585+
/**
586+
* Sets whether and when a notification for a {@link Player} that has no media should be shown.
587+
*
588+
* @param showNotificationForEmptyPlayerMode The {@link ShowNotificationForEmptyPlayerMode}.
589+
*/
590+
@UnstableApi
591+
public final void setShowNotificationForEmptyPlayer(
592+
@ShowNotificationForEmptyPlayerMode int showNotificationForEmptyPlayerMode) {
593+
getMediaNotificationManager()
594+
.setShowNotificationForEmptyPlayer(showNotificationForEmptyPlayerMode);
595+
}
596+
550597
/**
551598
* Returns whether there is a session with ongoing user-engaged playback that is run in a
552599
* foreground service.

0 commit comments

Comments
 (0)