Align logic to ignore disabled and non-custom buttons in custom layout

The legacy custom layout doesn't support disabled buttons or buttons
with non-custom actions. These are currently filtered out, but in
inconsistent ways:
 - MediaControllerImplBase doesn't filter at all.
 - DefaultNotificationProvider filters before converting
   mediaButtonPreferences, PlayerWrapper filters after the conversion.
 - PlayerWrapper doesn't disable buttons that are unavailable.

To ensure it's consistent, we can add these checks to the existing util
method in CommandButton and also make sure PlayerWrapper disables
unavailable buttons before triggering the util method.

This also means we can simplify some of the tests that rely on the
mediaButtonPreference to customLayout conversion in MediaController.

This change also includes two bug fixes in PlayerWrapper that
became evident in the tests: The extras need to be copied to
avoid modifying a Bundle instance that be used elsewhere and
we need to update the custom layout and potentially the session
extras when the available commands change, as they depend on them.

PiperOrigin-RevId: 704678404
This commit is contained in:
tonihei 2024-12-10 06:10:35 -08:00 committed by Copybara-Service
parent dc21f3add2
commit b34a5b4e5d
6 changed files with 162 additions and 260 deletions

View file

@ -1209,6 +1209,11 @@ public final class CommandButton {
int forwardButtonIndex = C.INDEX_UNSET;
for (int i = 0; i < mediaButtonPreferences.size(); i++) {
CommandButton button = mediaButtonPreferences.get(i);
if (!button.isEnabled
|| button.sessionCommand == null
|| button.sessionCommand.commandCode != SessionCommand.COMMAND_CODE_CUSTOM) {
continue;
}
for (int s = 0; s < button.slots.length(); s++) {
@Slot int slot = button.slots.get(s);
if (slot == SLOT_OVERFLOW) {
@ -1240,6 +1245,11 @@ public final class CommandButton {
}
for (int i = 0; i < mediaButtonPreferences.size(); i++) {
CommandButton button = mediaButtonPreferences.get(i);
if (!button.isEnabled
|| button.sessionCommand == null
|| button.sessionCommand.commandCode != SessionCommand.COMMAND_CODE_CUSTOM) {
continue;
}
if (i != backButtonIndex && i != forwardButtonIndex && button.slots.contains(SLOT_OVERFLOW)) {
customLayout.add(button.copyWithSlots(ImmutableIntArray.of(SLOT_OVERFLOW)));
}

View file

@ -1054,7 +1054,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
boolean commandGetTimelineChanged =
playerWrapper.getAvailablePlayerCommands().contains(Player.COMMAND_GET_TIMELINE)
!= playerCommands.contains(Player.COMMAND_GET_TIMELINE);
playerWrapper.setAvailableCommands(sessionCommands, playerCommands);
boolean extrasChanged = playerWrapper.setAvailableCommands(sessionCommands, playerCommands);
if (extrasChanged) {
sessionLegacyStub.getSessionCompat().setExtras(playerWrapper.getLegacyExtras());
}
if (commandGetTimelineChanged) {
sessionLegacyStub.updateLegacySessionPlaybackStateAndQueue(playerWrapper);
} else {

View file

@ -105,16 +105,40 @@ import java.util.List;
this.mediaButtonPreferences = mediaButtonPreferences;
this.availableSessionCommands = availableSessionCommands;
this.availablePlayerCommands = availablePlayerCommands;
this.legacyExtras = legacyExtras;
this.legacyExtras = new Bundle(legacyExtras);
if (!mediaButtonPreferences.isEmpty()) {
updateCustomLayoutAndLegacyExtrasForMediaButtonPreferences();
}
}
public void setAvailableCommands(
/**
* Sets new available commands for the platform session.
*
* @param availableSessionCommands The {@link SessionCommands}.
* @param availablePlayerCommands The {@link Player.Commands}.
* @return Whether the {@linkplain #getLegacyExtras platform session extras} were updated as a
* result of this change.
*/
public boolean setAvailableCommands(
SessionCommands availableSessionCommands, Commands availablePlayerCommands) {
this.availableSessionCommands = availableSessionCommands;
this.availablePlayerCommands = availablePlayerCommands;
if (mediaButtonPreferences.isEmpty()) {
return false;
}
boolean hadPrevReservation =
legacyExtras.getBoolean(
MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_PREV, /* defaultValue= */ false);
boolean hadNextReservation =
legacyExtras.getBoolean(
MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_NEXT, /* defaultValue= */ false);
updateCustomLayoutAndLegacyExtrasForMediaButtonPreferences();
return (legacyExtras.getBoolean(
MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_PREV, /* defaultValue= */ false)
!= hadPrevReservation)
|| (legacyExtras.getBoolean(
MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_NEXT, /* defaultValue= */ false)
!= hadNextReservation);
}
public SessionCommands getAvailableSessionCommands() {
@ -165,7 +189,7 @@ import java.util.List;
public void setLegacyExtras(Bundle extras) {
checkArgument(!extras.containsKey(EXTRAS_KEY_PLAYBACK_SPEED_COMPAT));
checkArgument(!extras.containsKey(EXTRAS_KEY_MEDIA_ID_COMPAT));
this.legacyExtras = extras;
this.legacyExtras = new Bundle(extras);
if (!mediaButtonPreferences.isEmpty()) {
// Re-calculate custom layout in case we have to set any additional extras.
updateCustomLayoutAndLegacyExtrasForMediaButtonPreferences();
@ -1305,9 +1329,14 @@ import java.util.List;
}
private void updateCustomLayoutAndLegacyExtrasForMediaButtonPreferences() {
ImmutableList<CommandButton> mediaButtonPreferencesWithUnavailableButtonsDisabled =
CommandButton.copyWithUnavailableButtonsDisabled(
mediaButtonPreferences, availableSessionCommands, availablePlayerCommands);
customLayout =
CommandButton.getCustomLayoutFromMediaButtonPreferences(
mediaButtonPreferences, /* backSlotAllowed= */ true, /* forwardSlotAllowed= */ true);
mediaButtonPreferencesWithUnavailableButtonsDisabled,
/* backSlotAllowed= */ true,
/* forwardSlotAllowed= */ true);
legacyExtras.putBoolean(
MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_PREV,
!CommandButton.containsButtonForSlot(customLayout, CommandButton.SLOT_BACK));

View file

@ -549,15 +549,15 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_BACK)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build());
@ -568,11 +568,11 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
@ -583,19 +583,19 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_BACK)
.build(),
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build());
@ -606,15 +606,15 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK)
.build(),
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
@ -626,19 +626,19 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_BACK)
.build(),
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build());
@ -649,15 +649,15 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
@ -668,19 +668,19 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_FORWARD)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build());
@ -691,15 +691,15 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD)
.build(),
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
@ -711,19 +711,19 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_FORWARD)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build());
@ -734,15 +734,15 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
@ -754,23 +754,23 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_FORWARD)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action5", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_CENTRAL, CommandButton.SLOT_BACK)
.build());
@ -781,19 +781,19 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action5", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD)
.build(),
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
@ -805,23 +805,23 @@ public class CommandButtonTest {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_FORWARD)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action3", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_FORWARD_SECONDARY)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_BACK_SECONDARY, CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action5", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_CENTRAL, CommandButton.SLOT_BACK)
.build());
@ -832,20 +832,51 @@ public class CommandButtonTest {
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setSessionCommand(new SessionCommand("action4", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build())
.inOrder();
}
@Test
public void
getCustomLayoutFromMediaButtonPreferences_disabledAndNonCustomCommands_returnsCorrectButtons() {
ImmutableList<CommandButton> mediaButtonPreferences =
ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build(),
new CommandButton.Builder(CommandButton.ICON_BLOCK)
.setSessionCommand(new SessionCommand("action2", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.setEnabled(false)
.build());
ImmutableList<CommandButton> customLayout =
CommandButton.getCustomLayoutFromMediaButtonPreferences(
mediaButtonPreferences, /* backSlotAllowed= */ true, /* forwardSlotAllowed= */ true);
assertThat(customLayout)
.containsExactly(
new CommandButton.Builder(CommandButton.ICON_ALBUM)
.setSessionCommand(new SessionCommand("action1", Bundle.EMPTY))
.setSlots(CommandButton.SLOT_OVERFLOW)
.build());
}
@Test
public void
getMediaButtonPreferencesFromCustomLayout_withPrevAndNextCommands_returnsCorrectSlots() {

View file

@ -116,7 +116,7 @@ public class ConnectionStateTest {
/* customLayout= */ ImmutableList.of(),
/* mediaButtonPreferences= */ ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_HEART_FILLED)
.setPlayerCommand(Player.COMMAND_PREPARE)
.setSessionCommand(new SessionCommand("action", Bundle.EMPTY))
.build()),
/* commandButtonsForMediaItems= */ ImmutableList.of(),
SessionCommands.EMPTY,

View file

@ -1037,13 +1037,7 @@ public class MediaControllerTest {
MediaController controller = controllerTestRule.createController(session.getToken());
assertThat(threadTestRule.getHandler().postAndSync(controller::getCustomLayout))
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(true)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button3.copyWithIsEnabled(false)),
withOverflowSlot(button4.copyWithIsEnabled(true)),
withOverflowSlot(button5.copyWithIsEnabled(false)))
.inOrder();
.containsExactly(button1);
session.cleanUp();
}
@ -1062,36 +1056,10 @@ public class MediaControllerTest {
CommandButton button2 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button2")
.setEnabled(false)
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command2", Bundle.EMPTY))
.build();
CommandButton button3 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button3")
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command3", Bundle.EMPTY))
.build();
CommandButton button4 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button4")
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command4", Bundle.EMPTY))
.build();
CommandButton button5 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button5")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_PLAY_PAUSE)
.setSlots(CommandButton.SLOT_OVERFLOW)
.build();
CommandButton button6 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button6")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_GET_TRACKS)
.build();
setupMediaButtonPreferences(session, ImmutableList.of(button1, button3));
setupMediaButtonPreferences(session, ImmutableList.of(button1, button2));
CountDownLatch latch = new CountDownLatch(2);
AtomicReference<List<CommandButton>> reportedCustomLayout = new AtomicReference<>();
AtomicReference<List<CommandButton>> reportedCustomLayoutChanged = new AtomicReference<>();
@ -1117,30 +1085,16 @@ public class MediaControllerTest {
});
ImmutableList<CommandButton> initialCustomLayoutFromGetter =
threadTestRule.getHandler().postAndSync(controller::getCustomLayout);
session.setMediaButtonPreferences(
ImmutableList.of(button1, button2, button4, button5, button6));
session.setMediaButtonPreferences(ImmutableList.of(button1));
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
ImmutableList<CommandButton> newCustomLayoutFromGetter =
threadTestRule.getHandler().postAndSync(controller::getCustomLayout);
assertThat(initialCustomLayoutFromGetter)
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(true)),
withOverflowSlot(button3.copyWithIsEnabled(false)))
.inOrder();
ImmutableList<CommandButton> expectedNewButtons =
ImmutableList.of(
withOverflowSlot(button1.copyWithIsEnabled(true)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button4.copyWithIsEnabled(false)),
withOverflowSlot(button5.copyWithIsEnabled(true)),
withOverflowSlot(button6.copyWithIsEnabled(false)));
assertThat(newCustomLayoutFromGetter).containsExactlyElementsIn(expectedNewButtons).inOrder();
assertThat(reportedCustomLayout.get()).containsExactlyElementsIn(expectedNewButtons).inOrder();
assertThat(reportedCustomLayoutChanged.get())
.containsExactlyElementsIn(expectedNewButtons)
.inOrder();
assertThat(initialCustomLayoutFromGetter).containsExactly(button1, button2).inOrder();
assertThat(newCustomLayoutFromGetter).containsExactly(button1);
assertThat(reportedCustomLayout.get()).containsExactly(button1);
assertThat(reportedCustomLayoutChanged.get()).containsExactly(button1);
session.cleanUp();
}
@ -1158,24 +1112,10 @@ public class MediaControllerTest {
CommandButton button2 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button2")
.setEnabled(false)
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command2", Bundle.EMPTY))
.build();
CommandButton button3 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button3")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_PLAY_PAUSE)
.setSlots(CommandButton.SLOT_OVERFLOW)
.build();
CommandButton button4 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button4")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_GET_TRACKS)
.build();
setupMediaButtonPreferences(session, ImmutableList.of(button1, button2, button3, button4));
setupMediaButtonPreferences(session, ImmutableList.of(button1, button2));
CountDownLatch latch = new CountDownLatch(2);
List<List<CommandButton>> reportedCustomLayoutChanged = new ArrayList<>();
List<List<CommandButton>> getterCustomLayoutChanged = new ArrayList<>();
@ -1197,103 +1137,18 @@ public class MediaControllerTest {
// Remove commands in custom layout from available commands.
session.setAvailableCommands(SessionCommands.EMPTY, Player.Commands.EMPTY);
// Add one session and player command back.
// Add one session command back.
session.setAvailableCommands(
new SessionCommands.Builder().add(button2.sessionCommand).build(),
new Player.Commands.Builder().add(Player.COMMAND_GET_TRACKS).build());
new SessionCommands.Builder().add(button2.sessionCommand).build(), Player.Commands.EMPTY);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(initialCustomLayout)
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(true)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button3.copyWithIsEnabled(true)),
withOverflowSlot(button4.copyWithIsEnabled(false)));
assertThat(initialCustomLayout).containsExactly(button1, button2);
assertThat(reportedCustomLayoutChanged).hasSize(2);
assertThat(reportedCustomLayoutChanged.get(0))
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(false)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button3.copyWithIsEnabled(false)),
withOverflowSlot(button4.copyWithIsEnabled(false)))
.inOrder();
assertThat(reportedCustomLayoutChanged.get(1))
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(false)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button3.copyWithIsEnabled(false)),
withOverflowSlot(button4.copyWithIsEnabled(true)))
.inOrder();
assertThat(reportedCustomLayoutChanged.get(0)).isEmpty();
assertThat(reportedCustomLayoutChanged.get(1)).containsExactly(button2);
assertThat(getterCustomLayoutChanged).hasSize(2);
assertThat(getterCustomLayoutChanged.get(0))
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(false)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button3.copyWithIsEnabled(false)),
withOverflowSlot(button4.copyWithIsEnabled(false)))
.inOrder();
assertThat(getterCustomLayoutChanged.get(1))
.containsExactly(
withOverflowSlot(button1.copyWithIsEnabled(false)),
withOverflowSlot(button2.copyWithIsEnabled(false)),
withOverflowSlot(button3.copyWithIsEnabled(false)),
withOverflowSlot(button4.copyWithIsEnabled(true)))
.inOrder();
session.cleanUp();
}
@Test
public void
getCustomLayout_setAvailableCommandsOnPlayerAfterSetMediaButtonPreferences_reportsCustomLayoutChanged()
throws Exception {
RemoteMediaSession session = createRemoteMediaSession(TEST_GET_CUSTOM_LAYOUT, null);
CommandButton button =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_PLAY_PAUSE)
.setSlots(CommandButton.SLOT_OVERFLOW)
.build();
setupMediaButtonPreferences(session, ImmutableList.of(button));
CountDownLatch latch = new CountDownLatch(2);
List<List<CommandButton>> reportedCustomLayouts = new ArrayList<>();
List<List<CommandButton>> getterCustomLayouts = new ArrayList<>();
MediaController.Listener listener =
new MediaController.Listener() {
@Override
public void onCustomLayoutChanged(
MediaController controller, List<CommandButton> layout) {
reportedCustomLayouts.add(layout);
getterCustomLayouts.add(controller.getCustomLayout());
latch.countDown();
}
};
MediaController controller =
controllerTestRule.createController(
session.getToken(), /* connectionHints= */ Bundle.EMPTY, listener);
ImmutableList<CommandButton> initialCustomLayout =
threadTestRule.getHandler().postAndSync(controller::getCustomLayout);
// Disable player command and then add it back.
session.getMockPlayer().notifyAvailableCommandsChanged(Player.Commands.EMPTY);
session
.getMockPlayer()
.notifyAvailableCommandsChanged(
new Player.Commands.Builder().add(Player.COMMAND_PLAY_PAUSE).build());
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(initialCustomLayout)
.containsExactly(withOverflowSlot(button.copyWithIsEnabled(true)));
assertThat(reportedCustomLayouts).hasSize(2);
assertThat(reportedCustomLayouts.get(0))
.containsExactly(withOverflowSlot(button.copyWithIsEnabled(false)));
assertThat(reportedCustomLayouts.get(1))
.containsExactly(withOverflowSlot(button.copyWithIsEnabled(true)));
assertThat(getterCustomLayouts).hasSize(2);
assertThat(getterCustomLayouts.get(0))
.containsExactly(withOverflowSlot(button.copyWithIsEnabled(false)));
assertThat(getterCustomLayouts.get(1))
.containsExactly(withOverflowSlot(button.copyWithIsEnabled(true)));
assertThat(getterCustomLayoutChanged.get(0)).isEmpty();
assertThat(getterCustomLayoutChanged.get(1)).containsExactly(button2);
session.cleanUp();
}
@ -1309,27 +1164,20 @@ public class MediaControllerTest {
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command1", Bundle.EMPTY))
.build();
CommandButton buttonIgnored =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button2")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_PLAY_PAUSE)
.build();
CommandButton button2 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button2")
.setEnabled(false)
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command2", Bundle.EMPTY))
.build();
CommandButton button3 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button3")
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command3", Bundle.EMPTY))
.build();
CommandButton button4 =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button4")
.setIconResId(R.drawable.media3_notification_small_icon)
.setSessionCommand(new SessionCommand("command4", Bundle.EMPTY))
.build();
setupMediaButtonPreferences(session, ImmutableList.of(button1, button2));
CountDownLatch latch = new CountDownLatch(5);
CountDownLatch latch = new CountDownLatch(3);
List<List<CommandButton>> reportedCustomLayout = new ArrayList<>();
List<List<CommandButton>> getterCustomLayout = new ArrayList<>();
List<List<CommandButton>> reportedCustomLayoutChanged = new ArrayList<>();
@ -1359,38 +1207,17 @@ public class MediaControllerTest {
threadTestRule.getHandler().postAndSync(controller::getCustomLayout);
// First call does not trigger onCustomLayoutChanged.
session.setMediaButtonPreferences(ImmutableList.of(button1, button2));
session.setMediaButtonPreferences(ImmutableList.of(button3, button4));
session.setMediaButtonPreferences(ImmutableList.of(button1, button2));
session.setMediaButtonPreferences(ImmutableList.of(button1, buttonIgnored, button2));
session.setMediaButtonPreferences(ImmutableList.of(button2));
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
CommandButton button1Enabled = withOverflowSlot(button1.copyWithIsEnabled(true));
CommandButton button2Disabled = withOverflowSlot(button2.copyWithIsEnabled(false));
CommandButton button3Disabled = withOverflowSlot(button3.copyWithIsEnabled(false));
CommandButton button4Disabled = withOverflowSlot(button4.copyWithIsEnabled(false));
assertThat(initialCustomLayout).containsExactly(button1Enabled, button2Disabled).inOrder();
assertThat(initialCustomLayout).containsExactly(button1, button2).inOrder();
assertThat(reportedCustomLayout)
.containsExactly(
ImmutableList.of(button1Enabled, button2Disabled),
ImmutableList.of(button3Disabled, button4Disabled),
ImmutableList.of(button1Enabled, button2Disabled))
.inOrder();
.containsExactly(ImmutableList.of(button1, button2), ImmutableList.of(button2));
assertThat(getterCustomLayout)
.containsExactly(
ImmutableList.of(button1Enabled, button2Disabled),
ImmutableList.of(button3Disabled, button4Disabled),
ImmutableList.of(button1Enabled, button2Disabled))
.inOrder();
assertThat(reportedCustomLayoutChanged)
.containsExactly(
ImmutableList.of(button3Disabled, button4Disabled),
ImmutableList.of(button1Enabled, button2Disabled))
.inOrder();
assertThat(getterCustomLayoutChanged)
.containsExactly(
ImmutableList.of(button3Disabled, button4Disabled),
ImmutableList.of(button1Enabled, button2Disabled))
.inOrder();
.containsExactly(ImmutableList.of(button1, button2), ImmutableList.of(button2));
assertThat(reportedCustomLayoutChanged).containsExactly(ImmutableList.of(button2));
assertThat(getterCustomLayoutChanged).containsExactly(ImmutableList.of(button2));
session.cleanUp();
}
@ -1456,7 +1283,8 @@ public class MediaControllerTest {
withBackSlot(button2), withForwardSlot(button1), withOverflowSlot(button3)),
ImmutableList.of(withBackSlot(button2), withOverflowSlot(button3)),
ImmutableList.of(withForwardSlot(button1), withOverflowSlot(button3)),
ImmutableList.of(withOverflowSlot(button3)));
ImmutableList.of(withOverflowSlot(button3)))
.inOrder();
session.cleanUp();
}
@ -1526,7 +1354,8 @@ public class MediaControllerTest {
withBackSlot(button2), withForwardSlot(button1), withOverflowSlot(button3)),
ImmutableList.of(withBackSlot(button2), withOverflowSlot(button3)),
ImmutableList.of(withForwardSlot(button1), withOverflowSlot(button3)),
ImmutableList.of(withOverflowSlot(button3)));
ImmutableList.of(withOverflowSlot(button3)))
.inOrder();
session.cleanUp();
}