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
This commit is contained in:
parent
7c9fede3ad
commit
bd192c17ca
@ -105,6 +105,7 @@
|
||||
Browse actions of AAOS</a>.
|
||||
* 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
|
||||
|
@ -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.
|
||||
*
|
||||
* <p>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}.
|
||||
*
|
||||
* <p>Note that this value can be used in addition or instead of {@link #iconResId} for consumers
|
||||
* that are capable of loading the {@link Uri}.
|
||||
* <p>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
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user