mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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
This commit is contained in:
parent
e8ffc7b6f8
commit
e2ece2f5bc
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user