Implement session extras for Media3 and legacy controllers

This provides an (unstable) API for apps to broadcast session extras
Bundle to all connected controllers and set the extras in the legacy
session.

Similar to the custom layout, the extras Bundle is not part of the
Media3 session state. This means that when a Media3 controller
connects to the session after the broadcast, the extras needs to be
sent to that controller in  `MediaSession.Callback.onPostConnect(MediaSession session, ControllerInfo controller)`.

PiperOrigin-RevId: 451871731
This commit is contained in:
bachinger 2022-05-30 14:24:42 +00:00 committed by Marc Baechinger
parent a629d09458
commit 85a936ecb1
22 changed files with 260 additions and 12 deletions

View File

@ -42,7 +42,8 @@ oneway interface IMediaController {
void onAvailableCommandsChangedFromSession( void onAvailableCommandsChangedFromSession(
int seq, in Bundle sessionCommandsBundle, in Bundle playerCommandsBundle) = 3009; int seq, in Bundle sessionCommandsBundle, in Bundle playerCommandsBundle) = 3009;
void onRenderedFirstFrame(int seq) = 3010; void onRenderedFirstFrame(int seq) = 3010;
// Next Id for MediaController: 3011 void onExtrasChanged(int seq, in Bundle extras) = 3011;
// Next Id for MediaController: 3012
void onChildrenChanged( void onChildrenChanged(
int seq, String parentId, int itemCount, in @nullable Bundle libraryParams) = 4000; int seq, String parentId, int itemCount, in @nullable Bundle libraryParams) = 4000;

View File

@ -151,8 +151,6 @@ public final class MediaConstants {
*/ */
public static final int ERROR_CODE_AUTHENTICATION_EXPIRED_COMPAT = 3; public static final int ERROR_CODE_AUTHENTICATION_EXPIRED_COMPAT = 3;
/* package */ static final String SESSION_COMMAND_ON_EXTRAS_CHANGED =
"androidx.media3.session.SESSION_COMMAND_ON_EXTRAS_CHANGED";
/* package */ static final String SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED = /* package */ static final String SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED =
"androidx.media3.session.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED"; "androidx.media3.session.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED";
/* package */ static final String SESSION_COMMAND_REQUEST_SESSION3_TOKEN = /* package */ static final String SESSION_COMMAND_REQUEST_SESSION3_TOKEN =

View File

@ -322,6 +322,14 @@ public class MediaController implements Player {
MediaController controller, SessionCommand command, Bundle args) { MediaController controller, SessionCommand command, Bundle args) {
return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED)); return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED));
} }
/**
* Called when the session extras have changed.
*
* @param controller The controller.
* @param extras The session extras that have changed.
*/
default void onExtrasChanged(MediaController controller, Bundle extras) {}
} }
/* package */ interface ConnectionCallback { /* package */ interface ConnectionCallback {

View File

@ -2598,6 +2598,13 @@ import org.checkerframework.checker.nullness.qual.NonNull;
}); });
} }
public void onExtrasChanged(Bundle extras) {
if (!isConnected()) {
return;
}
instance.notifyControllerListener(listener -> listener.onExtrasChanged(instance, extras));
}
public void onRenderedFirstFrame() { public void onRenderedFirstFrame() {
listeners.sendEvent(/* eventFlag= */ C.INDEX_UNSET, Listener::onRenderedFirstFrame); listeners.sendEvent(/* eventFlag= */ C.INDEX_UNSET, Listener::onRenderedFirstFrame);
} }

View File

@ -38,7 +38,6 @@ import static androidx.media3.session.MediaConstants.MEDIA_URI_QUERY_QUERY;
import static androidx.media3.session.MediaConstants.MEDIA_URI_QUERY_URI; import static androidx.media3.session.MediaConstants.MEDIA_URI_QUERY_URI;
import static androidx.media3.session.MediaConstants.MEDIA_URI_SET_MEDIA_URI_PREFIX; import static androidx.media3.session.MediaConstants.MEDIA_URI_SET_MEDIA_URI_PREFIX;
import static androidx.media3.session.MediaConstants.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED; import static androidx.media3.session.MediaConstants.SESSION_COMMAND_ON_CAPTIONING_ENABLED_CHANGED;
import static androidx.media3.session.MediaConstants.SESSION_COMMAND_ON_EXTRAS_CHANGED;
import static androidx.media3.session.MediaUtils.POSITION_DIFF_TOLERANCE_MS; import static androidx.media3.session.MediaUtils.POSITION_DIFF_TOLERANCE_MS;
import static androidx.media3.session.MediaUtils.calculateBufferedPercentage; import static androidx.media3.session.MediaUtils.calculateBufferedPercentage;
import static androidx.media3.session.SessionResult.RESULT_INFO_SKIPPED; import static androidx.media3.session.SessionResult.RESULT_INFO_SKIPPED;
@ -1606,14 +1605,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Override @Override
public void onExtrasChanged(Bundle extras) { public void onExtrasChanged(Bundle extras) {
instance.notifyControllerListener( instance.notifyControllerListener(listener -> listener.onExtrasChanged(instance, extras));
listener ->
ignoreFuture(
listener.onCustomCommand(
instance,
new SessionCommand(
SESSION_COMMAND_ON_EXTRAS_CHANGED, /* extras= */ Bundle.EMPTY),
extras)));
} }
@Override @Override

View File

@ -183,6 +183,11 @@ import java.util.List;
isTimelineExcluded)); isTimelineExcluded));
} }
@Override
public void onExtrasChanged(int seq, Bundle extras) {
dispatchControllerTaskOnHandler(controller -> controller.onExtrasChanged(extras));
}
@Override @Override
public void onRenderedFirstFrame(int seq) { public void onRenderedFirstFrame(int seq) {
dispatchControllerTaskOnHandler(MediaControllerImplBase::onRenderedFirstFrame); dispatchControllerTaskOnHandler(MediaControllerImplBase::onRenderedFirstFrame);

View File

@ -702,6 +702,32 @@ public class MediaSession {
impl.broadcastCustomCommand(command, args); impl.broadcastCustomCommand(command, args);
} }
/**
* Sends the session extras to connected controllers.
*
* <p>This is a synchronous call and doesn't wait for results from the controllers.
*
* @param sessionExtras The session extras.
*/
public void setSessionExtras(Bundle sessionExtras) {
checkNotNull(sessionExtras);
impl.setSessionExtras(sessionExtras);
}
/**
* Sends the session extras to the connected controller.
*
* <p>This is a synchronous call and doesn't wait for results from the controller.
*
* @param controller The controller to send the extras to.
* @param sessionExtras The session extras.
*/
public void setSessionExtras(ControllerInfo controller, Bundle sessionExtras) {
checkNotNull(controller, "controller must not be null");
checkNotNull(sessionExtras);
impl.setSessionExtras(controller, sessionExtras);
}
/** /**
* Sends a custom command to a specific controller. * Sends a custom command to a specific controller.
* *
@ -1119,6 +1145,8 @@ public class MediaSession {
default void setCustomLayout(int seq, List<CommandButton> layout) throws RemoteException {} default void setCustomLayout(int seq, List<CommandButton> layout) throws RemoteException {}
default void onSessionExtrasChanged(int seq, Bundle sessionExtras) throws RemoteException {}
default void sendCustomCommand(int seq, SessionCommand command, Bundle args) default void sendCustomCommand(int seq, SessionCommand command, Bundle args)
throws RemoteException {} throws RemoteException {}

View File

@ -342,6 +342,18 @@ import org.checkerframework.checker.initialization.qual.Initialized;
(controller, seq) -> controller.setCustomLayout(seq, layout)); (controller, seq) -> controller.setCustomLayout(seq, layout));
} }
public void setSessionExtras(Bundle sessionExtras) {
dispatchRemoteControllerTaskWithoutReturn(
(controller, seq) -> controller.onSessionExtrasChanged(seq, sessionExtras));
}
public void setSessionExtras(ControllerInfo controller, Bundle sessionExtras) {
if (sessionStub.getConnectedControllersManager().isConnected(controller)) {
dispatchRemoteControllerTaskWithoutReturn(
controller, (callback, seq) -> callback.onSessionExtrasChanged(seq, sessionExtras));
}
}
public void setAvailableCommands( public void setAvailableCommands(
ControllerInfo controller, SessionCommands sessionCommands, Player.Commands playerCommands) { ControllerInfo controller, SessionCommands sessionCommands, Player.Commands playerCommands) {
if (sessionStub.getConnectedControllersManager().isConnected(controller)) { if (sessionStub.getConnectedControllersManager().isConnected(controller)) {

View File

@ -886,6 +886,11 @@ import org.checkerframework.checker.initialization.qual.Initialized;
.setPlaybackState(sessionImpl.getPlayerWrapper().createPlaybackStateCompat()); .setPlaybackState(sessionImpl.getPlayerWrapper().createPlaybackStateCompat());
} }
@Override
public void onSessionExtrasChanged(int seq, Bundle sessionExtras) {
sessionImpl.getSessionCompat().setExtras(sessionExtras);
}
@Override @Override
public void onPlayWhenReadyChanged( public void onPlayWhenReadyChanged(
int seq, boolean playWhenReady, @Player.PlaybackSuppressionReason int reason) int seq, boolean playWhenReady, @Player.PlaybackSuppressionReason int reason)

View File

@ -1801,6 +1801,11 @@ import java.util.concurrent.ExecutionException;
iController.onRenderedFirstFrame(seq); iController.onRenderedFirstFrame(seq);
} }
@Override
public void onSessionExtrasChanged(int seq, Bundle sessionExtras) throws RemoteException {
iController.onExtrasChanged(seq, sessionExtras);
}
@Override @Override
public int hashCode() { public int hashCode() {
return ObjectsCompat.hash(getCallbackBinder()); return ObjectsCompat.hash(getCallbackBinder());

View File

@ -32,6 +32,8 @@ interface IRemoteMediaSession {
void release(String sessionId); void release(String sessionId);
void setAvailableCommands(String sessionId, in Bundle sessionCommands, in Bundle playerCommands); void setAvailableCommands(String sessionId, in Bundle sessionCommands, in Bundle playerCommands);
void setCustomLayout(String sessionId, in List<Bundle> layout); void setCustomLayout(String sessionId, in List<Bundle> layout);
void setSessionExtras(String sessionId, in Bundle extras);
void setSessionExtrasForController(String sessionId, in String controllerKey, in Bundle extras);
// Player Methods // Player Methods
void setPlayWhenReady(String sessionId, boolean playWhenReady, int reason); void setPlayWhenReady(String sessionId, boolean playWhenReady, int reason);

View File

@ -41,4 +41,5 @@ interface IRemoteMediaSessionCompat {
void setRatingType(String sessionTag, int type); void setRatingType(String sessionTag, int type);
void sendSessionEvent(String sessionTag, String event, in Bundle extras); void sendSessionEvent(String sessionTag, String event, in Bundle extras);
void setCaptioningEnabled(String sessionTag, boolean enabled); void setCaptioningEnabled(String sessionTag, boolean enabled);
void setSessionExtras(String sessionTag, in Bundle extras);
} }

View File

@ -29,6 +29,7 @@ public class MediaSessionConstants {
// Bundle keys // Bundle keys
public static final String KEY_AVAILABLE_SESSION_COMMANDS = "availableSessionCommands"; public static final String KEY_AVAILABLE_SESSION_COMMANDS = "availableSessionCommands";
public static final String KEY_CONTROLLER = "controllerKey";
private MediaSessionConstants() {} private MediaSessionConstants() {}
} }

View File

@ -27,6 +27,7 @@ import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import androidx.media3.test.session.common.HandlerThreadTestRule; import androidx.media3.test.session.common.HandlerThreadTestRule;
import androidx.media3.test.session.common.MainLooperTestRule; import androidx.media3.test.session.common.MainLooperTestRule;
import androidx.media3.test.session.common.TestUtils;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest; import androidx.test.filters.LargeTest;
@ -137,4 +138,42 @@ public class MediaControllerCompatCallbackWithMediaSessionCompatTest {
assertThat(receivedIconResIds).containsExactly(1, 2).inOrder(); assertThat(receivedIconResIds).containsExactly(1, 2).inOrder();
assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder(); assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder();
} }
/**
* Setting the session extras is used for instance by <a
* href="http://android-doc.github.io/reference/android/support/wearable/media/MediaControlConstants.html">
* Wear OS</a> and System UI (starting with T) to receive extras for UI customization. An app
* needs a way to set the session extras that are stored in the legacy session and broadcast to
* the connected controllers.
*/
@Test
public void setExtras_onExtrasChangedCalled() throws Exception {
Bundle sessionExtras = new Bundle();
sessionExtras.putString("key-1", "value-1");
CountDownLatch countDownLatch = new CountDownLatch(1);
MediaSessionCompat.Token sessionToken = session.getSessionToken();
List<Bundle> receivedSessionExtras = new ArrayList<>();
threadTestRule
.getHandler()
.postAndSync(
() -> {
MediaControllerCompat mediaControllerCompat =
new MediaControllerCompat(context, sessionToken);
mediaControllerCompat.registerCallback(
new MediaControllerCompat.Callback() {
@Override
public void onExtrasChanged(Bundle extras) {
receivedSessionExtras.add(extras);
receivedSessionExtras.add(mediaControllerCompat.getExtras());
countDownLatch.countDown();
}
});
});
session.setExtras(sessionExtras);
assertThat(countDownLatch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue();
assertThat(TestUtils.equals(receivedSessionExtras.get(1), sessionExtras)).isTrue();
}
} }

View File

@ -819,6 +819,30 @@ public class MediaControllerCompatCallbackWithMediaSessionTest {
assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder(); assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder();
} }
@Test
public void setSessionExtras_cnExtrasChangedCalled() throws Exception {
Bundle sessionExtras = new Bundle();
sessionExtras.putString("key-0", "value-0");
CountDownLatch latch = new CountDownLatch(1);
List<Bundle> receivedSessionExtras = new ArrayList<>();
MediaControllerCompat.Callback callback =
new MediaControllerCompat.Callback() {
@Override
public void onExtrasChanged(Bundle extras) {
receivedSessionExtras.add(extras);
receivedSessionExtras.add(controllerCompat.getExtras());
latch.countDown();
}
};
controllerCompat.registerCallback(callback, handler);
session.setSessionExtras(sessionExtras);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue();
assertThat(TestUtils.equals(receivedSessionExtras.get(1), sessionExtras)).isTrue();
}
@Test @Test
public void currentMediaItemChange() throws Exception { public void currentMediaItemChange() throws Exception {
int testItemIndex = 3; int testItemIndex = 3;

View File

@ -28,6 +28,7 @@ import static androidx.media3.session.SessionResult.RESULT_SUCCESS;
import static androidx.media3.test.session.common.CommonConstants.DEFAULT_TEST_NAME; import static androidx.media3.test.session.common.CommonConstants.DEFAULT_TEST_NAME;
import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_LIBRARY_SERVICE; import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_LIBRARY_SERVICE;
import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_SESSION_SERVICE; import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_SESSION_SERVICE;
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_CONTROLLER;
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS;
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_WITH_CUSTOM_COMMANDS; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_WITH_CUSTOM_COMMANDS;
import static androidx.media3.test.session.common.TestUtils.LONG_TIMEOUT_MS; import static androidx.media3.test.session.common.TestUtils.LONG_TIMEOUT_MS;
@ -1800,6 +1801,55 @@ public class MediaControllerListenerTest {
assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder(); assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder();
} }
@Test
public void setSessionExtras_onExtrasChangedCalled() throws Exception {
Bundle sessionExtras = TestUtils.createTestBundle();
sessionExtras.putString("key-0", "value-0");
CountDownLatch latch = new CountDownLatch(1);
List<Bundle> receivedSessionExtras = new ArrayList<>();
MediaController.Listener listener =
new MediaController.Listener() {
@Override
public void onExtrasChanged(MediaController controller, Bundle extras) {
receivedSessionExtras.add(extras);
latch.countDown();
}
};
controllerTestRule.createController(
remoteSession.getToken(), /* connectionHints= */ null, listener);
remoteSession.setSessionExtras(sessionExtras);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(receivedSessionExtras).hasSize(1);
assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue();
}
@Test
public void setSessionExtras_specificMedia3Controller_onExtrasChangedCalled() throws Exception {
Bundle sessionExtras = TestUtils.createTestBundle();
sessionExtras.putString("key-0", "value-0");
CountDownLatch latch = new CountDownLatch(1);
List<Bundle> receivedSessionExtras = new ArrayList<>();
MediaController.Listener listener =
new MediaController.Listener() {
@Override
public void onExtrasChanged(MediaController controller, Bundle extras) {
receivedSessionExtras.add(extras);
latch.countDown();
}
};
Bundle connectionHints = new Bundle();
connectionHints.putString(KEY_CONTROLLER, "controller_key_1");
controllerTestRule.createController(remoteSession.getToken(), connectionHints, listener);
remoteSession.setSessionExtras("controller_key_1", sessionExtras);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(receivedSessionExtras).hasSize(1);
assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue();
}
@Test @Test
public void onVideoSizeChanged() throws Exception { public void onVideoSizeChanged() throws Exception {
VideoSize testVideoSize = VideoSize testVideoSize =

View File

@ -32,6 +32,7 @@ import androidx.media3.common.FlagSet;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.media3.test.session.common.HandlerThreadTestRule; import androidx.media3.test.session.common.HandlerThreadTestRule;
import androidx.media3.test.session.common.MainLooperTestRule; import androidx.media3.test.session.common.MainLooperTestRule;
import androidx.media3.test.session.common.TestUtils;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest; import androidx.test.filters.LargeTest;
@ -168,4 +169,26 @@ public class MediaControllerListenerWithMediaSessionCompatTest {
assertThat(receivedIconResIds).containsExactly(1, 2).inOrder(); assertThat(receivedIconResIds).containsExactly(1, 2).inOrder();
assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder(); assertThat(receivedBundleValues).containsExactly("value-1", "value-2").inOrder();
} }
@Test
public void setSessionExtras_onExtrasChangedCalled() throws Exception {
Bundle sessionExtras = new Bundle();
sessionExtras.putString("key-1", "value-1");
CountDownLatch countDownLatch = new CountDownLatch(1);
List<Bundle> receivedSessionExtras = new ArrayList<>();
controllerTestRule.createController(
session.getSessionToken(),
new MediaController.Listener() {
@Override
public void onExtrasChanged(MediaController controller, Bundle extras) {
receivedSessionExtras.add(extras);
countDownLatch.countDown();
}
});
session.setExtras(sessionExtras);
assertThat(countDownLatch.await(1_000, MILLISECONDS)).isTrue();
assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue();
}
} }

View File

@ -216,5 +216,11 @@ public class MediaSessionCompatProviderService extends Service {
MediaSessionCompat session = sessionMap.get(sessionTag); MediaSessionCompat session = sessionMap.get(sessionTag);
session.setCaptioningEnabled(enabled); session.setCaptioningEnabled(enabled);
} }
@Override
public void setSessionExtras(String sessionTag, Bundle extras) throws RemoteException {
MediaSessionCompat session = sessionMap.get(sessionTag);
session.setExtras(extras);
}
} }
} }

View File

@ -54,6 +54,7 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_TRACK_SELE
import static androidx.media3.test.session.common.CommonConstants.KEY_VIDEO_SIZE; import static androidx.media3.test.session.common.CommonConstants.KEY_VIDEO_SIZE;
import static androidx.media3.test.session.common.CommonConstants.KEY_VOLUME; import static androidx.media3.test.session.common.CommonConstants.KEY_VOLUME;
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_AVAILABLE_SESSION_COMMANDS; import static androidx.media3.test.session.common.MediaSessionConstants.KEY_AVAILABLE_SESSION_COMMANDS;
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_CONTROLLER;
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS;
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_SESSION_ACTIVITY; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_SESSION_ACTIVITY;
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_IS_SESSION_COMMAND_AVAILABLE; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_IS_SESSION_COMMAND_AVAILABLE;
@ -427,6 +428,29 @@ public class MediaSessionProviderService extends Service {
}); });
} }
@Override
public void setSessionExtras(String sessionId, Bundle extras) throws RemoteException {
runOnHandler(() -> sessionMap.get(sessionId).setSessionExtras(extras));
}
@Override
public void setSessionExtrasForController(String sessionId, String controllerKey, Bundle extras)
throws RemoteException {
runOnHandler(
() -> {
MediaSession mediaSession = sessionMap.get(sessionId);
for (ControllerInfo controllerInfo : mediaSession.getConnectedControllers()) {
if (controllerInfo
.getConnectionHints()
.getString(KEY_CONTROLLER, /* defaultValue= */ "")
.equals(controllerKey)) {
mediaSession.setSessionExtras(controllerInfo, extras);
break;
}
}
});
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// MockPlayer methods // MockPlayer methods
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -197,6 +197,14 @@ public class RemoteMediaSession {
binder.setCustomLayout(sessionId, bundleList); binder.setCustomLayout(sessionId, bundleList);
} }
public void setSessionExtras(Bundle extras) throws RemoteException {
binder.setSessionExtras(sessionId, extras);
}
public void setSessionExtras(String controllerKey, Bundle extras) throws RemoteException {
binder.setSessionExtrasForController(sessionId, controllerKey, extras);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// RemoteMockPlayer methods // RemoteMockPlayer methods
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -173,6 +173,10 @@ public class RemoteMediaSessionCompat {
binder.setCaptioningEnabled(sessionTag, enabled); binder.setCaptioningEnabled(sessionTag, enabled);
} }
public void setExtras(Bundle extras) throws RemoteException {
binder.setSessionExtras(sessionTag, extras);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Non-public methods // Non-public methods
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -58,6 +58,11 @@ public final class TestMediaBrowserListener implements MediaBrowser.Listener {
return delegate.onSetCustomLayout(controller, layout); return delegate.onSetCustomLayout(controller, layout);
} }
@Override
public void onExtrasChanged(MediaController controller, Bundle extras) {
delegate.onExtrasChanged(controller, extras);
}
@Override @Override
public void onAvailableSessionCommandsChanged( public void onAvailableSessionCommandsChanged(
MediaController controller, SessionCommands commands) { MediaController controller, SessionCommands commands) {