diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaController.java b/libraries/session/src/main/java/androidx/media3/session/MediaController.java index 21aef646f1..361834849e 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaController.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaController.java @@ -175,6 +175,24 @@ public class MediaController implements Player { */ @UnstableApi public static final long RELEASE_UNBIND_TIMEOUT_MS = 30_000; + /** + * Key to mark the connection hints of the media notification controller. + * + *

For a controller to be {@linkplain + * MediaSession#isMediaNotificationController(MediaSession.ControllerInfo) recognized by the + * session as the media notification controller}, this key needs to be used to {@linkplain + * Bundle#putBoolean(String, boolean) set a boolean flag} in the connection hints to true. Only an + * internal controller that has the same package name as the session can be used as a media + * notification controller. + * + *

When using a session within a {@link MediaSessionService} or {@link MediaLibraryService}, + * the service connects a media notification controller automatically. Apps can do this for + * standalone session to configure the platform session in the same way. + */ + @UnstableApi + public static final String KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG = + "androidx.media3.session.MediaNotificationManager"; + private static final String TAG = "MediaController"; private static final String WRONG_THREAD_ERROR_MESSAGE = diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java b/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java index 4eaa932d9d..b8ad16d4de 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaNotificationManager.java @@ -55,8 +55,6 @@ import java.util.concurrent.TimeoutException; */ /* package */ final class MediaNotificationManager { - /* package */ static final String KEY_MEDIA_NOTIFICATION_MANAGER = - "androidx.media3.session.MediaNotificationManager"; private static final String TAG = "MediaNtfMng"; private final MediaSessionService mediaSessionService; @@ -92,7 +90,7 @@ import java.util.concurrent.TimeoutException; } MediaControllerListener listener = new MediaControllerListener(mediaSessionService, session); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); ListenableFuture controllerFuture = new MediaController.Builder(mediaSessionService, session.getToken()) .setConnectionHints(connectionHints) diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java b/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java index af7981cc7d..add90f57bd 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java @@ -387,7 +387,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; && controllerInfo .getConnectionHints() .getBoolean( - MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, /* defaultValue= */ false); + MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, /* defaultValue= */ false); } /** diff --git a/libraries/session/src/test/java/androidx/media3/session/MediaSessionUnitTest.java b/libraries/session/src/test/java/androidx/media3/session/MediaSessionUnitTest.java index 4aaa3686e2..fe8e4d3bc4 100644 --- a/libraries/session/src/test/java/androidx/media3/session/MediaSessionUnitTest.java +++ b/libraries/session/src/test/java/androidx/media3/session/MediaSessionUnitTest.java @@ -153,7 +153,7 @@ public class MediaSessionUnitTest { // Avoid naming collision with session_curre /* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID, /* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); MediaSession.ControllerInfo controllerInfo = new MediaSession.ControllerInfo( remoteUserInfo, @@ -174,7 +174,7 @@ public class MediaSessionUnitTest { // Avoid naming collision with session_curre /* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID, /* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); MediaSession.ControllerInfo controllerInfo = new MediaSession.ControllerInfo( remoteUserInfo, @@ -214,7 +214,7 @@ public class MediaSessionUnitTest { // Avoid naming collision with session_curre /* pid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_PID, /* uid= */ MediaSessionManager.RemoteUserInfo.UNKNOWN_UID); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); MediaSession.ControllerInfo controllerInfo = new MediaSession.ControllerInfo( remoteUserInfo, diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatPlaybackStateCompatActionsWithMediaSessionTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatPlaybackStateCompatActionsWithMediaSessionTest.java index 3a392943a2..f0868e6249 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatPlaybackStateCompatActionsWithMediaSessionTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatPlaybackStateCompatActionsWithMediaSessionTest.java @@ -1616,7 +1616,7 @@ public class MediaControllerCompatPlaybackStateCompatActionsWithMediaSessionTest throws InterruptedException { CountDownLatch connectionLatch = new CountDownLatch(1); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); ListenableFuture mediaNotificationControllerFuture = new MediaController.Builder( ApplicationProvider.getApplicationContext(), mediaSession.getToken()) diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackWithMediaControllerCompatTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackWithMediaControllerCompatTest.java index c0ebab372a..ef2d663dc0 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackWithMediaControllerCompatTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackWithMediaControllerCompatTest.java @@ -780,7 +780,7 @@ public class MediaSessionCallbackWithMediaControllerCompatTest { /* waitForConnection= */ true); KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder( ApplicationProvider.getApplicationContext(), session.get().getToken()) .setConnectionHints(connectionHints) @@ -889,7 +889,7 @@ public class MediaSessionCallbackWithMediaControllerCompatTest { .setId("dispatchMediaButtonEvent") .build())); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder( ApplicationProvider.getApplicationContext(), session.get().getToken()) .setConnectionHints(connectionHints) diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionKeyEventTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionKeyEventTest.java index e6bd1febe0..b3429b9c8e 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionKeyEventTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionKeyEventTest.java @@ -192,7 +192,7 @@ public class MediaSessionKeyEventTest { .get(0) .getConnectionHints() .getBoolean( - MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, + MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, /* defaultValue= */ false)) .isTrue(); threadTestRule.getHandler().postAndSync(controller::release); @@ -234,7 +234,7 @@ public class MediaSessionKeyEventTest { .get(0) .getConnectionHints() .getBoolean( - MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, + MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, /* defaultValue= */ false)) .isTrue(); threadTestRule.getHandler().postAndSync(controller::release); @@ -351,7 +351,7 @@ public class MediaSessionKeyEventTest { () -> { Bundle connectionHints = new Bundle(); connectionHints.putBoolean( - MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, /* value= */ true); + MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, /* value= */ true); return new MediaController.Builder( ApplicationProvider.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionServiceTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionServiceTest.java index 7d9f16c21e..4690f2b80b 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionServiceTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionServiceTest.java @@ -312,7 +312,7 @@ public class MediaSessionServiceTest { .get(0) .getConnectionHints() .getBoolean( - MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, + MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, /* defaultValue= */ false)) .isTrue(); assertThat(TestUtils.equals(controllerInfoList.get(1).getConnectionHints(), testHints)) diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java index 49156c7844..396a423687 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java @@ -529,7 +529,7 @@ public class MediaSessionTest { }) .build())); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder( ApplicationProvider.getApplicationContext(), session.get().getToken()) .setConnectionHints(connectionHints) @@ -740,7 +740,7 @@ public class MediaSessionTest { }) .build()); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder(ApplicationProvider.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) .buildAsync() @@ -779,7 +779,7 @@ public class MediaSessionTest { public void onMediaButtonEvent_noKeyEvent_mediaNotificationControllerConnected_returnsFalse() throws Exception { Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder(ApplicationProvider.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) .buildAsync() @@ -809,7 +809,7 @@ public class MediaSessionTest { public void onMediaButtonEvent_invalidKeyEvent_mediaNotificationControllerConnected_returnsFalse() throws Exception { Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder(ApplicationProvider.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) .buildAsync() @@ -839,7 +839,7 @@ public class MediaSessionTest { public void onMediaButtonEvent_invalidAction_mediaNotificationControllerConnected_returnsFalse() throws Exception { Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder(ApplicationProvider.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) .buildAsync() @@ -869,7 +869,7 @@ public class MediaSessionTest { onMediaButtonEvent_invalidComponent_mediaNotificationControllerConnected_returnsFalse() throws Exception { Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder(ApplicationProvider.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) .buildAsync() diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionWithMediaControllerCompatTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionWithMediaControllerCompatTest.java index c880e5beb0..a970d1dfda 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionWithMediaControllerCompatTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionWithMediaControllerCompatTest.java @@ -124,7 +124,7 @@ public class MediaSessionWithMediaControllerCompatTest { sessionTestRule.ensureReleaseAfterTest( new MediaSession.Builder(context, player).setId(TAG).setCallback(callback).build()); Bundle connectionHints = new Bundle(); - connectionHints.putBoolean(MediaNotificationManager.KEY_MEDIA_NOTIFICATION_MANAGER, true); + connectionHints.putBoolean(MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); new MediaController.Builder(context.getApplicationContext(), session.getToken()) .setConnectionHints(connectionHints) .buildAsync() diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java index a7975d4188..e3655c5578 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaSessionProviderService.java @@ -328,7 +328,8 @@ public class MediaSessionProviderService extends Service { session.setSessionPositionUpdateDelayMs(0L); if (useFakeMediaNotificationManagerController) { Bundle connectionHints = new Bundle(); - connectionHints.putBoolean("androidx.media3.session.MediaNotificationManager", true); + connectionHints.putBoolean( + MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG, true); //noinspection unused ListenableFuture unusedFuture = new MediaController.Builder(getApplicationContext(), session.getToken())