diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaBrowserImplLegacy.java b/libraries/session/src/main/java/androidx/media3/session/MediaBrowserImplLegacy.java index a8ef55e73c..b37d9676c0 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaBrowserImplLegacy.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaBrowserImplLegacy.java @@ -43,6 +43,7 @@ import com.google.common.util.concurrent.SettableFuture; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Objects; import org.checkerframework.checker.initialization.qual.UnderInitialization; /** Implementation of MediaBrowser with the {@link MediaBrowserCompat} for legacy support. */ @@ -93,8 +94,21 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; } @Override - public ImmutableMap getCommandButtonsForMediaItemsMap() { - return commandButtonsForMediaItems; + public ImmutableList getCommandButtonsForMediaItem(MediaItem mediaItem) { + // Do not filter by available commands. When connected to a legacy session, the available + // session commands are read from the custom actions in PlaybackStateCompat (see + // LegacyConversion.convertToSessionCommands). Filtering by these commands would force a + // legacy session to put all commands for media items into the playback state as custom commands + // which would interfere with the custom commands set for media controls. + ImmutableList supportedActions = mediaItem.mediaMetadata.supportedCommands; + ImmutableList.Builder commandButtonsForMediaItem = new ImmutableList.Builder<>(); + for (int i = 0; i < supportedActions.size(); i++) { + CommandButton commandButton = commandButtonsForMediaItems.get(supportedActions.get(i)); + if (commandButton != null && commandButton.sessionCommand != null) { + commandButtonsForMediaItem.add(commandButton); + } + } + return commandButtonsForMediaItem.build(); } @Override @@ -307,7 +321,9 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; @Override public ListenableFuture sendCustomCommand(SessionCommand command, Bundle args) { MediaBrowserCompat browserCompat = getBrowserCompat(); - if (browserCompat != null && instance.isSessionCommandAvailable(command)) { + if (browserCompat != null + && (instance.isSessionCommandAvailable(command) + || isContainedInCommandButtonsForMediaItems(command))) { SettableFuture settable = SettableFuture.create(); browserCompat.sendCustomAction( command.customAction, @@ -330,7 +346,20 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; }); return settable; } - return super.sendCustomCommand(command, args); + return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_ERROR_PERMISSION_DENIED)); + } + + // Using this method as a proxy whether an browser is allowed to send a custom action can be + // justified because a MediaBrowserCompat can declare the custom browse actions in onGetRoot() + // specifically for each browser that connects. This is different to Media3 where the command + // buttons for media items are declared on the session level, and are constraint by the available + // session commands granted individually to a controller/browser in onConnect. + private boolean isContainedInCommandButtonsForMediaItems(SessionCommand command) { + if (command.commandCode != SessionCommand.COMMAND_CODE_CUSTOM) { + return false; + } + CommandButton commandButton = commandButtonsForMediaItems.get(command.customAction); + return commandButton != null && Objects.equals(commandButton.sessionCommand, command); } private MediaBrowserCompat getBrowserCompat(LibraryParams extras) { 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 15abc49131..8719ddeca7 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaController.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaController.java @@ -62,7 +62,6 @@ import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSourceBitmapLoader; import androidx.media3.session.legacy.MediaBrowserCompat; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -674,16 +673,7 @@ public class MediaController implements Player { */ @UnstableApi public final ImmutableList getCommandButtonsForMediaItem(MediaItem mediaItem) { - ImmutableMap buttonMap = impl.getCommandButtonsForMediaItemsMap(); - ImmutableList supportedActions = mediaItem.mediaMetadata.supportedCommands; - ImmutableList.Builder commandButtonsForMediaItem = new ImmutableList.Builder<>(); - for (int i = 0; i < supportedActions.size(); i++) { - CommandButton commandButton = buttonMap.get(supportedActions.get(i)); - if (commandButton != null) { - commandButtonsForMediaItem.add(commandButton); - } - } - return commandButtonsForMediaItem.build(); + return impl.getCommandButtonsForMediaItem(mediaItem); } @Override @@ -2174,7 +2164,7 @@ public class MediaController implements Player { ImmutableList getCustomLayout(); - ImmutableMap getCommandButtonsForMediaItemsMap(); + ImmutableList getCommandButtonsForMediaItem(MediaItem mediaItem); Bundle getSessionExtras(); diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java b/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java index e59c0bb81d..126cf87f72 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java @@ -745,8 +745,19 @@ import org.checkerframework.checker.nullness.qual.NonNull; } @Override - public ImmutableMap getCommandButtonsForMediaItemsMap() { - return commandButtonsForMediaItemsMap; + public ImmutableList getCommandButtonsForMediaItem(MediaItem mediaItem) { + ImmutableList supportedActions = mediaItem.mediaMetadata.supportedCommands; + SessionCommands availableSessionCommands = getAvailableSessionCommands(); + ImmutableList.Builder commandButtonsForMediaItem = new ImmutableList.Builder<>(); + for (int i = 0; i < supportedActions.size(); i++) { + CommandButton commandButton = commandButtonsForMediaItemsMap.get(supportedActions.get(i)); + if (commandButton != null + && commandButton.sessionCommand != null + && availableSessionCommands.contains(commandButton.sessionCommand)) { + commandButtonsForMediaItem.add(commandButton); + } + } + return commandButtonsForMediaItem.build(); } @Override diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplLegacy.java b/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplLegacy.java index 24cdc6811a..43e2c72cfb 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplLegacy.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplLegacy.java @@ -76,7 +76,6 @@ import androidx.media3.session.legacy.PlaybackStateCompat; import androidx.media3.session.legacy.RatingCompat; import androidx.media3.session.legacy.VolumeProviderCompat; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; @@ -102,6 +101,7 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; private final ListenerSet listeners; private final ControllerCompatCallback controllerCompatCallback; private final BitmapLoader bitmapLoader; + private final ImmutableList commandButtonsForMediaItems; @Nullable private MediaControllerCompat controllerCompat; @Nullable private MediaBrowserCompat browserCompat; @@ -137,6 +137,8 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; this.bitmapLoader = bitmapLoader; currentPositionMs = C.TIME_UNSET; lastSetPlayWhenReadyCalledTimeMs = C.TIME_UNSET; + // Always empty. Only supported for a MediaBrowser connected to a MediaBrowserServiceCompat. + commandButtonsForMediaItems = ImmutableList.of(); } /* package */ MediaController getInstance() { @@ -410,6 +412,11 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; controllerCompat.getTransportControls().fastForward(); } + @Override + public ImmutableList getCommandButtonsForMediaItem(MediaItem mediaItem) { + return commandButtonsForMediaItems; + } + @Override @Nullable public PendingIntent getSessionActivity() { @@ -421,11 +428,6 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization; return controllerInfo.customLayout; } - @Override - public ImmutableMap getCommandButtonsForMediaItemsMap() { - return ImmutableMap.of(); - } - @Override public Bundle getSessionExtras() { return controllerInfo.sessionExtras; diff --git a/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/MediaSessionConstants.java b/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/MediaSessionConstants.java index 5b75b7ea06..5d575e4225 100644 --- a/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/MediaSessionConstants.java +++ b/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/MediaSessionConstants.java @@ -23,6 +23,8 @@ public class MediaSessionConstants { public static final String TEST_GET_CUSTOM_LAYOUT = "testGetCustomLayout"; public static final String TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS = "testGetCommandButtonsForMediaItems"; + public static final String TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE = + "testGetCommandButtonsForMediaItemsCommandsNotAvailable"; public static final String TEST_WITH_CUSTOM_COMMANDS = "testWithCustomCommands"; public static final String TEST_CONTROLLER_LISTENER_SESSION_REJECTS = "connection_sessionRejects"; public static final String TEST_IS_SESSION_COMMAND_AVAILABLE = "testIsSessionCommandAvailable"; diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserListenerWithMediaBrowserServiceCompatTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserListenerWithMediaBrowserServiceCompatTest.java index 6294fd1e6b..eacb435187 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserListenerWithMediaBrowserServiceCompatTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserListenerWithMediaBrowserServiceCompatTest.java @@ -220,8 +220,20 @@ public class MediaBrowserListenerWithMediaBrowserServiceCompatTest { @Test public void sendCustomCommandWithMediaItem_mediaItemIdConvertedCorrectly() throws Exception { remoteService.setProxyForTest(TEST_MEDIA_ITEMS_WITH_BROWSE_ACTIONS); - MediaBrowser mediaBrowser = createBrowser(/* listener= */ null); + MediaBrowser mediaBrowser = + createBrowser( + /* connectionHints= */ Bundle.EMPTY, + /* maxCommandsForMediaItems= */ 2, + /* listener= */ null); MediaItem mediaItem = new MediaItem.Builder().setMediaId("mediaIdFromCommand").build(); + // When connected to a legacy browser service, the library root needs to be requested + // before media item commands are available. + LibraryResult libraryRootResult = + threadTestRule + .getHandler() + .postAndSync(() -> mediaBrowser.getLibraryRoot(new LibraryParams.Builder().build())) + .get(TIMEOUT_MS, MILLISECONDS); + assertThat(libraryRootResult.resultCode).isEqualTo(RESULT_SUCCESS); SessionResult sessionResult = threadTestRule @@ -232,12 +244,45 @@ public class MediaBrowserListenerWithMediaBrowserServiceCompatTest { new SessionCommand(MediaBrowserConstants.COMMAND_RADIO, Bundle.EMPTY), mediaItem, /* args= */ Bundle.EMPTY)) - .get(); + .get(TIMEOUT_MS, MILLISECONDS); assertThat(sessionResult.extras.getString(MediaConstants.EXTRA_KEY_MEDIA_ID)) .isEqualTo("mediaIdFromCommand"); } + @Test + public void sendCustomCommandWithMediaItem_commandButtonNotAvailable_permissionDenied() + throws Exception { + remoteService.setProxyForTest(TEST_MEDIA_ITEMS_WITH_BROWSE_ACTIONS); + MediaBrowser mediaBrowser = + createBrowser( + /* connectionHints= */ Bundle.EMPTY, + /* maxCommandsForMediaItems= */ 0, + /* listener= */ null); + MediaItem mediaItem = new MediaItem.Builder().setMediaId("mediaIdFromCommand").build(); + // When connected to a legacy browser service, the library root needs to be requested + // before media item commands are available. + LibraryResult libraryRootResult = + threadTestRule + .getHandler() + .postAndSync(() -> mediaBrowser.getLibraryRoot(new LibraryParams.Builder().build())) + .get(TIMEOUT_MS, MILLISECONDS); + assertThat(libraryRootResult.resultCode).isEqualTo(RESULT_SUCCESS); + + SessionResult sessionResult = + threadTestRule + .getHandler() + .postAndSync( + () -> + mediaBrowser.sendCustomCommand( + new SessionCommand(MediaBrowserConstants.COMMAND_RADIO, Bundle.EMPTY), + mediaItem, + /* args= */ Bundle.EMPTY)) + .get(TIMEOUT_MS, MILLISECONDS); + + assertThat(sessionResult.resultCode).isEqualTo(SessionResult.RESULT_ERROR_PERMISSION_DENIED); + } + @Test public void onChildrenChanged_subscribeAndUnsubscribe() throws Exception { String testParentId = "testOnChildrenChanged"; diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java index 037ba929e0..d842e7a33b 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java @@ -22,6 +22,7 @@ import static androidx.media3.test.session.common.CommonConstants.DEFAULT_TEST_N import static androidx.media3.test.session.common.CommonConstants.SUPPORT_APP_PACKAGE_NAME; import static androidx.media3.test.session.common.MediaSessionConstants.KEY_AVAILABLE_SESSION_COMMANDS; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS; +import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_CUSTOM_LAYOUT; 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; @@ -68,10 +69,8 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.LargeTest; import com.google.common.collect.ImmutableList; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -554,7 +553,8 @@ public class MediaControllerTest { @Test public void getCommandButtonsForMediaItem() throws Exception { RemoteMediaSession session = - createRemoteMediaSession(TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS, /* tokenExtras= */ null); + createRemoteMediaSession( + TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS, /* tokenExtras= */ Bundle.EMPTY); CommandButton playlistAddButton = new CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setSessionCommand( @@ -588,10 +588,41 @@ public class MediaControllerTest { session.cleanUp(); } + @Test + public void getCommandButtonsForMediaItem_availableCommandsNotGranted_commandButtonsEmpty() + throws Exception { + RemoteMediaSession session = + createRemoteMediaSession( + TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE, + /* tokenExtras= */ Bundle.EMPTY); + MediaItem mediaItem = + new MediaItem.Builder() + .setMediaId("mediaId") + .setMediaMetadata( + new MediaMetadata.Builder() + .setSupportedCommands( + ImmutableList.of( + MediaBrowserConstants.COMMAND_PLAYLIST_ADD, + MediaBrowserConstants.COMMAND_RADIO, + "invalid")) + .build()) + .build(); + MediaController controller = controllerTestRule.createController(session.getToken()); + + ImmutableList commandButtons = + threadTestRule + .getHandler() + .postAndSync(() -> controller.getCommandButtonsForMediaItem(mediaItem)); + + assertThat(commandButtons).isEmpty(); + session.cleanUp(); + } + @Test public void sendCustomCommandForMediaItem() throws Exception { RemoteMediaSession session = - createRemoteMediaSession(TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS, /* tokenExtras= */ null); + createRemoteMediaSession( + TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS, /* tokenExtras= */ Bundle.EMPTY); MediaItem mediaItem = new MediaItem.Builder() .setMediaId("mediaId-1") @@ -601,11 +632,9 @@ public class MediaControllerTest { ImmutableList.of(MediaBrowserConstants.COMMAND_PLAYLIST_ADD)) .build()) .build(); - CountDownLatch latch = new CountDownLatch(/* count= */ 1); - AtomicReference sessionResultRef = new AtomicReference<>(); MediaController controller = controllerTestRule.createController(session.getToken()); - Futures.addCallback( + SessionResult sessionResult = threadTestRule .getHandler() .postAndSync( @@ -614,29 +643,48 @@ public class MediaControllerTest { controller.getCommandButtonsForMediaItem(mediaItem).get(0); return controller.sendCustomCommand( commandButton.sessionCommand, mediaItem, Bundle.EMPTY); - }), - new FutureCallback() { - @Override - public void onSuccess(SessionResult result) { - sessionResultRef.set(result); - latch.countDown(); - } + }) + .get(TIMEOUT_MS, MILLISECONDS); - @Override - public void onFailure(Throwable t) { - latch.countDown(); - } - }, - MoreExecutors.directExecutor()); - - assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue(); - assertThat(sessionResultRef.get()).isNotNull(); - assertThat(sessionResultRef.get().resultCode).isEqualTo(SessionResult.RESULT_SUCCESS); - assertThat(sessionResultRef.get().extras.getString(MediaConstants.EXTRA_KEY_MEDIA_ID)) + assertThat(sessionResult.resultCode).isEqualTo(SessionResult.RESULT_SUCCESS); + assertThat(sessionResult.extras.getString(MediaConstants.EXTRA_KEY_MEDIA_ID)) .isEqualTo("mediaId-1"); session.cleanUp(); } + @Test + public void sendCustomCommandForMediaItem_availableCommandsNotGranted_permissionDenied() + throws Exception { + RemoteMediaSession session = + createRemoteMediaSession( + TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE, + /* tokenExtras= */ Bundle.EMPTY); + SessionCommand playlistAddSessionCommand = + new SessionCommand(MediaBrowserConstants.COMMAND_PLAYLIST_ADD, /* extras= */ Bundle.EMPTY); + MediaItem mediaItem = + new MediaItem.Builder() + .setMediaId("mediaId-1") + .setMediaMetadata( + new MediaMetadata.Builder() + .setSupportedCommands( + ImmutableList.of(MediaBrowserConstants.COMMAND_PLAYLIST_ADD)) + .build()) + .build(); + MediaController controller = controllerTestRule.createController(session.getToken()); + + SessionResult sessionResult = + threadTestRule + .getHandler() + .postAndSync( + () -> + controller.sendCustomCommand( + playlistAddSessionCommand, mediaItem, Bundle.EMPTY)) + .get(TIMEOUT_MS, MILLISECONDS); + + assertThat(sessionResult.resultCode).isEqualTo(SessionResult.RESULT_ERROR_PERMISSION_DENIED); + session.cleanUp(); + } + @Test public void getSessionExtras_includedInConnectionStateWhenConnecting() throws Exception { RemoteMediaSession session = 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 f2aee71628..03c0e6e898 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 @@ -64,6 +64,7 @@ import static androidx.media3.test.session.common.MediaSessionConstants.NOTIFICA import static androidx.media3.test.session.common.MediaSessionConstants.TEST_COMMAND_GET_TRACKS; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS; +import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE; import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_CUSTOM_LAYOUT; 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; @@ -237,6 +238,7 @@ public class MediaSessionProviderService extends Service { break; } case TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS: + case TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE: { CommandButton playlistAddButton = new CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) @@ -256,6 +258,10 @@ public class MediaSessionProviderService extends Service { @Override public MediaSession.ConnectionResult onConnect( MediaSession session, ControllerInfo controller) { + if (sessionId.equals( + TEST_GET_COMMAND_BUTTONS_FOR_MEDIA_ITEMS_COMMANDS_NOT_AVAILABLE)) { + return MediaSession.Callback.super.onConnect(session, controller); + } return new MediaSession.ConnectionResult.AcceptedResultBuilder(session) .setAvailableSessionCommands( new SessionCommands.Builder() diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaBrowserServiceCompat.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaBrowserServiceCompat.java index 94e2d5bfeb..6b1e3118d0 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaBrowserServiceCompat.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaBrowserServiceCompat.java @@ -46,7 +46,6 @@ import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaBrowserCompat.MediaItem; import android.support.v4.media.MediaDescriptionCompat; import android.support.v4.media.session.MediaSessionCompat; -import android.support.v4.media.session.MediaSessionCompat.Callback; import android.support.v4.media.session.PlaybackStateCompat; import androidx.annotation.GuardedBy; import androidx.annotation.Nullable; @@ -89,7 +88,7 @@ public class MockMediaBrowserServiceCompat extends MediaBrowserServiceCompat { instance = this; } sessionCompat = new MediaSessionCompat(this, TAG); - sessionCompat.setCallback(new Callback() {}); + sessionCompat.setCallback(new MediaSessionCompat.Callback() {}); sessionCompat.setActive(true); setSessionToken(sessionCompat.getSessionToken()); @@ -401,27 +400,6 @@ public class MockMediaBrowserServiceCompat extends MediaBrowserServiceCompat { } extras.putParcelableArrayList( BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST, browseActionList); - - session.setPlaybackState( - new PlaybackStateCompat.Builder() - .setState( - PlaybackStateCompat.STATE_PLAYING, - /* position= */ 123L, - /* playbackSpeed= */ 1.0f) - .addCustomAction( - new PlaybackStateCompat.CustomAction.Builder( - MediaBrowserConstants.COMMAND_PLAYLIST_ADD, - "Add to playlist", - CommandButton.ICON_PLAYLIST_ADD) - .build()) - .addCustomAction( - new PlaybackStateCompat.CustomAction.Builder( - MediaBrowserConstants.COMMAND_RADIO, - "Radio station", - CommandButton.ICON_RADIO) - .build()) - .build()); - return new BrowserRoot(ROOT_ID, extras); }