diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 1d55ba060a..7b76789739 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -105,6 +105,7 @@ Browse actions of AAOS. * Fix bug where a Media3 controller was sometimes unable to let a session app start a foreground service after requesting `play()`. + * Restrict `CommandButton.Builder.setIconUri` to only accept content Uris. * UI: * Make the stretched/cropped video in `PlayerView`-in-Compose-`AndroidView` workaround opt-in, due to issues 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 4e0bce85a9..aa58a5bbb6 100644 --- a/libraries/session/src/main/java/androidx/media3/session/CommandButton.java +++ b/libraries/session/src/main/java/androidx/media3/session/CommandButton.java @@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkState; import static java.lang.annotation.ElementType.TYPE_USE; +import android.content.ContentResolver; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; @@ -424,8 +425,8 @@ public final class CommandButton { /** * [will be deprecated] Use {@link #Builder(int)} instead to define the {@link Icon} for this - * button. A separate resource id via {@link #setIconResId(int)} or {@link #setIconUri} is no - * longer required unless for {@link #ICON_UNDEFINED}. + * button. A separate resource id via {@link #setIconResId(int)} is no longer required unless + * for {@link #ICON_UNDEFINED}. */ public Builder() { this(ICON_UNDEFINED); @@ -519,11 +520,11 @@ public final class CommandButton { } /** - * Sets a {@link Uri} for the icon of this button. + * Sets a content {@link Uri} for the icon of this button. * *
Note that this {@link Uri} may be used when the predefined {@link Icon} is not available - * or set to {@link #ICON_UNDEFINED}. It can be used in addition or instead of {@link - * #setCustomIconResId} for consumers that are capable of loading the {@link Uri}. + * or set to {@link #ICON_UNDEFINED}. It can be used in addition to {@link #setCustomIconResId} + * for consumers that are capable of loading the content {@link Uri}. * * @param uri The uri to an icon. * @return This builder for chaining. @@ -531,6 +532,9 @@ public final class CommandButton { @UnstableApi @CanIgnoreReturnValue public Builder setIconUri(Uri uri) { + checkArgument( + Objects.equal(uri.getScheme(), ContentResolver.SCHEME_CONTENT), + "Only content Uris are supported for CommandButton"); this.iconUri = uri; return this; } @@ -606,11 +610,11 @@ public final class CommandButton { @DrawableRes public final int iconResId; /** - * The {@link Uri} for the icon of the button that is used when the predefined {@link #icon} is - * not available or set to {@link #ICON_UNDEFINED}. Can be {@code null}. + * The content {@link Uri} for the icon of the button that is used when the predefined {@link + * #icon} is not available or set to {@link #ICON_UNDEFINED}. Can be {@code null}. * - *
Note that this value can be used in addition or instead of {@link #iconResId} for consumers - * that are capable of loading the {@link Uri}. + *
Note that this value can be used in addition to {@link #iconResId} for consumers that are + * capable of loading the content {@link Uri}. */ @UnstableApi @Nullable public final Uri iconUri; @@ -809,7 +813,7 @@ public final class CommandButton { if (playerCommand != Player.COMMAND_INVALID) { builder.setPlayerCommand(playerCommand); } - if (iconUri != null) { + if (iconUri != null && Objects.equal(iconUri.getScheme(), ContentResolver.SCHEME_CONTENT)) { builder.setIconUri(iconUri); } return builder 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 a973112dfe..c37dc10653 100644 --- a/libraries/session/src/test/java/androidx/media3/session/CommandButtonTest.java +++ b/libraries/session/src/test/java/androidx/media3/session/CommandButtonTest.java @@ -364,7 +364,7 @@ public class CommandButtonTest { .setDisplayName("name") .setEnabled(true) .setIconResId(R.drawable.media3_notification_small_icon) - .setIconUri(Uri.parse("http://test.test")) + .setIconUri(Uri.parse("content://test")) .setExtras(extras) .setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING)) .build(); @@ -373,7 +373,7 @@ public class CommandButtonTest { .setDisplayName("name") .setEnabled(true) .setIconResId(R.drawable.media3_notification_small_icon) - .setIconUri(Uri.parse("http://test.test")) + .setIconUri(Uri.parse("content://test")) .setExtras(extras) .setPlayerCommand(Player.COMMAND_GET_METADATA) .build(); diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java index 41b1b3f47a..83fa6e58ef 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java @@ -145,7 +145,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest .getString( androidx.media3.session.legacy.MediaConstants .EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI)) - .isEqualTo("http://www.example.com/icon/playlist_add"); + .isEqualTo("content://playlist_add"); assertThat( mediaItemCommandButtons .get(0) @@ -174,7 +174,7 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest .getString( androidx.media3.session.legacy.MediaConstants .EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI)) - .isEqualTo("http://www.example.com/icon/radio"); + .isEqualTo("content://radio"); assertThat( mediaItemCommandButtons .get(1) 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 fe1297c83c..6294fd1e6b 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 @@ -142,14 +142,14 @@ public class MediaBrowserListenerWithMediaBrowserServiceCompatTest { CommandButton playlistAddButton = new CommandButton.Builder() .setDisplayName("Add to playlist") - .setIconUri(Uri.parse("https://www.example.com/icon/playlist_add")) + .setIconUri(Uri.parse("content://playlist_add")) .setSessionCommand( new SessionCommand(MediaBrowserConstants.COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .build(); CommandButton radioButton = new CommandButton.Builder() .setDisplayName("Radio station") - .setIconUri(Uri.parse("https://www.example.com/icon/radio")) + .setIconUri(Uri.parse("content://radio")) .setSessionCommand( new SessionCommand(MediaBrowserConstants.COMMAND_RADIO, Bundle.EMPTY)) .build(); @@ -192,7 +192,7 @@ public class MediaBrowserListenerWithMediaBrowserServiceCompatTest { CommandButton playlistAddButton = new CommandButton.Builder() .setDisplayName("Add to playlist") - .setIconUri(Uri.parse("https://www.example.com/icon/playlist_add")) + .setIconUri(Uri.parse("content://playlist_add")) .setSessionCommand( new SessionCommand(MediaBrowserConstants.COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .build(); 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 092d5be93c..94e2d5bfeb 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 @@ -364,7 +364,7 @@ public class MockMediaBrowserServiceCompat extends MediaBrowserServiceCompat { "Add to playlist"); playlistAddBrowseAction.putString( androidx.media3.session.legacy.MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, - "https://www.example.com/icon/playlist_add"); + "content://playlist_add"); playlistAddBrowseAction.putBundle( androidx.media3.session.legacy.MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_EXTRAS, playlistAddExtras); @@ -379,7 +379,7 @@ public class MockMediaBrowserServiceCompat extends MediaBrowserServiceCompat { "Radio station"); radioBrowseAction.putString( androidx.media3.session.legacy.MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, - "https://www.example.com/icon/radio"); + "content://radio"); radioBrowseAction.putBundle( androidx.media3.session.legacy.MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_EXTRAS, radioExtras); diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java index 4c60d9a36b..14f80db5c4 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java @@ -238,7 +238,7 @@ public class MockMediaLibraryService extends MediaLibraryService { ImmutableList.of( new CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName("Add to playlist") - .setIconUri(Uri.parse("http://www.example.com/icon/playlist_add")) + .setIconUri(Uri.parse("content://playlist_add")) .setSessionCommand( new SessionCommand( MediaBrowserConstants.COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) @@ -246,7 +246,7 @@ public class MockMediaLibraryService extends MediaLibraryService { .build(), new CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName("Radio station") - .setIconUri(Uri.parse("http://www.example.com/icon/radio")) + .setIconUri(Uri.parse("content://radio")) .setSessionCommand( new SessionCommand(MediaBrowserConstants.COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras)