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 3c82ec75d2..33e9af7920 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSession.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSession.java @@ -701,6 +701,9 @@ public class MediaSession { * * * + *

Interoperability: This call has no effect when called for a {@linkplain + * ControllerInfo#LEGACY_CONTROLLER_VERSION legacy controller}. + * * @param controller The controller to specify layout. * @param layout The ordered list of {@link CommandButton}. */ @@ -793,6 +796,9 @@ public class MediaSession { * *

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

Interoperability: This call has no effect when called for a {@linkplain + * ControllerInfo#LEGACY_CONTROLLER_VERSION legacy controller}. + * * @param controller The controller to send the extras to. * @param sessionExtras The session extras. */ @@ -816,6 +822,9 @@ public class MediaSession { * *

A command is not accepted if it is not a custom command. * + *

Interoperability: This call has no effect when called for a {@linkplain + * ControllerInfo#LEGACY_CONTROLLER_VERSION legacy controller}. + * * @param controller The controller to send the custom command to. * @param command A custom command. * @param args A {@link Bundle} for additional arguments. May be empty. 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 13cf696db0..45d2db7277 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionLegacyStub.java @@ -987,6 +987,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; sessionImpl.getSessionCompat().setExtras(sessionExtras); } + @Override + public void sendCustomCommand(int seq, SessionCommand command, Bundle args) { + sessionImpl.getSessionCompat().sendSessionEvent(command.customAction, args); + } + @Override public void onPlayWhenReadyChanged( int seq, boolean playWhenReady, @Player.PlaybackSuppressionReason int reason) diff --git a/libraries/session/src/main/java/androidx/media3/session/SessionCommand.java b/libraries/session/src/main/java/androidx/media3/session/SessionCommand.java index c514af10c8..de204146e6 100644 --- a/libraries/session/src/main/java/androidx/media3/session/SessionCommand.java +++ b/libraries/session/src/main/java/androidx/media3/session/SessionCommand.java @@ -123,6 +123,10 @@ public final class SessionCommand implements Bundleable { /** * The extra bundle of a custom command. It will be {@link Bundle#EMPTY} for a predefined command. + * + *

Interoperability: This value is not used when the command is sent to a legacy {@link + * android.support.v4.media.session.MediaSessionCompat} or {@link + * android.support.v4.media.session.MediaControllerCompat}. */ public final Bundle customExtras; @@ -143,7 +147,9 @@ public final class SessionCommand implements Bundleable { * Creates a custom command. * * @param action The action of this custom command. - * @param extras An extra bundle for this custom command. + * @param extras An extra bundle for this custom command. This value is not used when the command + * is sent to a legacy {@link android.support.v4.media.session.MediaSessionCompat} or {@link + * android.support.v4.media.session.MediaControllerCompat}. */ public SessionCommand(String action, Bundle extras) { commandCode = COMMAND_CODE_CUSTOM; 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 71543ae0fe..bd85cf9338 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 @@ -980,6 +980,35 @@ public class MediaControllerCompatCallbackWithMediaSessionTest { assertThat(TestUtils.equals(receivedSessionExtras.get(1), sessionExtras)).isTrue(); } + @Test + public void broadcastCustomCommand_cnSessionEventCalled() throws Exception { + Bundle commandCallExtras = new Bundle(); + commandCallExtras.putString("key-0", "value-0"); + // Specify session command extras to see that they are NOT used. + Bundle sessionCommandExtras = new Bundle(); + sessionCommandExtras.putString("key-0", "value-1"); + SessionCommand sessionCommand = new SessionCommand("custom_action", sessionCommandExtras); + CountDownLatch latch = new CountDownLatch(1); + AtomicReference receivedCommand = new AtomicReference<>(); + AtomicReference receivedCommandExtras = new AtomicReference<>(); + MediaControllerCompat.Callback callback = + new MediaControllerCompat.Callback() { + @Override + public void onSessionEvent(String event, Bundle extras) { + receivedCommand.set(event); + receivedCommandExtras.set(extras); + latch.countDown(); + } + }; + controllerCompat.registerCallback(callback, handler); + + session.broadcastCustomCommand(sessionCommand, commandCallExtras); + + assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); + assertThat(receivedCommand.get()).isEqualTo("custom_action"); + assertThat(TestUtils.equals(receivedCommandExtras.get(), commandCallExtras)).isTrue(); + } + @Test public void onMediaItemTransition_updatesLegacyMetadataAndPlaybackState_correctModelConversion() throws Exception {