Skip to content

Commit c8a016e

Browse files
committed
Add notification for empty player setting
1 parent 2fc5e58 commit c8a016e

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
@@ -39,6 +39,7 @@
3939
import androidx.media3.common.util.Log;
4040
import androidx.media3.common.util.Util;
4141
import androidx.media3.session.MediaNotification.Provider.NotificationChannelInfo;
42+
import androidx.media3.session.MediaSessionService.ShowNotificationForEmptyPlayerMode;
4243
import androidx.media3.session.MediaSessionService.ShowNotificationForIdlePlayerMode;
4344
import com.google.common.collect.ImmutableList;
4445
import com.google.common.util.concurrent.FutureCallback;
@@ -85,6 +86,7 @@
8586
private boolean isUserEngagedTimeoutEnabled;
8687
private long userEngagedTimeoutMs;
8788
@ShowNotificationForIdlePlayerMode int showNotificationForIdlePlayerMode;
89+
@ShowNotificationForEmptyPlayerMode int showNotificationForEmptyPlayerMode;
8890

8991
public MediaNotificationManager(
9092
MediaSessionService mediaSessionService,
@@ -108,6 +110,8 @@ public MediaNotificationManager(
108110
userEngagedTimeoutMs = MediaSessionService.DEFAULT_FOREGROUND_SERVICE_TIMEOUT_MS;
109111
showNotificationForIdlePlayerMode =
110112
MediaSessionService.SHOW_NOTIFICATION_FOR_IDLE_PLAYER_AFTER_STOP_OR_ERROR;
113+
showNotificationForEmptyPlayerMode =
114+
MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER;
111115
}
112116

113117
/**
@@ -236,6 +240,16 @@ public void setShowNotificationForIdlePlayer(
236240
}
237241
}
238242

243+
public void setShowNotificationForEmptyPlayer(
244+
@ShowNotificationForEmptyPlayerMode int showNotificationForEmptyPlayerMode) {
245+
this.showNotificationForEmptyPlayerMode = showNotificationForEmptyPlayerMode;
246+
List<MediaSession> sessions = mediaSessionService.getSessions();
247+
for (int i = 0; i < sessions.size(); i++) {
248+
mediaSessionService.onUpdateNotificationInternal(
249+
sessions.get(i), /* startInForegroundWhenPaused= */ false);
250+
}
251+
}
252+
239253
@Override
240254
public boolean handleMessage(Message msg) {
241255
if (msg.what == MSG_USER_ENGAGED_TIMEOUT) {
@@ -345,10 +359,25 @@ private void removeNotification() {
345359

346360
private boolean shouldShowNotification(MediaSession session) {
347361
MediaController controller = getConnectedControllerForSession(session);
348-
if (controller == null || controller.getCurrentTimeline().isEmpty()) {
362+
if (controller == null) {
349363
return false;
350364
}
351365
ControllerInfo controllerInfo = checkNotNull(controllerMap.get(session));
366+
if (controller.getCurrentTimeline().isEmpty()) {
367+
switch (showNotificationForEmptyPlayerMode) {
368+
case MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_ALWAYS:
369+
break;
370+
case MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_NEVER:
371+
return false;
372+
case MediaSessionService.SHOW_NOTIFICATION_FOR_EMPTY_PLAYER_AFTER_STOP_OR_ERROR:
373+
if (!controllerInfo.hasBeenPrepared) {
374+
return false;
375+
}
376+
break;
377+
default:
378+
throw new IllegalStateException();
379+
}
380+
}
352381
if (controller.getPlaybackState() != Player.STATE_IDLE) {
353382
// Playback first prepared or restarted, reset previous notification dismissed flag.
354383
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
@@ -199,8 +199,8 @@ default void onForegroundServiceStartNotAllowedException() {}
199199
public @interface ShowNotificationForIdlePlayerMode {}
200200

201201
/**
202-
* Always show a notification when the {@link Player} is in {@link Player#STATE_IDLE}, has media,
203-
* and the notification wasn't explicitly dismissed.
202+
* Always show a notification when the {@link Player} is in {@link Player#STATE_IDLE} and the
203+
* notification wasn't explicitly dismissed.
204204
*/
205205
@UnstableApi public static final int SHOW_NOTIFICATION_FOR_IDLE_PLAYER_ALWAYS = 1;
206206

@@ -209,10 +209,45 @@ default void onForegroundServiceStartNotAllowedException() {}
209209

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

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

218253
private final Object lock;
@@ -595,6 +630,18 @@ public final void setShowNotificationForIdlePlayer(
595630
.setShowNotificationForIdlePlayer(showNotificationForIdlePlayerMode);
596631
}
597632

633+
/**
634+
* Sets whether and when a notification for a {@link Player} that has no media should be shown.
635+
*
636+
* @param showNotificationForEmptyPlayerMode The {@link ShowNotificationForEmptyPlayerMode}.
637+
*/
638+
@UnstableApi
639+
public final void setShowNotificationForEmptyPlayer(
640+
@ShowNotificationForEmptyPlayerMode int showNotificationForEmptyPlayerMode) {
641+
getMediaNotificationManager()
642+
.setShowNotificationForEmptyPlayer(showNotificationForEmptyPlayerMode);
643+
}
644+
598645
/**
599646
* Returns whether there is a session with ongoing user-engaged playback that is run in a
600647
* foreground service.

0 commit comments

Comments
 (0)