Commit e2ece2f5 by tonihei Committed by christosts

Add missing command checks in UI module

The commands are partly checked already before enabling
features or calling player methods, but the checks were
still missing in many places.

#minor-release

PiperOrigin-RevId: 504589888
parent e8ffc7b6
......@@ -15,6 +15,8 @@
*/
package androidx.media3.ui;
import static androidx.media3.common.Player.COMMAND_GET_MEDIA_ITEMS_METADATA;
import android.app.PendingIntent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
......@@ -48,6 +50,9 @@ public final class DefaultMediaDescriptionAdapter implements MediaDescriptionAda
@Override
public CharSequence getCurrentContentTitle(Player player) {
if (!player.isCommandAvailable(COMMAND_GET_MEDIA_ITEMS_METADATA)) {
return "";
}
@Nullable CharSequence displayTitle = player.getMediaMetadata().displayTitle;
if (!TextUtils.isEmpty(displayTitle)) {
return displayTitle;
......@@ -66,6 +71,9 @@ public final class DefaultMediaDescriptionAdapter implements MediaDescriptionAda
@Nullable
@Override
public CharSequence getCurrentContentText(Player player) {
if (!player.isCommandAvailable(COMMAND_GET_MEDIA_ITEMS_METADATA)) {
return null;
}
@Nullable CharSequence artist = player.getMediaMetadata().artist;
if (!TextUtils.isEmpty(artist)) {
return artist;
......@@ -77,6 +85,9 @@ public final class DefaultMediaDescriptionAdapter implements MediaDescriptionAda
@Nullable
@Override
public Bitmap getCurrentLargeIcon(Player player, BitmapCallback callback) {
if (!player.isCommandAvailable(COMMAND_GET_MEDIA_ITEMS_METADATA)) {
return null;
}
@Nullable byte[] data = player.getMediaMetadata().artworkData;
if (data == null) {
return null;
......
......@@ -15,11 +15,22 @@
*/
package androidx.media3.ui;
import static androidx.media3.common.Player.COMMAND_GET_CURRENT_MEDIA_ITEM;
import static androidx.media3.common.Player.COMMAND_GET_TIMELINE;
import static androidx.media3.common.Player.COMMAND_GET_TRACKS;
import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE;
import static androidx.media3.common.Player.COMMAND_PREPARE;
import static androidx.media3.common.Player.COMMAND_SEEK_BACK;
import static androidx.media3.common.Player.COMMAND_SEEK_FORWARD;
import static androidx.media3.common.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_DEFAULT_POSITION;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_MEDIA_ITEM;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
import static androidx.media3.common.Player.COMMAND_SET_SPEED_AND_PITCH;
import static androidx.media3.common.Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS;
import static androidx.media3.common.Player.EVENT_AVAILABLE_COMMANDS_CHANGED;
import static androidx.media3.common.Player.EVENT_IS_PLAYING_CHANGED;
import static androidx.media3.common.Player.EVENT_PLAYBACK_PARAMETERS_CHANGED;
......@@ -35,6 +46,7 @@ import static androidx.media3.common.Player.EVENT_TRACKS_CHANGED;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull;
import static androidx.media3.common.util.Util.getDrawable;
import static androidx.media3.common.util.Util.msToUs;
import android.annotation.SuppressLint;
import android.content.Context;
......@@ -798,7 +810,7 @@ public class PlayerControlView extends FrameLayout {
*/
public void setRepeatToggleModes(@RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
this.repeatToggleModes = repeatToggleModes;
if (player != null) {
if (player != null && player.isCommandAvailable(COMMAND_SET_REPEAT_MODE)) {
@Player.RepeatMode int currentMode = player.getRepeatMode();
if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
&& currentMode != Player.REPEAT_MODE_OFF) {
......@@ -1062,7 +1074,7 @@ public class PlayerControlView extends FrameLayout {
}
@Nullable Player player = this.player;
if (player == null) {
if (player == null || !player.isCommandAvailable(COMMAND_SET_REPEAT_MODE)) {
updateButton(/* enabled= */ false, repeatToggleButton);
repeatToggleButton.setImageDrawable(repeatOffButtonDrawable);
repeatToggleButton.setContentDescription(repeatOffButtonContentDescription);
......@@ -1096,7 +1108,7 @@ public class PlayerControlView extends FrameLayout {
@Nullable Player player = this.player;
if (!controlViewLayoutManager.getShowButton(shuffleButton)) {
updateButton(/* enabled= */ false, shuffleButton);
} else if (player == null) {
} else if (player == null || !player.isCommandAvailable(COMMAND_SET_SHUFFLE_MODE)) {
updateButton(/* enabled= */ false, shuffleButton);
shuffleButton.setImageDrawable(shuffleOffButtonDrawable);
shuffleButton.setContentDescription(shuffleOffContentDescription);
......@@ -1120,8 +1132,8 @@ public class PlayerControlView extends FrameLayout {
textTrackSelectionAdapter.clear();
audioTrackSelectionAdapter.clear();
if (player == null
|| !player.isCommandAvailable(Player.COMMAND_GET_TRACKS)
|| !player.isCommandAvailable(Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS)) {
|| !player.isCommandAvailable(COMMAND_GET_TRACKS)
|| !player.isCommandAvailable(COMMAND_SET_TRACK_SELECTION_PARAMETERS)) {
return;
}
Tracks tracks = player.getCurrentTracks();
......@@ -1162,12 +1174,14 @@ public class PlayerControlView extends FrameLayout {
if (player == null) {
return;
}
multiWindowTimeBar =
showMultiWindowTimeBar && canShowMultiWindowTimeBar(player.getCurrentTimeline(), window);
multiWindowTimeBar = showMultiWindowTimeBar && canShowMultiWindowTimeBar(player, window);
currentWindowOffset = 0;
long durationUs = 0;
int adGroupCount = 0;
Timeline timeline = player.getCurrentTimeline();
Timeline timeline =
player.isCommandAvailable(COMMAND_GET_TIMELINE)
? player.getCurrentTimeline()
: Timeline.EMPTY;
if (!timeline.isEmpty()) {
int currentWindowIndex = player.getCurrentMediaItemIndex();
int firstWindowIndex = multiWindowTimeBar ? 0 : currentWindowIndex;
......@@ -1209,6 +1223,11 @@ public class PlayerControlView extends FrameLayout {
}
durationUs += window.durationUs;
}
} else if (player.isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
long playerDurationMs = player.getContentDuration();
if (playerDurationMs != C.TIME_UNSET) {
durationUs = msToUs(playerDurationMs);
}
}
long durationMs = Util.usToMs(durationUs);
if (durationView != null) {
......@@ -1236,7 +1255,7 @@ public class PlayerControlView extends FrameLayout {
@Nullable Player player = this.player;
long position = 0;
long bufferedPosition = 0;
if (player != null) {
if (player != null && player.isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
position = currentWindowOffset + player.getContentPosition();
bufferedPosition = currentWindowOffset + player.getContentBufferedPosition();
}
......@@ -1314,7 +1333,7 @@ public class PlayerControlView extends FrameLayout {
}
private void setPlaybackSpeed(float speed) {
if (player == null) {
if (player == null || !player.isCommandAvailable(COMMAND_SET_SPEED_AND_PITCH)) {
return;
}
player.setPlaybackParameters(player.getPlaybackParameters().withSpeed(speed));
......@@ -1335,11 +1354,12 @@ public class PlayerControlView extends FrameLayout {
}
private void seekToTimeBarPosition(Player player, long positionMs) {
int windowIndex;
Timeline timeline = player.getCurrentTimeline();
if (multiWindowTimeBar && !timeline.isEmpty()) {
if (multiWindowTimeBar
&& player.isCommandAvailable(COMMAND_GET_TIMELINE)
&& player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)) {
Timeline timeline = player.getCurrentTimeline();
int windowCount = timeline.getWindowCount();
windowIndex = 0;
int windowIndex = 0;
while (true) {
long windowDurationMs = timeline.getWindow(windowIndex, window).getDurationMs();
if (positionMs < windowDurationMs) {
......@@ -1352,17 +1372,13 @@ public class PlayerControlView extends FrameLayout {
positionMs -= windowDurationMs;
windowIndex++;
}
} else {
windowIndex = player.getCurrentMediaItemIndex();
player.seekTo(windowIndex, positionMs);
} else if (player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)) {
player.seekTo(positionMs);
}
seekTo(player, windowIndex, positionMs);
updateProgress();
}
private void seekTo(Player player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
}
private void onFullScreenButtonClicked(View v) {
if (onFullScreenModeChangedListener == null) {
return;
......@@ -1440,10 +1456,12 @@ public class PlayerControlView extends FrameLayout {
}
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
if (player.getPlaybackState() != Player.STATE_ENDED) {
if (player.getPlaybackState() != Player.STATE_ENDED
&& player.isCommandAvailable(COMMAND_SEEK_FORWARD)) {
player.seekForward();
}
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND
&& player.isCommandAvailable(COMMAND_SEEK_BACK)) {
player.seekBack();
} else if (event.getRepeatCount() == 0) {
switch (keyCode) {
......@@ -1458,10 +1476,14 @@ public class PlayerControlView extends FrameLayout {
dispatchPause(player);
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
player.seekToNext();
if (player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)) {
player.seekToNext();
}
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
player.seekToPrevious();
if (player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS)) {
player.seekToPrevious();
}
break;
default:
break;
......@@ -1501,7 +1523,10 @@ public class PlayerControlView extends FrameLayout {
}
private boolean shouldEnablePlayPauseButton() {
return player != null && !player.getCurrentTimeline().isEmpty();
return player != null
&& player.isCommandAvailable(COMMAND_PLAY_PAUSE)
&& (!player.isCommandAvailable(COMMAND_GET_TIMELINE)
|| !player.getCurrentTimeline().isEmpty());
}
private boolean shouldShowPauseButton() {
......@@ -1522,16 +1547,21 @@ public class PlayerControlView extends FrameLayout {
private void dispatchPlay(Player player) {
@State int state = player.getPlaybackState();
if (state == Player.STATE_IDLE) {
if (state == Player.STATE_IDLE && player.isCommandAvailable(COMMAND_PREPARE)) {
player.prepare();
} else if (state == Player.STATE_ENDED) {
seekTo(player, player.getCurrentMediaItemIndex(), C.TIME_UNSET);
} else if (state == Player.STATE_ENDED
&& player.isCommandAvailable(COMMAND_SEEK_TO_DEFAULT_POSITION)) {
player.seekToDefaultPosition();
}
if (player.isCommandAvailable(COMMAND_PLAY_PAUSE)) {
player.play();
}
player.play();
}
private void dispatchPause(Player player) {
player.pause();
if (player.isCommandAvailable(COMMAND_PLAY_PAUSE)) {
player.pause();
}
}
@SuppressLint("InlinedApi")
......@@ -1547,13 +1577,18 @@ public class PlayerControlView extends FrameLayout {
}
/**
* Returns whether the specified {@code timeline} can be shown on a multi-window time bar.
* Returns whether the specified {@code player} can be shown on a multi-window time bar.
*
* @param timeline The {@link Timeline} to check.
* @param player The {@link Player} to check.
* @param window A scratch {@link Timeline.Window} instance.
* @return Whether the specified timeline can be shown on a multi-window time bar.
*/
private static boolean canShowMultiWindowTimeBar(Timeline timeline, Timeline.Window window) {
private static boolean canShowMultiWindowTimeBar(Player player, Timeline.Window window) {
if (!player.isCommandAvailable(COMMAND_GET_TIMELINE)
|| !player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)) {
return false;
}
Timeline timeline = player.getCurrentTimeline();
if (timeline.getWindowCount() > MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR) {
return false;
}
......@@ -1674,22 +1709,33 @@ public class PlayerControlView extends FrameLayout {
}
controlViewLayoutManager.resetHideCallbacks();
if (nextButton == view) {
player.seekToNext();
if (player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)) {
player.seekToNext();
}
} else if (previousButton == view) {
player.seekToPrevious();
if (player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS)) {
player.seekToPrevious();
}
} else if (fastForwardButton == view) {
if (player.getPlaybackState() != Player.STATE_ENDED) {
if (player.getPlaybackState() != Player.STATE_ENDED
&& player.isCommandAvailable(COMMAND_SEEK_FORWARD)) {
player.seekForward();
}
} else if (rewindButton == view) {
player.seekBack();
if (player.isCommandAvailable(COMMAND_SEEK_BACK)) {
player.seekBack();
}
} else if (playPauseButton == view) {
dispatchPlayPause(player);
} else if (repeatToggleButton == view) {
player.setRepeatMode(
RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
if (player.isCommandAvailable(COMMAND_SET_REPEAT_MODE)) {
player.setRepeatMode(
RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
}
} else if (shuffleButton == view) {
player.setShuffleModeEnabled(!player.getShuffleModeEnabled());
if (player.isCommandAvailable(COMMAND_SET_SHUFFLE_MODE)) {
player.setShuffleModeEnabled(!player.getShuffleModeEnabled());
}
} else if (settingsButton == view) {
controlViewLayoutManager.removeHideCallbacks();
displaySettingsWindow(settingsAdapter, settingsButton);
......@@ -1892,7 +1938,8 @@ public class PlayerControlView extends FrameLayout {
holder.checkView.setVisibility(isTrackSelectionOff ? VISIBLE : INVISIBLE);
holder.itemView.setOnClickListener(
v -> {
if (player != null) {
if (player != null
&& player.isCommandAvailable(COMMAND_SET_TRACK_SELECTION_PARAMETERS)) {
TrackSelectionParameters trackSelectionParameters =
player.getTrackSelectionParameters();
player.setTrackSelectionParameters(
......@@ -1933,7 +1980,8 @@ public class PlayerControlView extends FrameLayout {
holder.checkView.setVisibility(hasSelectionOverride ? INVISIBLE : VISIBLE);
holder.itemView.setOnClickListener(
v -> {
if (player == null) {
if (player == null
|| !player.isCommandAvailable(COMMAND_SET_TRACK_SELECTION_PARAMETERS)) {
return;
}
TrackSelectionParameters trackSelectionParameters =
......@@ -2036,6 +2084,9 @@ public class PlayerControlView extends FrameLayout {
holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE);
holder.itemView.setOnClickListener(
v -> {
if (!player.isCommandAvailable(COMMAND_SET_TRACK_SELECTION_PARAMETERS)) {
return;
}
TrackSelectionParameters trackSelectionParameters =
player.getTrackSelectionParameters();
player.setTrackSelectionParameters(
......
......@@ -15,10 +15,17 @@
*/
package androidx.media3.ui;
import static androidx.media3.common.Player.COMMAND_CHANGE_MEDIA_ITEMS;
import static androidx.media3.common.Player.COMMAND_GET_CURRENT_MEDIA_ITEM;
import static androidx.media3.common.Player.COMMAND_GET_TIMELINE;
import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE;
import static androidx.media3.common.Player.COMMAND_PREPARE;
import static androidx.media3.common.Player.COMMAND_SEEK_BACK;
import static androidx.media3.common.Player.COMMAND_SEEK_FORWARD;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_DEFAULT_POSITION;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT;
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
import static androidx.media3.common.Player.COMMAND_STOP;
import static androidx.media3.common.Player.EVENT_IS_PLAYING_CHANGED;
import static androidx.media3.common.Player.EVENT_MEDIA_METADATA_CHANGED;
import static androidx.media3.common.Player.EVENT_PLAYBACK_PARAMETERS_CHANGED;
......@@ -1205,7 +1212,9 @@ public class PlayerNotificationManager {
@Nullable NotificationCompat.Builder builder,
boolean ongoing,
@Nullable Bitmap largeIcon) {
if (player.getPlaybackState() == Player.STATE_IDLE && player.getCurrentTimeline().isEmpty()) {
if (player.getPlaybackState() == Player.STATE_IDLE
&& player.isCommandAvailable(COMMAND_GET_TIMELINE)
&& player.getCurrentTimeline().isEmpty()) {
builderActions = null;
return null;
}
......@@ -1259,6 +1268,7 @@ public class PlayerNotificationManager {
// Changing "showWhen" causes notification flicker if SDK_INT < 21.
if (Util.SDK_INT >= 21
&& useChronometer
&& player.isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)
&& player.isPlaying()
&& !player.isPlayingAd()
&& !player.isCurrentMediaItemDynamic()
......@@ -1537,24 +1547,43 @@ public class PlayerNotificationManager {
}
String action = intent.getAction();
if (ACTION_PLAY.equals(action)) {
if (player.getPlaybackState() == Player.STATE_IDLE) {
if (player.getPlaybackState() == Player.STATE_IDLE
&& player.isCommandAvailable(COMMAND_PREPARE)) {
player.prepare();
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
player.seekToDefaultPosition(player.getCurrentMediaItemIndex());
} else if (player.getPlaybackState() == Player.STATE_ENDED
&& player.isCommandAvailable(COMMAND_SEEK_TO_DEFAULT_POSITION)) {
player.seekToDefaultPosition();
}
if (player.isCommandAvailable(COMMAND_PLAY_PAUSE)) {
player.play();
}
player.play();
} else if (ACTION_PAUSE.equals(action)) {
player.pause();
if (player.isCommandAvailable(COMMAND_PLAY_PAUSE)) {
player.pause();
}
} else if (ACTION_PREVIOUS.equals(action)) {
player.seekToPrevious();
if (player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS)) {
player.seekToPrevious();
}
} else if (ACTION_REWIND.equals(action)) {
player.seekBack();
if (player.isCommandAvailable(COMMAND_SEEK_BACK)) {
player.seekBack();
}
} else if (ACTION_FAST_FORWARD.equals(action)) {
player.seekForward();
if (player.isCommandAvailable(COMMAND_SEEK_FORWARD)) {
player.seekForward();
}
} else if (ACTION_NEXT.equals(action)) {
player.seekToNext();
if (player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)) {
player.seekToNext();
}
} else if (ACTION_STOP.equals(action)) {
player.stop(/* reset= */ true);
if (player.isCommandAvailable(COMMAND_STOP)) {
player.stop();
}
if (player.isCommandAvailable(COMMAND_CHANGE_MEDIA_ITEMS)) {
player.clearMediaItems();
}
} else if (ACTION_DISMISS.equals(action)) {
stopNotification(/* dismissedByUser= */ true);
} else if (action != null
......
......@@ -15,7 +15,11 @@
*/
package androidx.media3.ui;
import static androidx.media3.common.Player.COMMAND_GET_CURRENT_MEDIA_ITEM;
import static androidx.media3.common.Player.COMMAND_GET_MEDIA_ITEMS_METADATA;
import static androidx.media3.common.Player.COMMAND_GET_TEXT;
import static androidx.media3.common.Player.COMMAND_GET_TIMELINE;
import static androidx.media3.common.Player.COMMAND_GET_TRACKS;
import static androidx.media3.common.Player.COMMAND_SET_VIDEO_SURFACE;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.getDrawable;
......@@ -527,10 +531,12 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
@Nullable Player oldPlayer = this.player;
if (oldPlayer != null) {
oldPlayer.removeListener(componentListener);
if (surfaceView instanceof TextureView) {
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SurfaceView) {
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
if (oldPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
if (surfaceView instanceof TextureView) {
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SurfaceView) {
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
}
}
}
if (subtitleView != null) {
......@@ -743,7 +749,9 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (player != null && player.isPlayingAd()) {
if (player != null
&& player.isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)
&& player.isPlayingAd()) {
return super.dispatchKeyEvent(event);
}
......@@ -1274,7 +1282,8 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
}
int playbackState = player.getPlaybackState();
return controllerAutoShow
&& !player.getCurrentTimeline().isEmpty()
&& (!player.isCommandAvailable(COMMAND_GET_TIMELINE)
|| !player.getCurrentTimeline().isEmpty())
&& (playbackState == Player.STATE_IDLE
|| playbackState == Player.STATE_ENDED
|| !checkNotNull(player).getPlayWhenReady());
......@@ -1289,12 +1298,17 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
}
private boolean isPlayingAd() {
return player != null && player.isPlayingAd() && player.getPlayWhenReady();
return player != null
&& player.isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)
&& player.isPlayingAd()
&& player.getPlayWhenReady();
}
private void updateForCurrentTrackSelections(boolean isNewPlayer) {
@Nullable Player player = this.player;
if (player == null || player.getCurrentTracks().isEmpty()) {
if (player == null
|| !player.isCommandAvailable(COMMAND_GET_TRACKS)
|| player.getCurrentTracks().isEmpty()) {
if (!keepContentOnPlayerReset) {
hideArtwork();
closeShutter();
......@@ -1318,7 +1332,7 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
closeShutter();
// Display artwork if enabled and available, else hide it.
if (useArtwork()) {
if (setArtworkFromMediaMetadata(player.getMediaMetadata())) {
if (setArtworkFromMediaMetadata(player)) {
return;
}
if (setDrawableArtwork(defaultArtwork)) {
......@@ -1330,7 +1344,11 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
}
@RequiresNonNull("artworkView")
private boolean setArtworkFromMediaMetadata(MediaMetadata mediaMetadata) {
private boolean setArtworkFromMediaMetadata(Player player) {
if (!player.isCommandAvailable(COMMAND_GET_MEDIA_ITEMS_METADATA)) {
return false;
}
MediaMetadata mediaMetadata = player.getMediaMetadata();
if (mediaMetadata.artworkData == null) {
return false;
}
......@@ -1549,10 +1567,14 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
// is necessary to avoid closing the shutter when such a transition occurs. See:
// https://github.com/google/ExoPlayer/issues/5507.
Player player = checkNotNull(PlayerView.this.player);
Timeline timeline = player.getCurrentTimeline();
Timeline timeline =
player.isCommandAvailable(COMMAND_GET_TIMELINE)
? player.getCurrentTimeline()
: Timeline.EMPTY;
if (timeline.isEmpty()) {
lastPeriodUidWithTracks = null;
} else if (!player.getCurrentTracks().isEmpty()) {
} else if (player.isCommandAvailable(COMMAND_GET_TRACKS)
&& !player.getCurrentTracks().isEmpty()) {
lastPeriodUidWithTracks =
timeline.getPeriod(player.getCurrentPeriodIndex(), period, /* setIds= */ true).uid;
} else if (lastPeriodUidWithTracks != null) {
......
......@@ -15,6 +15,9 @@
*/
package androidx.media3.ui;
import static androidx.media3.common.Player.COMMAND_GET_TRACKS;
import static androidx.media3.common.Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
......@@ -102,7 +105,9 @@ public final class TrackSelectionDialogBuilder {
Context context, CharSequence title, Player player, @C.TrackType int trackType) {
this.context = context;
this.title = title;
List<Tracks.Group> allTrackGroups = player.getCurrentTracks().getGroups();
Tracks tracks =
player.isCommandAvailable(COMMAND_GET_TRACKS) ? player.getCurrentTracks() : Tracks.EMPTY;
List<Tracks.Group> allTrackGroups = tracks.getGroups();
trackGroups = new ArrayList<>();
for (int i = 0; i < allTrackGroups.size(); i++) {
Tracks.Group trackGroup = allTrackGroups.get(i);
......@@ -113,6 +118,9 @@ public final class TrackSelectionDialogBuilder {
overrides = player.getTrackSelectionParameters().overrides;
callback =
(isDisabled, overrides) -> {
if (!player.isCommandAvailable(COMMAND_SET_TRACK_SELECTION_PARAMETERS)) {
return;
}
TrackSelectionParameters.Builder parametersBuilder =
player.getTrackSelectionParameters().buildUpon();
parametersBuilder.setTrackTypeDisabled(trackType, isDisabled);
......
......@@ -34,7 +34,7 @@ import org.junit.runner.RunWith;
public class DefaultMediaDescriptionAdapterTest {
@Test
public void getters_returnMediaMetadataValues() {
public void getters_withGetMetatadataCommandAvailable_returnMediaMetadataValues() {
Context context = ApplicationProvider.getApplicationContext();
Player player = mock(Player.class);
MediaMetadata mediaMetadata =
......@@ -43,6 +43,7 @@ public class DefaultMediaDescriptionAdapterTest {
PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE);
DefaultMediaDescriptionAdapter adapter = new DefaultMediaDescriptionAdapter(pendingIntent);
when(player.isCommandAvailable(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)).thenReturn(true);
when(player.getMediaMetadata()).thenReturn(mediaMetadata);
assertThat(adapter.createCurrentContentIntent(player)).isEqualTo(pendingIntent);
......@@ -51,4 +52,22 @@ public class DefaultMediaDescriptionAdapterTest {
assertThat(adapter.getCurrentContentText(player).toString())
.isEqualTo(mediaMetadata.artist.toString());
}
@Test
public void getters_withoutGetMetatadataCommandAvailable_returnMediaMetadataValues() {
Context context = ApplicationProvider.getApplicationContext();
Player player = mock(Player.class);
MediaMetadata mediaMetadata =
new MediaMetadata.Builder().setDisplayTitle("display title").setArtist("artist").build();
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE);
DefaultMediaDescriptionAdapter adapter = new DefaultMediaDescriptionAdapter(pendingIntent);
when(player.isCommandAvailable(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)).thenReturn(false);
when(player.getMediaMetadata()).thenReturn(mediaMetadata);
assertThat(adapter.createCurrentContentIntent(player)).isEqualTo(pendingIntent);
assertThat(adapter.getCurrentContentTitle(player).toString()).isEqualTo("");
assertThat(adapter.getCurrentContentText(player)).isNull();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment