From ab904bde2d9ec55699ddfb0e9ad53f51172c7c14 Mon Sep 17 00:00:00 2001 From: siroberts Date: Wed, 12 Jul 2023 15:22:11 +0100 Subject: [PATCH] Prevent the creation of CommandButtons without commands. The setPlayerCommand and setSessionCommand builder methods contain assertions to ensure that at most one of these fields is set, but this left it possible to create a command button with no command by calling build on an empty builder. PiperOrigin-RevId: 547488248 --- .../java/androidx/media3/session/CommandButton.java | 10 +++++++--- .../androidx/media3/session/CommandButtonTest.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libraries/session/src/main/java/androidx/media3/session/CommandButton.java b/libraries/session/src/main/java/androidx/media3/session/CommandButton.java index 86d9c176cb..cecf79a8bc 100644 --- a/libraries/session/src/main/java/androidx/media3/session/CommandButton.java +++ b/libraries/session/src/main/java/androidx/media3/session/CommandButton.java @@ -17,6 +17,7 @@ package androidx.media3.session; import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkNotNull; +import static androidx.media3.common.util.Assertions.checkState; import android.os.Bundle; import android.text.TextUtils; @@ -147,17 +148,20 @@ public final class CommandButton implements Bundleable { /** Builds a {@link CommandButton}. */ public CommandButton build() { + checkState( + (sessionCommand == null) != (playerCommand == Player.COMMAND_INVALID), + "Exactly one of sessionCommand and playerCommand should be set"); return new CommandButton( sessionCommand, playerCommand, iconResId, displayName, extras, enabled); } } - /** The session command of the button. Can be {@code null} if the button is a placeholder. */ + /** The session command of the button. Will be {@code null} if {@link #playerCommand} is set. */ @Nullable public final SessionCommand sessionCommand; /** - * The {@link Player.Command} command of the button. Can be {@link Player#COMMAND_INVALID} if the - * button is a placeholder. + * The {@link Player.Command} command of the button. Will be {@link Player#COMMAND_INVALID} if + * {@link #sessionCommand} is set. */ public final @Player.Command int playerCommand; diff --git a/libraries/session/src/test/java/androidx/media3/session/CommandButtonTest.java b/libraries/session/src/test/java/androidx/media3/session/CommandButtonTest.java index 05a2ff5095..b1e7c1f0d5 100644 --- a/libraries/session/src/test/java/androidx/media3/session/CommandButtonTest.java +++ b/libraries/session/src/test/java/androidx/media3/session/CommandButtonTest.java @@ -17,6 +17,7 @@ package androidx.media3.session; import static androidx.media3.session.CommandButton.CREATOR; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import android.os.Bundle; import androidx.media3.common.Player; @@ -199,4 +200,13 @@ public class CommandButtonTest { .build() .hashCode()); } + + @Test + public void build_withoutSessionOrPlayerCommandSet_throwsIllegalStateException() { + CommandButton.Builder builder = + new CommandButton.Builder() + .setDisplayName("button") + .setIconResId(R.drawable.media3_notification_small_icon); + assertThrows(IllegalStateException.class, builder::build); + } }