diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b742815498..67ddf2b1af 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -17,6 +17,12 @@ * Muxers: * IMA extension: * Session: + * Allow the session activity to be set per controller to override the + global session activity. The session activity can be defined for a + controller at connection time by creating a `ConnectionResult` with + `AcceptedResultBuilder.setSessionActivivty(PendingIntent)`. Once + connected, the session activity can be updated with + `MediaSession.setSessionActivity(ControllerInfo, PendingIntent)`. * UI: * Downloads: * OkHttp Extension: diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSession.java b/libraries/session/src/main/java/androidx/media3/session/MediaSession.java index a75902e2fa..5aa4ba1934 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSession.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSession.java @@ -759,6 +759,8 @@ public class MediaSession { * Builder#setSessionActivity(PendingIntent) building the session}. * * @param activityPendingIntent The pending intent to start the session activity. + * @throws IllegalArgumentException if the {@link PendingIntent} passed into this method is + * {@linkplain PendingIntent#getActivity(Context, int, Intent, int) not an activity}. */ @UnstableApi public final void setSessionActivity(PendingIntent activityPendingIntent) { @@ -768,6 +770,30 @@ public class MediaSession { impl.setSessionActivity(activityPendingIntent); } + /** + * Sends the session activity to the connected controller. + * + *

This call immediately returns and doesn't wait for a result from the controller. + * + *

Interoperability: This call has no effect when called for a {@linkplain + * ControllerInfo#LEGACY_CONTROLLER_VERSION legacy controller}. To set the session activity of the + * platform session use {@linkplain #getMediaNotificationControllerInfo() the media notification + * controller} as the target controller. + * + * @param controller The controller to send the session activity to. + * @param activityPendingIntent The pending intent to start the session activity. + * @throws IllegalArgumentException if the {@link PendingIntent} passed into this method is + * {@linkplain PendingIntent#getActivity(Context, int, Intent, int) not an activity}. + */ + @UnstableApi + public final void setSessionActivity( + ControllerInfo controller, PendingIntent activityPendingIntent) { + if (Util.SDK_INT >= 31) { + checkArgument(Api31.isActivity(activityPendingIntent)); + } + impl.setSessionActivity(controller, activityPendingIntent); + } + /** * Sets the underlying {@link Player} for this session to dispatch incoming events to. * @@ -1025,7 +1051,7 @@ public class MediaSession { /** * Broadcasts a custom command to all connected controllers. * - *

This is a synchronous call and doesn't wait for results from the controllers. + *

This call immediately returns and doesn't wait for a result from the controller. * *

A command is not accepted if it is not a custom command. * @@ -1061,7 +1087,7 @@ public class MediaSession { *

The initial extras can be set {@linkplain Builder#setSessionExtras(Bundle) when building the * session}. * - *

This is a synchronous call and doesn't wait for results from the controllers. + *

This call immediately returns and doesn't wait for a result from the controller. * * @param sessionExtras The session extras. */ @@ -1078,7 +1104,7 @@ public class MediaSession { * ConnectionResult.AcceptedResultBuilder#setSessionExtras(Bundle) building the connection * result}. * - *

This is a synchronous call and doesn't wait for results from the controller. + *

This call immediately returns and doesn't wait for a result from the controller. * *

Interoperability: This call has no effect when called for a {@linkplain * ControllerInfo#LEGACY_CONTROLLER_VERSION legacy controller}. @@ -1713,6 +1739,7 @@ public class MediaSession { private Player.Commands availablePlayerCommands = DEFAULT_PLAYER_COMMANDS; @Nullable private ImmutableList customLayout; @Nullable private Bundle sessionExtras; + @Nullable private PendingIntent sessionActivity; /** * Creates an instance. @@ -1788,6 +1815,18 @@ public class MediaSession { return this; } + /** + * Sets the session activity, overriding the {@linkplain MediaSession#getSessionActivity() + * session activity of the session}. + * + *

The default is null to indicate that the session activity of the session should be used. + */ + @CanIgnoreReturnValue + public AcceptedResultBuilder setSessionActivity(@Nullable PendingIntent sessionActivity) { + this.sessionActivity = sessionActivity; + return this; + } + /** Returns a new {@link ConnectionResult} instance for accepting a connection. */ public ConnectionResult build() { return new ConnectionResult( @@ -1795,7 +1834,8 @@ public class MediaSession { availableSessionCommands, availablePlayerCommands, customLayout, - sessionExtras); + sessionExtras, + sessionActivity); } } @@ -1826,18 +1866,23 @@ public class MediaSession { /** The session extras. */ @UnstableApi @Nullable public final Bundle sessionExtras; + /** The session activity. */ + @UnstableApi @Nullable public final PendingIntent sessionActivity; + /** Creates a new instance with the given available session and player commands. */ private ConnectionResult( boolean accepted, SessionCommands availableSessionCommands, Player.Commands availablePlayerCommands, @Nullable ImmutableList customLayout, - @Nullable Bundle sessionExtras) { + @Nullable Bundle sessionExtras, + @Nullable PendingIntent sessionActivity) { isAccepted = accepted; this.availableSessionCommands = availableSessionCommands; this.availablePlayerCommands = availablePlayerCommands; this.customLayout = customLayout; this.sessionExtras = sessionExtras; + this.sessionActivity = sessionActivity; } /** @@ -1857,7 +1902,8 @@ public class MediaSession { availableSessionCommands, availablePlayerCommands, /* customLayout= */ null, - /* sessionExtras= */ null); + /* sessionExtras= */ null, + /* sessionActivity= */ null); } /** Creates a {@link ConnectionResult} to reject a connection. */ @@ -1867,7 +1913,8 @@ public class MediaSession { SessionCommands.EMPTY, Player.Commands.EMPTY, /* customLayout= */ ImmutableList.of(), - /* sessionExtras= */ Bundle.EMPTY); + /* sessionExtras= */ Bundle.EMPTY, + /* sessionActivity= */ null); } } 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 678a0d4561..a6e4c12ecb 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java @@ -783,19 +783,23 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @UnstableApi protected void setSessionActivity(PendingIntent sessionActivity) { - if (Objects.equals(this.sessionActivity, sessionActivity)) { - return; - } this.sessionActivity = sessionActivity; - sessionLegacyStub.getSessionCompat().setSessionActivity(sessionActivity); ImmutableList connectedControllers = sessionStub.getConnectedControllersManager().getConnectedControllers(); for (int i = 0; i < connectedControllers.size(); i++) { - ControllerInfo controllerInfo = connectedControllers.get(i); - if (controllerInfo.getControllerVersion() >= 3) { - dispatchRemoteControllerTaskWithoutReturn( - controllerInfo, - (controller, seq) -> controller.onSessionActivityChanged(seq, sessionActivity)); + setSessionActivity(connectedControllers.get(i), sessionActivity); + } + } + + @UnstableApi + protected void setSessionActivity(ControllerInfo controller, PendingIntent sessionActivity) { + if (controller.getControllerVersion() >= 3 + && sessionStub.getConnectedControllersManager().isConnected(controller)) { + dispatchRemoteControllerTaskWithoutReturn( + controller, (callback, seq) -> callback.onSessionActivityChanged(seq, sessionActivity)); + if (isMediaNotificationController(controller)) { + dispatchRemoteControllerTaskToLegacyStub( + (callback, seq) -> callback.onSessionActivityChanged(seq, sessionActivity)); } } } diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java b/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java index 400dbd35da..e787973cd7 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java @@ -1117,6 +1117,11 @@ import org.checkerframework.checker.initialization.qual.Initialized; sessionCompat.setPlaybackState(sessionImpl.getPlayerWrapper().createPlaybackStateCompat()); } + @Override + public void onSessionActivityChanged(int seq, PendingIntent sessionActivity) { + sessionCompat.setSessionActivity(sessionActivity); + } + @Override public void onError(int seq, SessionError sessionError) { PlayerWrapper playerWrapper = sessionImpl.getPlayerWrapper(); diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java b/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java index b032a38924..9e32a005a1 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java @@ -526,7 +526,9 @@ import java.util.concurrent.ExecutionException; MediaLibraryInfo.VERSION_INT, MediaSessionStub.VERSION_INT, MediaSessionStub.this, - sessionImpl.getSessionActivity(), + connectionResult.sessionActivity != null + ? connectionResult.sessionActivity + : sessionImpl.getSessionActivity(), connectionResult.customLayout != null ? connectionResult.customLayout : sessionImpl.getCustomLayout(), diff --git a/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaController.aidl b/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaController.aidl index 2ff7a39d88..d74b940323 100644 --- a/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaController.aidl +++ b/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaController.aidl @@ -30,6 +30,9 @@ interface IRemoteMediaController { // MediaController Methods Bundle getConnectedSessionToken(String controllerId); Bundle getSessionExtras(String controllerId); + Bundle getCustomLayout(String controllerId); + Bundle getAvailableCommands(String controllerId); + PendingIntent getSessionActivity(String controllerId); void play(String controllerId); void pause(String controllerId); void setPlayWhenReady(String controllerId, boolean playWhenReady); @@ -101,8 +104,6 @@ interface IRemoteMediaController { int page, int pageSize, in Bundle libraryParams); - Bundle getCustomLayout(String controllerId); - Bundle getAvailableCommands(String controllerId); Bundle getItem(String controllerId, String mediaId); Bundle search(String controllerId, String query, in Bundle libraryParams); Bundle getSearchResult( diff --git a/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaSession.aidl b/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaSession.aidl index f749757953..e59ed772d2 100644 --- a/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaSession.aidl +++ b/libraries/test_session_common/src/main/aidl/androidx/media3/test/session/common/IRemoteMediaSession.aidl @@ -35,7 +35,7 @@ interface IRemoteMediaSession { void setSessionExtras(String sessionId, in Bundle extras); void setSessionExtrasForController(String sessionId, in String controllerKey, in Bundle extras); void sendError(String sessionId, String controllerKey, in Bundle SessionError); - void setSessionActivity(String sessionId, in PendingIntent sessionActivity); + void setSessionActivity(String sessionId, String controllerKey, in PendingIntent sessionActivity); // Player Methods void setPlayWhenReady(String sessionId, boolean playWhenReady, int reason); diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatCallbackWithMediaSessionTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatCallbackWithMediaSessionTest.java index 64b2bfaeeb..cd380e9ba2 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatCallbackWithMediaSessionTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerCompatCallbackWithMediaSessionTest.java @@ -1227,7 +1227,8 @@ public class MediaControllerCompatCallbackWithMediaSessionTest { } @Test - public void setSessionActivity_changedWhenReceivedWithSetter() throws Exception { + public void setSessionActivity_forAllControllers_changedWhenReceivedWithSetter() + throws Exception { Intent intent = new Intent(context, SurfaceActivity.class); PendingIntent sessionActivity = PendingIntent.getActivity( @@ -1243,7 +1244,34 @@ public class MediaControllerCompatCallbackWithMediaSessionTest { controllerCompat.registerCallback(callback, handler); assertThat(controllerCompat.getSessionActivity()).isNull(); - session.setSessionActivity(sessionActivity); + session.setSessionActivity(/* controllerKey= */ null, sessionActivity); + // The legacy API has no change listener for the session activity. Changing the state to + // trigger a callback. + session.getMockPlayer().notifyPlaybackStateChanged(STATE_READY); + + assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); + assertThat(controllerCompat.getSessionActivity()).isEqualTo(sessionActivity); + } + + @Test + public void setSessionActivity_setToNotificationController_changedWhenReceivedWithSetter() + throws Exception { + Intent intent = new Intent(context, SurfaceActivity.class); + PendingIntent sessionActivity = + PendingIntent.getActivity( + context, 0, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + CountDownLatch latch = new CountDownLatch(1); + MediaControllerCompat.Callback callback = + new MediaControllerCompat.Callback() { + @Override + public void onPlaybackStateChanged(PlaybackStateCompat state) { + latch.countDown(); + } + }; + controllerCompat.registerCallback(callback, handler); + assertThat(controllerCompat.getSessionActivity()).isNull(); + + session.setSessionActivity(NOTIFICATION_CONTROLLER_KEY, sessionActivity); // The legacy API has no change listener for the session activity. Changing the state to // trigger a callback. session.getMockPlayer().notifyPlaybackStateChanged(STATE_READY); diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerListenerTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerListenerTest.java index 8ccc47d7a8..758bb863d6 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerListenerTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerListenerTest.java @@ -2535,13 +2535,69 @@ public class MediaControllerListenerTest { remoteSession.getToken(), /* connectionHints= */ null, listener); assertThat(controller.getSessionActivity()).isNull(); - remoteSession.setSessionActivity(sessionActivity); + remoteSession.setSessionActivity(/* controllerKey= */ null, sessionActivity); assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); assertThat(controller.getSessionActivity()).isEqualTo(sessionActivity); assertThat(receivedSessionActivities).containsExactly(sessionActivity); } + @Test + public void setSessionActivity_forSpecificController_onSessionActivityChangedCalled() + throws Exception { + Intent intent = new Intent(context, SurfaceActivity.class); + PendingIntent sessionActivity = + PendingIntent.getActivity( + context, 0, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + CountDownLatch latch1 = new CountDownLatch(1); + List receivedSessionActivities1 = new ArrayList<>(); + MediaController.Listener listener1 = + new MediaController.Listener() { + @Override + public void onSessionActivityChanged( + MediaController controller, PendingIntent sessionActivity) { + receivedSessionActivities1.add(sessionActivity); + latch1.countDown(); + } + }; + Bundle connectionHints1 = new Bundle(); + connectionHints1.putString(KEY_CONTROLLER, "ctrl-1"); + MediaController controller1 = + controllerTestRule.createController(remoteSession.getToken(), connectionHints1, listener1); + List receivedSessionActivities2 = new ArrayList<>(); + CountDownLatch latch2 = new CountDownLatch(1); + MediaController.Listener listener2 = + new MediaController.Listener() { + @Override + public void onSessionActivityChanged( + MediaController controller, PendingIntent sessionActivity) { + receivedSessionActivities2.add(sessionActivity); + latch2.countDown(); + } + }; + Bundle connectionHints2 = new Bundle(); + connectionHints2.putString(KEY_CONTROLLER, "ctrl-2"); + MediaController controller2 = + controllerTestRule.createController(remoteSession.getToken(), connectionHints2, listener2); + assertThat(controller1.getSessionActivity()).isNull(); + assertThat(controller2.getSessionActivity()).isNull(); + + remoteSession.setSessionActivity(/* controllerKey= */ "ctrl-1", sessionActivity); + + assertThat(latch1.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); + assertThat(controller1.getSessionActivity()).isEqualTo(sessionActivity); + assertThat(controller2.getSessionActivity()).isNull(); + assertThat(receivedSessionActivities1).containsExactly(sessionActivity); + assertThat(receivedSessionActivities2).isEmpty(); + + remoteSession.setSessionActivity(/* controllerKey= */ "ctrl-2", sessionActivity); + + assertThat(latch2.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); + assertThat(controller2.getSessionActivity()).isEqualTo(sessionActivity); + assertThat(receivedSessionActivities1).containsExactly(sessionActivity); + assertThat(receivedSessionActivities2).containsExactly(sessionActivity); + } + @Test public void onVideoSizeChanged() throws Exception { VideoSize defaultVideoSize = MediaTestUtils.createDefaultVideoSize(); diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackTest.java index bb30dfccec..e8c361f83b 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionCallbackTest.java @@ -29,7 +29,9 @@ import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.junit.Assert.fail; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import androidx.annotation.Nullable; @@ -45,6 +47,7 @@ import androidx.media3.session.MediaSession.ConnectionResult.AcceptedResultBuild import androidx.media3.session.MediaSession.ControllerInfo; import androidx.media3.test.session.common.HandlerThreadTestRule; import androidx.media3.test.session.common.MainLooperTestRule; +import androidx.media3.test.session.common.SurfaceActivity; import androidx.media3.test.session.common.TestHandler; import androidx.media3.test.session.common.TestUtils; import androidx.media3.test.utils.TestExoPlayerBuilder; @@ -293,6 +296,49 @@ public class MediaSessionCallbackTest { assertThat(remoteController.getSessionExtras().getString("origin")).isEqualTo("controller"); } + @Test + public void onConnect_connectionResultSessionActivitySet_usesControllerSpecificSessionActivity() + throws Exception { + Intent intent = new Intent(context, SurfaceActivity.class); + PendingIntent controllerSpecificSessionActivity = + PendingIntent.getActivity( + context, 0, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); + MediaSession.Callback callback = + new MediaSession.Callback() { + @Override + public MediaSession.ConnectionResult onConnect( + MediaSession session, ControllerInfo controller) { + AcceptedResultBuilder connectionResult = + new AcceptedResultBuilder(session) + .setAvailablePlayerCommands(Player.Commands.EMPTY); + if (controller.getConnectionHints().getBoolean("want_session_activity", false)) { + connectionResult.setSessionActivity(controllerSpecificSessionActivity); + } + return connectionResult.build(); + } + }; + MediaSession session = + sessionTestRule.ensureReleaseAfterTest( + new MediaSession.Builder(context, player) + .setCallback(callback) + .setId( + "onConnect_connectionResultSessionActivitySet_usesControllerSpecificSessionActivity") + .build()); + Bundle connectionHints = new Bundle(); + connectionHints.putBoolean("want_session_activity", true); + + RemoteMediaController remoteControllerWithSpecificSessionActivity = + remoteControllerTestRule.createRemoteController( + session.getToken(), /* waitForConnection= */ true, connectionHints); + RemoteMediaController remoteControllerWithoutSpecificSessionActivity = + remoteControllerTestRule.createRemoteController( + session.getToken(), /* waitForConnection= */ true, /* connectionHints= */ Bundle.EMPTY); + + assertThat(remoteControllerWithSpecificSessionActivity.getSessionActivity()) + .isEqualTo(controllerSpecificSessionActivity); + assertThat(remoteControllerWithoutSpecificSessionActivity.getSessionActivity()).isNull(); + } + @Test public void onConnect_connectionResultDefault_emptySessionExtras() throws Exception { MediaSession session = diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaControllerProviderService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaControllerProviderService.java index 5c17cc70b5..a912560c56 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MediaControllerProviderService.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MediaControllerProviderService.java @@ -21,6 +21,7 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_COMMAND_BU import static androidx.media3.test.session.common.TestUtils.SERVICE_CONNECTION_TIMEOUT_MS; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -854,6 +855,12 @@ public class MediaControllerProviderService extends Service { return runOnHandler(controller::getAvailableCommands).toBundle(); } + @Override + public PendingIntent getSessionActivity(String controllerId) throws RemoteException { + MediaController controller = mediaControllerMap.get(controllerId); + return runOnHandler(controller::getSessionActivity); + } + @Override public Bundle getItem(String controllerId, String mediaId) throws RemoteException { MediaBrowser browser = (MediaBrowser) mediaControllerMap.get(controllerId); 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 206db15a60..6557d4ec3c 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 @@ -111,6 +111,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Callable; /** @@ -607,9 +608,29 @@ public class MediaSessionProviderService extends Service { } @Override - public void setSessionActivity(String sessionId, PendingIntent sessionActivity) + public void setSessionActivity( + String sessionId, @Nullable String controllerKey, PendingIntent sessionActivity) throws RemoteException { - runOnHandler(() -> sessionMap.get(sessionId).setSessionActivity(sessionActivity)); + MediaSession mediaSession = sessionMap.get(sessionId); + if (mediaSession == null) { + return; + } + if (controllerKey == null) { + // Set to all controllers by using the global session method. + runOnHandler(() -> mediaSession.setSessionActivity(sessionActivity)); + return; + } + List connectedControllers = mediaSession.getConnectedControllers(); + for (int i = 0; i < connectedControllers.size(); i++) { + ControllerInfo controllerInfo = connectedControllers.get(i); + @Nullable + String connectedControllerKey = + controllerInfo.getConnectionHints().getString(KEY_CONTROLLER); + if (Objects.equals(controllerKey, connectedControllerKey)) { + // Set to controller for that the test case has given the provided controllerKey. + runOnHandler(() -> mediaSession.setSessionActivity(controllerInfo, sessionActivity)); + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaController.java b/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaController.java index 6b9ab66892..b8143f31e8 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaController.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaController.java @@ -22,6 +22,7 @@ import static androidx.media3.test.session.common.TestUtils.SERVICE_CONNECTION_T import static com.google.common.truth.Truth.assertWithMessage; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -393,6 +394,10 @@ public class RemoteMediaController { return Player.Commands.fromBundle(commandsBundle); } + public PendingIntent getSessionActivity() throws RemoteException { + return binder.getSessionActivity(controllerId); + } + //////////////////////////////////////////////////////////////////////////////// // Non-public methods //////////////////////////////////////////////////////////////////////////////// diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaSession.java b/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaSession.java index 869b9eb164..70af785ff7 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaSession.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/RemoteMediaSession.java @@ -209,8 +209,9 @@ public class RemoteMediaSession { binder.setSessionExtrasForController(sessionId, controllerKey, extras); } - public void setSessionActivity(PendingIntent sessionActivity) throws RemoteException { - binder.setSessionActivity(sessionId, sessionActivity); + public void setSessionActivity(String controllerKey, PendingIntent sessionActivity) + throws RemoteException { + binder.setSessionActivity(sessionId, controllerKey, sessionActivity); } public void sendError(@Nullable String controllerKey, SessionError sessionError)