Add slots to CommandButton

These allow to define preferences for where a button should be
displayed.

PiperOrigin-RevId: 686938126
This commit is contained in:
tonihei 2024-10-17 09:14:07 -07:00 committed by Copybara-Service
parent 8cb558e875
commit e851a1419d
2 changed files with 304 additions and 7 deletions

View File

@ -32,6 +32,7 @@ import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.primitives.ImmutableIntArray;
import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.CheckReturnValue; import com.google.errorprone.annotations.CheckReturnValue;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
@ -411,17 +412,68 @@ public final class CommandButton {
*/ */
@UnstableApi public static final int ICON_FEED = 0xe0e5; @UnstableApi public static final int ICON_FEED = 0xe0e5;
// TODO: b/332877990 - Stabilize these constants and other slot APIs
/**
* A slot at which a button can be displayed in a UI surface. Must be one of the {@code
* CommandButton.SLOT_} constants.
*/
@UnstableApi
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@IntDef({
SLOT_CENTRAL,
SLOT_BACK,
SLOT_FORWARD,
SLOT_BACK_SECONDARY,
SLOT_FORWARD_SECONDARY,
SLOT_OVERFLOW
})
public @interface Slot {}
/** A central slot in a playback control UI, most commonly used for play or pause actions. */
@UnstableApi public static final int SLOT_CENTRAL = 1;
/**
* A slot in a playback control UI for backward-directed playback actions, most commonly used for
* previous or rewind actions.
*/
@UnstableApi public static final int SLOT_BACK = 2;
/**
* A slot in a playback control UI for forward-directed playback actions, most commonly used for
* next or fast-forward actions.
*/
@UnstableApi public static final int SLOT_FORWARD = 3;
/**
* A slot in a playback control UI for secondary backward-directed playback actions, most commonly
* used for previous or rewind actions.
*/
@UnstableApi public static final int SLOT_BACK_SECONDARY = 4;
/**
* A slot in a playback control UI for secondary forward-directed playback actions, most commonly
* used for next or fast-forward actions.
*/
@UnstableApi public static final int SLOT_FORWARD_SECONDARY = 5;
/** A slot in a playback control UI for additional actions that don't fit into other slots. */
@UnstableApi public static final int SLOT_OVERFLOW = 6;
/** A builder for {@link CommandButton}. */ /** A builder for {@link CommandButton}. */
public static final class Builder { public static final class Builder {
private final @Icon int icon;
@Nullable private SessionCommand sessionCommand; @Nullable private SessionCommand sessionCommand;
private @Player.Command int playerCommand; private @Player.Command int playerCommand;
private @Icon int icon;
@DrawableRes private int iconResId; @DrawableRes private int iconResId;
@Nullable private Uri iconUri; @Nullable private Uri iconUri;
private CharSequence displayName; private CharSequence displayName;
private Bundle extras; private Bundle extras;
private boolean enabled; private boolean enabled;
@Nullable private ImmutableIntArray slots;
/** /**
* [will be deprecated] Use {@link #Builder(int)} instead to define the {@link Icon} for this * [will be deprecated] Use {@link #Builder(int)} instead to define the {@link Icon} for this
@ -451,7 +503,6 @@ public final class CommandButton {
displayName = ""; displayName = "";
extras = Bundle.EMPTY; extras = Bundle.EMPTY;
playerCommand = Player.COMMAND_INVALID; playerCommand = Player.COMMAND_INVALID;
icon = ICON_UNDEFINED;
enabled = true; enabled = true;
} }
@ -581,13 +632,63 @@ public final class CommandButton {
return this; return this;
} }
/**
* Sets the allowed {@link Slot} positions for this button.
*
* <p>The button is only allowed in the defined slots. If none of the slots can display the
* button, either because the slots do not exist, are already occupied or the UI surface does
* not allow the specific type of button in these slots, the button will not be displayed at
* all.
*
* <p>When multiple slots are provided, they define a preference order. The button will be
* placed in the first slot in the list that exists, isn't already occupied and that allows this
* type of button.
*
* <p>When not specified, the default value depends on the associated {@link #setPlayerCommand
* player command} and the {@link Icon} set in the constructor:
*
* <ul>
* <li>{@link Player#COMMAND_PLAY_PAUSE} and/or {@link #ICON_PLAY}, {@link #ICON_PAUSE}:
* {@link #SLOT_CENTRAL}
* <li>{@link Player#COMMAND_SEEK_TO_PREVIOUS}, {@link
* Player#COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM}, {@link Player#COMMAND_SEEK_BACK} and/or
* {@link #ICON_PREVIOUS}, {@link #ICON_SKIP_BACK}, {@link #ICON_REWIND}: {@link
* #SLOT_BACK}
* <li>{@link Player#COMMAND_SEEK_TO_NEXT}, {@link Player#COMMAND_SEEK_TO_NEXT_MEDIA_ITEM},
* {@link Player#COMMAND_SEEK_FORWARD} and/or {@link #ICON_NEXT}, {@link
* #ICON_SKIP_FORWARD}, {@link #ICON_FAST_FORWARD}: {@link #SLOT_FORWARD}
* <li>Anything else: {@link #SLOT_OVERFLOW}
* </ul>
*
* @param slots The list of allowed {@link Slot} positions. Must not be empty.
* @return This builder for chaining.
*/
@UnstableApi
@CanIgnoreReturnValue
public Builder setSlots(@Slot int... slots) {
checkArgument(slots.length != 0);
this.slots = ImmutableIntArray.copyOf(slots);
return this;
}
/** Builds a {@link CommandButton}. */ /** Builds a {@link CommandButton}. */
public CommandButton build() { public CommandButton build() {
checkState( checkState(
(sessionCommand == null) != (playerCommand == Player.COMMAND_INVALID), (sessionCommand == null) != (playerCommand == Player.COMMAND_INVALID),
"Exactly one of sessionCommand and playerCommand should be set"); "Exactly one of sessionCommand and playerCommand should be set");
if (slots == null) {
slots = ImmutableIntArray.of(getDefaultSlot(playerCommand, icon));
}
return new CommandButton( return new CommandButton(
sessionCommand, playerCommand, icon, iconResId, iconUri, displayName, extras, enabled); sessionCommand,
playerCommand,
icon,
iconResId,
iconUri,
displayName,
extras,
enabled,
slots);
} }
} }
@ -630,6 +731,19 @@ public final class CommandButton {
*/ */
@UnstableApi public final Bundle extras; @UnstableApi public final Bundle extras;
/**
* The allowed {@link Slot} positions for this button.
*
* <p>The button is only allowed in the defined slots. If none of the slots can display the
* button, either because the slots do not exist, are already occupied or the UI surface does not
* allow the specific type of button in these slots, the button will not be displayed at all.
*
* <p>When multiple slots are provided, they define a preference order. The button will be placed
* in the first slot in the list that exists, isn't already occupied and that allows this type of
* button.
*/
@UnstableApi public final ImmutableIntArray slots;
/** /**
* Whether the button is enabled. * Whether the button is enabled.
* *
@ -647,7 +761,8 @@ public final class CommandButton {
@Nullable Uri iconUri, @Nullable Uri iconUri,
CharSequence displayName, CharSequence displayName,
Bundle extras, Bundle extras,
boolean enabled) { boolean enabled,
ImmutableIntArray slots) {
this.sessionCommand = sessionCommand; this.sessionCommand = sessionCommand;
this.playerCommand = playerCommand; this.playerCommand = playerCommand;
this.icon = icon; this.icon = icon;
@ -656,6 +771,7 @@ public final class CommandButton {
this.displayName = displayName; this.displayName = displayName;
this.extras = new Bundle(extras); this.extras = new Bundle(extras);
this.isEnabled = enabled; this.isEnabled = enabled;
this.slots = slots;
} }
/** Returns a copy with the new {@link #isEnabled} flag. */ /** Returns a copy with the new {@link #isEnabled} flag. */
@ -675,7 +791,8 @@ public final class CommandButton {
iconUri, iconUri,
displayName, displayName,
new Bundle(extras), new Bundle(extras),
isEnabled); isEnabled,
slots);
} }
/** Checks the given command button for equality while ignoring {@link #extras}. */ /** Checks the given command button for equality while ignoring {@link #extras}. */
@ -694,13 +811,14 @@ public final class CommandButton {
&& iconResId == button.iconResId && iconResId == button.iconResId
&& Objects.equal(iconUri, button.iconUri) && Objects.equal(iconUri, button.iconUri)
&& TextUtils.equals(displayName, button.displayName) && TextUtils.equals(displayName, button.displayName)
&& isEnabled == button.isEnabled; && isEnabled == button.isEnabled
&& slots.equals(button.slots);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode( return Objects.hashCode(
sessionCommand, playerCommand, icon, iconResId, displayName, isEnabled, iconUri); sessionCommand, playerCommand, icon, iconResId, displayName, isEnabled, iconUri, slots);
} }
/** /**
@ -747,6 +865,7 @@ public final class CommandButton {
private static final String FIELD_ENABLED = Util.intToStringMaxRadix(5); private static final String FIELD_ENABLED = Util.intToStringMaxRadix(5);
private static final String FIELD_ICON_URI = Util.intToStringMaxRadix(6); private static final String FIELD_ICON_URI = Util.intToStringMaxRadix(6);
private static final String FIELD_ICON = Util.intToStringMaxRadix(7); private static final String FIELD_ICON = Util.intToStringMaxRadix(7);
private static final String FIELD_SLOTS = Util.intToStringMaxRadix(8);
@UnstableApi @UnstableApi
public Bundle toBundle() { public Bundle toBundle() {
@ -775,6 +894,9 @@ public final class CommandButton {
if (!isEnabled) { if (!isEnabled) {
bundle.putBoolean(FIELD_ENABLED, isEnabled); bundle.putBoolean(FIELD_ENABLED, isEnabled);
} }
if (slots.length() != 1 || slots.get(0) != SLOT_OVERFLOW) {
bundle.putIntArray(FIELD_SLOTS, slots.toArray());
}
return bundle; return bundle;
} }
@ -806,6 +928,9 @@ public final class CommandButton {
sessionInterfaceVersion < 3 || bundle.getBoolean(FIELD_ENABLED, /* defaultValue= */ true); sessionInterfaceVersion < 3 || bundle.getBoolean(FIELD_ENABLED, /* defaultValue= */ true);
@Nullable Uri iconUri = bundle.getParcelable(FIELD_ICON_URI); @Nullable Uri iconUri = bundle.getParcelable(FIELD_ICON_URI);
@Icon int icon = bundle.getInt(FIELD_ICON, /* defaultValue= */ ICON_UNDEFINED); @Icon int icon = bundle.getInt(FIELD_ICON, /* defaultValue= */ ICON_UNDEFINED);
@Nullable
@Slot
int[] slots = bundle.getIntArray(FIELD_SLOTS);
Builder builder = new Builder(icon, iconResId); Builder builder = new Builder(icon, iconResId);
if (sessionCommand != null) { if (sessionCommand != null) {
builder.setSessionCommand(sessionCommand); builder.setSessionCommand(sessionCommand);
@ -820,6 +945,7 @@ public final class CommandButton {
.setDisplayName(displayName) .setDisplayName(displayName)
.setExtras(extras == null ? Bundle.EMPTY : extras) .setExtras(extras == null ? Bundle.EMPTY : extras)
.setEnabled(enabled) .setEnabled(enabled)
.setSlots(slots == null ? new int[] {SLOT_OVERFLOW} : slots)
.build(); .build();
} }
@ -983,4 +1109,42 @@ public final class CommandButton {
return 0; return 0;
} }
} }
/**
* Returns the default {@link Slot} for a button.
*
* @param playerCommand The {@link Player.Command} associated with this button.
* @param icon The {@link Icon} of this button.
* @return The default {@link Slot} for this button.
*/
@UnstableApi
public static @Slot int getDefaultSlot(@Player.Command int playerCommand, @Icon int icon) {
if (playerCommand == Player.COMMAND_PLAY_PAUSE || icon == ICON_PLAY || icon == ICON_PAUSE) {
return SLOT_CENTRAL;
} else if (playerCommand == Player.COMMAND_SEEK_BACK
|| playerCommand == Player.COMMAND_SEEK_TO_PREVIOUS
|| playerCommand == Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM
|| icon == ICON_PREVIOUS
|| icon == ICON_REWIND
|| icon == ICON_SKIP_BACK
|| icon == ICON_SKIP_BACK_5
|| icon == ICON_SKIP_BACK_10
|| icon == ICON_SKIP_BACK_15
|| icon == ICON_SKIP_BACK_30) {
return SLOT_BACK;
} else if (playerCommand == Player.COMMAND_SEEK_FORWARD
|| playerCommand == Player.COMMAND_SEEK_TO_NEXT
|| playerCommand == Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
|| icon == ICON_NEXT
|| icon == ICON_FAST_FORWARD
|| icon == ICON_SKIP_FORWARD
|| icon == ICON_SKIP_FORWARD_5
|| icon == ICON_SKIP_FORWARD_10
|| icon == ICON_SKIP_FORWARD_15
|| icon == ICON_SKIP_FORWARD_30) {
return SLOT_FORWARD;
} else {
return SLOT_OVERFLOW;
}
}
} }

View File

@ -23,6 +23,7 @@ import android.os.Bundle;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.primitives.ImmutableIntArray;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -172,6 +173,7 @@ public class CommandButtonTest {
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setIconUri(Uri.parse("content://test")) .setIconUri(Uri.parse("content://test"))
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_FORWARD, CommandButton.SLOT_CENTRAL)
.build()) .build())
.isEqualTo( .isEqualTo(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED) new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
@ -179,6 +181,7 @@ public class CommandButtonTest {
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setIconUri(Uri.parse("content://test")) .setIconUri(Uri.parse("content://test"))
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_FORWARD, CommandButton.SLOT_CENTRAL)
.build()); .build());
} }
@ -189,6 +192,7 @@ public class CommandButtonTest {
.setDisplayName("button") .setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_BACK)
.build(); .build();
assertThat(button) assertThat(button)
@ -199,6 +203,7 @@ public class CommandButtonTest {
.setDisplayName("button2") .setDisplayName("button2")
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_BACK)
.build()); .build());
assertThat(button) assertThat(button)
.isNotEqualTo( .isNotEqualTo(
@ -206,6 +211,7 @@ public class CommandButtonTest {
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS) .setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.setDisplayName("button") .setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setSlots(CommandButton.SLOT_BACK)
.build()); .build());
assertThat(button) assertThat(button)
.isNotEqualTo( .isNotEqualTo(
@ -213,6 +219,7 @@ public class CommandButtonTest {
.setIconResId(R.drawable.media3_icon_play) .setIconResId(R.drawable.media3_icon_play)
.setDisplayName("button") .setDisplayName("button")
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_BACK)
.build()); .build());
assertThat(button) assertThat(button)
.isNotEqualTo( .isNotEqualTo(
@ -221,6 +228,7 @@ public class CommandButtonTest {
.setDisplayName("button") .setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_BACK)
.build()); .build());
assertThat(button) assertThat(button)
.isNotEqualTo( .isNotEqualTo(
@ -228,6 +236,7 @@ public class CommandButtonTest {
.setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_LIBRARY_GET_ITEM)) .setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_LIBRARY_GET_ITEM))
.setDisplayName("button") .setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setSlots(CommandButton.SLOT_BACK)
.build()); .build());
assertThat(button) assertThat(button)
.isNotEqualTo( .isNotEqualTo(
@ -236,6 +245,7 @@ public class CommandButtonTest {
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setIconUri(Uri.parse("content://test")) .setIconUri(Uri.parse("content://test"))
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_BACK)
.build()); .build());
assertThat(button) assertThat(button)
.isNotEqualTo( .isNotEqualTo(
@ -243,6 +253,15 @@ public class CommandButtonTest {
.setDisplayName("button") .setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon) .setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT) .setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_BACK)
.build());
assertThat(button)
.isNotEqualTo(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setDisplayName("button")
.setIconResId(R.drawable.media3_notification_small_icon)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.setSlots(CommandButton.SLOT_FORWARD)
.build()); .build());
} }
@ -355,6 +374,118 @@ public class CommandButtonTest {
assertThrows(IllegalStateException.class, builder::build); assertThrows(IllegalStateException.class, builder::build);
} }
@Test
public void build_withoutSlots_assignsDefaultSlots() {
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_PLAY_PAUSE)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_CENTRAL));
assertThat(
new CommandButton.Builder(CommandButton.ICON_PLAY)
.setPlayerCommand(Player.COMMAND_PREPARE)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_CENTRAL));
assertThat(
new CommandButton.Builder(CommandButton.ICON_PAUSE)
.setPlayerCommand(Player.COMMAND_STOP)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_CENTRAL));
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_SEEK_BACK)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_PREVIOUS)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_SKIP_BACK)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_SKIP_BACK_10)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_REWIND)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_BACK));
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_SEEK_FORWARD)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_UNDEFINED)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_NEXT)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_SKIP_FORWARD)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_SKIP_FORWARD_10)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_FAST_FORWARD)
.setPlayerCommand(Player.COMMAND_SEEK_TO_MEDIA_ITEM)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_FORWARD));
assertThat(
new CommandButton.Builder(CommandButton.ICON_SHUFFLE_ON)
.setPlayerCommand(Player.COMMAND_SET_SHUFFLE_MODE)
.build()
.slots)
.isEqualTo(ImmutableIntArray.of(CommandButton.SLOT_OVERFLOW));
}
@Test @Test
public void fromBundle_afterToBundle_returnsEqualInstance() { public void fromBundle_afterToBundle_returnsEqualInstance() {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
@ -367,6 +498,7 @@ public class CommandButtonTest {
.setIconUri(Uri.parse("content://test")) .setIconUri(Uri.parse("content://test"))
.setExtras(extras) .setExtras(extras)
.setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING)) .setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING))
.setSlots(CommandButton.SLOT_OVERFLOW, CommandButton.SLOT_BACK)
.build(); .build();
CommandButton buttonWithPlayerCommand = CommandButton buttonWithPlayerCommand =
new CommandButton.Builder(CommandButton.ICON_CLOSED_CAPTIONS) new CommandButton.Builder(CommandButton.ICON_CLOSED_CAPTIONS)
@ -376,6 +508,7 @@ public class CommandButtonTest {
.setIconUri(Uri.parse("content://test")) .setIconUri(Uri.parse("content://test"))
.setExtras(extras) .setExtras(extras)
.setPlayerCommand(Player.COMMAND_GET_METADATA) .setPlayerCommand(Player.COMMAND_GET_METADATA)
.setSlots(CommandButton.SLOT_CENTRAL)
.build(); .build();
CommandButton buttonWithDefaultValues = CommandButton buttonWithDefaultValues =
new CommandButton.Builder(CommandButton.ICON_UNDEFINED) new CommandButton.Builder(CommandButton.ICON_UNDEFINED)