From bd192c17caa93294d1bcd0855736a904bd9ce452 Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 8 Oct 2024 02:51:37 -0700 Subject: [PATCH] Restrict CommandButton.iconUri to content Uris These Uris are not widely supported yet and were only meant to be used with content Uris. Restricting this more tightly allows controllers to use these Uris more easily as they have a stricter guarentee on what it's needed to load these Uris. Media session apps with different types of Uris can convert them by setting up a ContentProvider if needed. Issue: androidx/media#1783 PiperOrigin-RevId: 683539747 --- RELEASENOTES.md | 1 + .../media3/session/CommandButton.java | 24 +++++++++++-------- .../media3/session/CommandButtonTest.java | 4 ++-- ...wserCompatWithMediaLibraryServiceTest.java | 4 ++-- ...enerWithMediaBrowserServiceCompatTest.java | 6 ++--- .../MockMediaBrowserServiceCompat.java | 4 ++-- .../session/MockMediaLibraryService.java | 4 ++-- 7 files changed, 26 insertions(+), 21 deletions(-) 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)