Use MediaUtils.intersect in MediaControllerImplBase

PiperOrigin-RevId: 550566322
This commit is contained in:
bachinger 2023-07-24 16:21:43 +01:00 committed by Rohit Singh
parent 2c19399d3e
commit a90ec96425
6 changed files with 77 additions and 13 deletions

View file

@ -149,7 +149,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
playerCommandsFromSession = Commands.EMPTY;
playerCommandsFromPlayer = Commands.EMPTY;
intersectedPlayerCommands =
createIntersectedCommands(playerCommandsFromSession, playerCommandsFromPlayer);
createIntersectedCommandsEnsuringCommandReleaseAvailable(
playerCommandsFromSession, playerCommandsFromPlayer);
listeners =
new ListenerSet<>(
applicationLooper,
@ -2479,7 +2480,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
playerCommandsFromSession = result.playerCommandsFromSession;
playerCommandsFromPlayer = result.playerCommandsFromPlayer;
intersectedPlayerCommands =
createIntersectedCommands(playerCommandsFromSession, playerCommandsFromPlayer);
createIntersectedCommandsEnsuringCommandReleaseAvailable(
playerCommandsFromSession, playerCommandsFromPlayer);
customLayout =
CommandButton.getEnabledCommandButtons(
result.customLayout, sessionCommands, intersectedPlayerCommands);
@ -2638,7 +2640,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
playerCommandsFromSession = playerCommands;
Commands prevIntersectedPlayerCommands = intersectedPlayerCommands;
intersectedPlayerCommands =
createIntersectedCommands(playerCommandsFromSession, playerCommandsFromPlayer);
createIntersectedCommandsEnsuringCommandReleaseAvailable(
playerCommandsFromSession, playerCommandsFromPlayer);
intersectedPlayerCommandsChanged =
!Util.areEqual(intersectedPlayerCommands, prevIntersectedPlayerCommands);
}
@ -2679,7 +2682,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
playerCommandsFromPlayer = commandsFromPlayer;
Commands prevIntersectedPlayerCommands = intersectedPlayerCommands;
intersectedPlayerCommands =
createIntersectedCommands(playerCommandsFromSession, playerCommandsFromPlayer);
createIntersectedCommandsEnsuringCommandReleaseAvailable(
playerCommandsFromSession, playerCommandsFromPlayer);
boolean intersectedPlayerCommandsChanged =
!Util.areEqual(intersectedPlayerCommands, prevIntersectedPlayerCommands);
if (intersectedPlayerCommandsChanged) {
@ -3082,17 +3086,13 @@ import org.checkerframework.checker.nullness.qual.NonNull;
return newMediaItemIndex;
}
private static Commands createIntersectedCommands(
private static Commands createIntersectedCommandsEnsuringCommandReleaseAvailable(
Commands commandFromSession, Commands commandsFromPlayer) {
Commands.Builder intersectCommandsBuilder = new Commands.Builder();
Commands intersectedCommands = MediaUtils.intersect(commandFromSession, commandsFromPlayer);
// Release is always available as it just releases the connection, not the underlying player.
intersectCommandsBuilder.add(Player.COMMAND_RELEASE);
for (int i = 0; i < commandFromSession.size(); i++) {
if (commandsFromPlayer.contains(commandFromSession.get(i))) {
intersectCommandsBuilder.add(commandFromSession.get(i));
}
}
return intersectCommandsBuilder.build();
return intersectedCommands.contains(Player.COMMAND_RELEASE)
? intersectedCommands
: intersectedCommands.buildUpon().add(Player.COMMAND_RELEASE).build();
}
// This will be called on the main thread.

View file

@ -100,6 +100,7 @@ interface IRemoteMediaController {
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(

View file

@ -422,6 +422,32 @@ public class MediaControllerTest {
session.cleanUp();
}
@Test
public void getAvailableCommands_emptyPlayerCommands_commandReleaseStillAvailable()
throws Exception {
CountDownLatch latch = new CountDownLatch(1);
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
List<Player.Commands> capturedCommands = new ArrayList<>();
controller.addListener(
new Player.Listener() {
@Override
public void onAvailableCommandsChanged(Player.Commands availableCommands) {
capturedCommands.add(availableCommands);
capturedCommands.add(controller.getAvailableCommands());
latch.countDown();
}
});
remoteSession.setAvailableCommands(SessionCommands.EMPTY, Player.Commands.EMPTY);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(capturedCommands).hasSize(2);
assertThat(capturedCommands.get(0).size()).isEqualTo(1);
assertThat(capturedCommands.get(0).contains(Player.COMMAND_RELEASE)).isTrue();
assertThat(capturedCommands.get(1).size()).isEqualTo(1);
assertThat(capturedCommands.get(1).contains(Player.COMMAND_RELEASE)).isTrue();
}
@Test
public void getPackageName() throws Exception {
MediaController controller = controllerTestRule.createController(remoteSession.getToken());

View file

@ -193,6 +193,31 @@ public class MediaSessionCallbackTest {
.isEqualTo(RESULT_SUCCESS);
}
@Test
public void onConnect_emptyPlayerCommands_commandReleaseAlwaysIncluded() throws Exception {
MediaSession.Callback callback =
new MediaSession.Callback() {
@Override
public MediaSession.ConnectionResult onConnect(
MediaSession session, ControllerInfo controller) {
return new AcceptedResultBuilder(session)
.setAvailablePlayerCommands(Player.Commands.EMPTY)
.build();
}
};
MediaSession session =
sessionTestRule.ensureReleaseAfterTest(
new MediaSession.Builder(context, player)
.setCallback(callback)
.setId("onConnect_emptyPlayerCommands_commandReleaseAlwaysIncluded")
.build());
RemoteMediaController remoteController =
controllerTestRule.createRemoteController(session.getToken());
assertThat(remoteController.getAvailableCommands().size()).isEqualTo(1);
assertThat(remoteController.getAvailableCommands().contains(Player.COMMAND_RELEASE)).isTrue();
}
@Test
public void onPostConnect_afterConnected() throws Exception {
CountDownLatch latch = new CountDownLatch(1);

View file

@ -823,6 +823,12 @@ public class MediaControllerProviderService extends Service {
return bundle;
}
@Override
public Bundle getAvailableCommands(String controllerId) throws RemoteException {
MediaController controller = mediaControllerMap.get(controllerId);
return runOnHandler(controller::getAvailableCommands).toBundle();
}
@Override
public Bundle getItem(String controllerId, String mediaId) throws RemoteException {
MediaBrowser browser = (MediaBrowser) mediaControllerMap.get(controllerId);

View file

@ -34,6 +34,7 @@ import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.Player.RepeatMode;
import androidx.media3.common.Rating;
import androidx.media3.common.TrackSelectionParameters;
@ -362,6 +363,11 @@ public class RemoteMediaController {
return customLayout.build();
}
public Player.Commands getAvailableCommands() throws RemoteException {
Bundle commandsBundle = binder.getAvailableCommands(controllerId);
return Player.Commands.CREATOR.fromBundle(commandsBundle);
}
////////////////////////////////////////////////////////////////////////////////
// Non-public methods
////////////////////////////////////////////////////////////////////////////////