Remove deprecated ControlDispatcher

The possibilities to set a ControlDispatcher have been removed in
<unknown commit> so that the ControlDispatcher is always a
DefaultControlDispatcher.

PiperOrigin-RevId: 403327092
This commit is contained in:
kimvde 2021-10-15 11:08:08 +01:00 committed by Oliver Woodman
parent bc1b2dae11
commit 5ef00f0e96
9 changed files with 121 additions and 433 deletions

View File

@ -107,12 +107,10 @@
`Player.EVENT_MEDIA_METADATA_CHANGED` for convenient access to
structured metadata, or access the raw static metadata directly from the
`TrackSelection#getFormat()`.
* Remove `setControlDispatcher` from `PlayerWrapper`,
`SessionPlayerConnector`, `MediaSessionConnector`, `PlayerControlView`,
`PlayerNotificationManager`, `PlayerView`, `StyledPlayerControlView`,
`StyledPlayerView` and `LeanbackPlayerAdapter`. Operations can be
customized by using a `ForwardingPlayer`, or when configuring the player
(for example by using `ExoPlayer.Builder.setSeekBackIncrementMs`).
* Remove `ControlDispatcher` and `DefaultControlDispatcher`. Operations
can be customized by using a `ForwardingPlayer`, or when configuring the
player (for example by using
`ExoPlayer.Builder.setSeekBackIncrementMs`).
### 2.15.1 (2021-09-20)

View File

@ -26,8 +26,6 @@ import androidx.leanback.media.PlaybackGlueHost;
import androidx.leanback.media.PlayerAdapter;
import androidx.leanback.media.SurfaceHolderGlueHost;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
@ -51,7 +49,6 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
private final PlayerListener playerListener;
private final int updatePeriodMs;
private ControlDispatcher controlDispatcher;
@Nullable private ErrorMessageProvider<? super PlaybackException> errorMessageProvider;
@Nullable private SurfaceHolderGlueHost surfaceHolderGlueHost;
private boolean hasSurface;
@ -72,7 +69,6 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
this.updatePeriodMs = updatePeriodMs;
handler = Util.createHandlerForCurrentOrMainLooper();
playerListener = new PlayerListener();
controlDispatcher = new DefaultControlDispatcher();
}
/**
@ -143,27 +139,27 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
@Override
public void play() {
if (player.getPlaybackState() == Player.STATE_IDLE) {
controlDispatcher.dispatchPrepare(player);
player.prepare();
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
player.seekToDefaultPosition(player.getCurrentWindowIndex());
}
if (player.isCommandAvailable(Player.COMMAND_PLAY_PAUSE)
&& controlDispatcher.dispatchSetPlayWhenReady(player, true)) {
if (player.isCommandAvailable(Player.COMMAND_PLAY_PAUSE)) {
player.play();
getCallback().onPlayStateChanged(this);
}
}
@Override
public void pause() {
if (player.isCommandAvailable(Player.COMMAND_PLAY_PAUSE)
&& controlDispatcher.dispatchSetPlayWhenReady(player, false)) {
if (player.isCommandAvailable(Player.COMMAND_PLAY_PAUSE)) {
player.pause();
getCallback().onPlayStateChanged(this);
}
}
@Override
public void seekTo(long positionMs) {
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), positionMs);
player.seekTo(player.getCurrentMediaItemIndex(), positionMs);
}
@Override

View File

@ -33,8 +33,6 @@ import androidx.media2.common.CallbackMediaItem;
import androidx.media2.common.MediaMetadata;
import androidx.media2.common.SessionPlayer;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
@ -123,7 +121,6 @@ import java.util.List;
private final List<androidx.media2.common.MediaItem> media2Playlist;
private final List<MediaItem> exoPlayerPlaylist;
private ControlDispatcher controlDispatcher;
private int sessionPlayerState;
private boolean prepared;
@Nullable private androidx.media2.common.MediaItem bufferingItem;
@ -142,7 +139,6 @@ import java.util.List;
this.player = player;
this.mediaItemConverter = mediaItemConverter;
controlDispatcher = new DefaultControlDispatcher();
componentListener = new ComponentListener();
player.addListener(componentListener);
@ -235,13 +231,19 @@ import java.util.List;
}
public boolean skipToPreviousPlaylistItem() {
return player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS)
&& controlDispatcher.dispatchPrevious(player);
if (!player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS)) {
return false;
}
player.seekToPrevious();
return true;
}
public boolean skipToNextPlaylistItem() {
return player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)
&& controlDispatcher.dispatchNext(player);
if (!player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)) {
return false;
}
player.seekToNext();
return true;
}
public boolean skipToPlaylistItem(@IntRange(from = 0) int index) {
@ -252,11 +254,11 @@ import java.util.List;
// but RESULT_ERROR_INVALID_STATE with IllegalStateException is expected here.
Assertions.checkState(0 <= index && index < timeline.getWindowCount());
int windowIndex = player.getCurrentWindowIndex();
if (windowIndex != index) {
return player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)
&& controlDispatcher.dispatchSeekTo(player, index, C.TIME_UNSET);
if (windowIndex == index || !player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)) {
return false;
}
return false;
player.seekToDefaultPosition(index);
return true;
}
public boolean updatePlaylistMetadata(@Nullable MediaMetadata metadata) {
@ -265,15 +267,19 @@ import java.util.List;
}
public boolean setRepeatMode(int repeatMode) {
return player.isCommandAvailable(COMMAND_SET_REPEAT_MODE)
&& controlDispatcher.dispatchSetRepeatMode(
player, Utils.getExoPlayerRepeatMode(repeatMode));
if (!player.isCommandAvailable(COMMAND_SET_REPEAT_MODE)) {
return false;
}
player.setRepeatMode(Utils.getExoPlayerRepeatMode(repeatMode));
return true;
}
public boolean setShuffleMode(int shuffleMode) {
return player.isCommandAvailable(COMMAND_SET_SHUFFLE_MODE)
&& controlDispatcher.dispatchSetShuffleModeEnabled(
player, Utils.getExoPlayerShuffleMode(shuffleMode));
if (!player.isCommandAvailable(COMMAND_SET_SHUFFLE_MODE)) {
return false;
}
player.setShuffleModeEnabled(Utils.getExoPlayerShuffleMode(shuffleMode));
return true;
}
@Nullable
@ -322,36 +328,38 @@ import java.util.List;
public boolean play() {
if (player.getPlaybackState() == Player.STATE_ENDED) {
boolean seekHandled =
player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)
&& controlDispatcher.dispatchSeekTo(
player, player.getCurrentWindowIndex(), /* positionMs= */ 0);
if (!seekHandled) {
if (!player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)) {
return false;
}
player.seekTo(player.getCurrentWindowIndex(), /* positionMs= */ 0);
}
boolean playWhenReady = player.getPlayWhenReady();
int suppressReason = player.getPlaybackSuppressionReason();
if (playWhenReady && suppressReason == Player.PLAYBACK_SUPPRESSION_REASON_NONE) {
if ((playWhenReady && suppressReason == Player.PLAYBACK_SUPPRESSION_REASON_NONE)
|| !player.isCommandAvailable(COMMAND_PLAY_PAUSE)) {
return false;
}
return player.isCommandAvailable(COMMAND_PLAY_PAUSE)
&& controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ true);
player.play();
return true;
}
public boolean pause() {
boolean playWhenReady = player.getPlayWhenReady();
int suppressReason = player.getPlaybackSuppressionReason();
if (!playWhenReady && suppressReason == Player.PLAYBACK_SUPPRESSION_REASON_NONE) {
if ((!playWhenReady && suppressReason == Player.PLAYBACK_SUPPRESSION_REASON_NONE)
|| !player.isCommandAvailable(COMMAND_PLAY_PAUSE)) {
return false;
}
return player.isCommandAvailable(COMMAND_PLAY_PAUSE)
&& controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ false);
player.pause();
return true;
}
public boolean seekTo(long position) {
return player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)
&& controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), position);
if (!player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)) {
return false;
}
player.seekTo(player.getCurrentWindowIndex(), position);
return true;
}
public long getCurrentPosition() {
@ -471,7 +479,8 @@ import java.util.List;
}
public void reset() {
controlDispatcher.dispatchStop(player, /* reset= */ true);
player.stop();
player.clearMediaItems();
prepared = false;
bufferingItem = null;
}

View File

@ -45,8 +45,6 @@ import android.view.KeyEvent;
import androidx.annotation.LongDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
@ -450,7 +448,6 @@ public final class MediaSessionConnector {
private final ArrayList<CommandReceiver> commandReceivers;
private final ArrayList<CommandReceiver> customCommandReceivers;
private ControlDispatcher controlDispatcher;
private CustomActionProvider[] customActionProviders;
private Map<String, CustomActionProvider> customActionMap;
@Nullable private MediaMetadataProvider mediaMetadataProvider;
@ -480,7 +477,6 @@ public final class MediaSessionConnector {
componentListener = new ComponentListener();
commandReceivers = new ArrayList<>();
customCommandReceivers = new ArrayList<>();
controlDispatcher = new DefaultControlDispatcher();
customActionProviders = new CustomActionProvider[0];
customActionMap = Collections.emptyMap();
mediaMetadataProvider =
@ -885,10 +881,8 @@ public final class MediaSessionConnector {
private long buildPlaybackActions(Player player) {
boolean enableSeeking = player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM);
boolean enableRewind =
player.isCommandAvailable(COMMAND_SEEK_BACK) && controlDispatcher.isRewindEnabled();
boolean enableFastForward =
player.isCommandAvailable(COMMAND_SEEK_FORWARD) && controlDispatcher.isFastForwardEnabled();
boolean enableRewind = player.isCommandAvailable(COMMAND_SEEK_BACK);
boolean enableFastForward = player.isCommandAvailable(COMMAND_SEEK_FORWARD);
boolean enableSetRating = false;
boolean enableSetCaptioningEnabled = false;
@ -976,7 +970,7 @@ public final class MediaSessionConnector {
}
private void seekTo(Player player, int windowIndex, long positionMs) {
controlDispatcher.dispatchSeekTo(player, windowIndex, positionMs);
player.seekTo(windowIndex, positionMs);
}
private static int getMediaSessionPlaybackState(
@ -1173,20 +1167,19 @@ public final class MediaSessionConnector {
if (playbackPreparer != null) {
playbackPreparer.onPrepare(/* playWhenReady= */ true);
} else {
controlDispatcher.dispatchPrepare(player);
player.prepare();
}
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
}
controlDispatcher.dispatchSetPlayWhenReady(
Assertions.checkNotNull(player), /* playWhenReady= */ true);
Assertions.checkNotNull(player).play();
}
}
@Override
public void onPause() {
if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_PAUSE)) {
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ false);
player.pause();
}
}
@ -1200,21 +1193,22 @@ public final class MediaSessionConnector {
@Override
public void onFastForward() {
if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_FAST_FORWARD)) {
controlDispatcher.dispatchFastForward(player);
player.seekForward();
}
}
@Override
public void onRewind() {
if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_REWIND)) {
controlDispatcher.dispatchRewind(player);
player.seekBack();
}
}
@Override
public void onStop() {
if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_STOP)) {
controlDispatcher.dispatchStop(player, /* reset= */ true);
player.stop();
player.clearMediaItems();
}
}
@ -1233,7 +1227,7 @@ public final class MediaSessionConnector {
shuffleModeEnabled = false;
break;
}
controlDispatcher.dispatchSetShuffleModeEnabled(player, shuffleModeEnabled);
player.setShuffleModeEnabled(shuffleModeEnabled);
}
}
@ -1255,15 +1249,14 @@ public final class MediaSessionConnector {
repeatMode = Player.REPEAT_MODE_OFF;
break;
}
controlDispatcher.dispatchSetRepeatMode(player, repeatMode);
player.setRepeatMode(repeatMode);
}
}
@Override
public void onSetPlaybackSpeed(float speed) {
if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_SET_PLAYBACK_SPEED) && speed > 0) {
controlDispatcher.dispatchSetPlaybackParameters(
player, player.getPlaybackParameters().withSpeed(speed));
player.setPlaybackParameters(player.getPlaybackParameters().withSpeed(speed));
}
}

View File

@ -1,125 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.Player.RepeatMode;
/** @deprecated Use a {@link ForwardingPlayer} or configure the player to customize operations. */
@Deprecated
public interface ControlDispatcher {
/**
* Dispatches a {@link Player#prepare()} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchPrepare(Player player);
/**
* Dispatches a {@link Player#setPlayWhenReady(boolean)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param playWhenReady Whether playback should proceed when ready.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady);
/**
* Dispatches a {@link Player#seekTo(int, long)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param windowIndex The index of the window.
* @param positionMs The seek position in the specified window, or {@link C#TIME_UNSET} to seek to
* the window's default position.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSeekTo(Player player, int windowIndex, long positionMs);
/**
* Dispatches a {@link Player#seekToPreviousWindow()} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchPrevious(Player player);
/**
* Dispatches a {@link Player#seekToNextWindow()} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchNext(Player player);
/**
* Dispatches a rewind operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchRewind(Player player);
/**
* Dispatches a fast forward operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchFastForward(Player player);
/**
* Dispatches a {@link Player#setRepeatMode(int)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param repeatMode The repeat mode.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode);
/**
* Dispatches a {@link Player#setShuffleModeEnabled(boolean)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param shuffleModeEnabled Whether shuffling is enabled.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled);
/**
* Dispatches a {@link Player#stop()} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param reset Whether the player should be reset.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchStop(Player player, boolean reset);
/**
* Dispatches a {@link Player#setPlaybackParameters(PlaybackParameters)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param playbackParameters The playback parameters.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetPlaybackParameters(Player player, PlaybackParameters playbackParameters);
/** Returns {@code true} if rewind is enabled, {@code false} otherwise. */
boolean isRewindEnabled();
/** Returns {@code true} if fast forward is enabled, {@code false} otherwise. */
boolean isFastForwardEnabled();
}

View File

@ -1,158 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import static java.lang.Math.max;
import static java.lang.Math.min;
/** @deprecated Use a {@link ForwardingPlayer} or configure the player to customize operations. */
@Deprecated
public class DefaultControlDispatcher implements ControlDispatcher {
private final long rewindIncrementMs;
private final long fastForwardIncrementMs;
private final boolean rewindAndFastForwardIncrementsSet;
/** Creates an instance. */
public DefaultControlDispatcher() {
fastForwardIncrementMs = C.TIME_UNSET;
rewindIncrementMs = C.TIME_UNSET;
rewindAndFastForwardIncrementsSet = false;
}
/**
* Creates an instance with the given increments.
*
* @param fastForwardIncrementMs The fast forward increment in milliseconds. A non-positive value
* disables the fast forward operation.
* @param rewindIncrementMs The rewind increment in milliseconds. A non-positive value disables
* the rewind operation.
*/
public DefaultControlDispatcher(long fastForwardIncrementMs, long rewindIncrementMs) {
this.fastForwardIncrementMs = fastForwardIncrementMs;
this.rewindIncrementMs = rewindIncrementMs;
rewindAndFastForwardIncrementsSet = true;
}
@Override
public boolean dispatchPrepare(Player player) {
player.prepare();
return true;
}
@Override
public boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady) {
player.setPlayWhenReady(playWhenReady);
return true;
}
@Override
public boolean dispatchSeekTo(Player player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
return true;
}
@Override
public boolean dispatchPrevious(Player player) {
player.seekToPrevious();
return true;
}
@Override
public boolean dispatchNext(Player player) {
player.seekToNext();
return true;
}
@Override
public boolean dispatchRewind(Player player) {
if (!rewindAndFastForwardIncrementsSet) {
player.seekBack();
} else if (isRewindEnabled() && player.isCurrentWindowSeekable()) {
seekToOffset(player, -rewindIncrementMs);
}
return true;
}
@Override
public boolean dispatchFastForward(Player player) {
if (!rewindAndFastForwardIncrementsSet) {
player.seekForward();
} else if (isFastForwardEnabled() && player.isCurrentWindowSeekable()) {
seekToOffset(player, fastForwardIncrementMs);
}
return true;
}
@Override
public boolean dispatchSetRepeatMode(Player player, @Player.RepeatMode int repeatMode) {
player.setRepeatMode(repeatMode);
return true;
}
@Override
public boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled) {
player.setShuffleModeEnabled(shuffleModeEnabled);
return true;
}
@Override
public boolean dispatchStop(Player player, boolean reset) {
player.stop(reset);
return true;
}
@Override
public boolean dispatchSetPlaybackParameters(
Player player, PlaybackParameters playbackParameters) {
player.setPlaybackParameters(playbackParameters);
return true;
}
@Override
public boolean isRewindEnabled() {
return !rewindAndFastForwardIncrementsSet || rewindIncrementMs > 0;
}
@Override
public boolean isFastForwardEnabled() {
return !rewindAndFastForwardIncrementsSet || fastForwardIncrementMs > 0;
}
/** Returns the rewind increment in milliseconds. */
public long getRewindIncrementMs(Player player) {
return rewindAndFastForwardIncrementsSet ? rewindIncrementMs : player.getSeekBackIncrement();
}
/** Returns the fast forward increment in milliseconds. */
public long getFastForwardIncrementMs(Player player) {
return rewindAndFastForwardIncrementsSet
? fastForwardIncrementMs
: player.getSeekForwardIncrement();
}
// Internal methods.
private static void seekToOffset(Player player, long offsetMs) {
long positionMs = player.getCurrentPosition() + offsetMs;
long durationMs = player.getDuration();
if (durationMs != C.TIME_UNSET) {
positionMs = min(positionMs, durationMs);
}
positionMs = max(positionMs, 0);
player.seekTo(positionMs);
}
}

View File

@ -50,8 +50,6 @@ import androidx.annotation.DoNotInline;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Player.Events;
@ -321,7 +319,6 @@ public class PlayerControlView extends FrameLayout {
private final String shuffleOffContentDescription;
@Nullable private Player player;
private ControlDispatcher controlDispatcher;
@Nullable private ProgressUpdateListener progressUpdateListener;
private boolean isAttachedToWindow;
@ -418,7 +415,6 @@ public class PlayerControlView extends FrameLayout {
extraAdGroupTimesMs = new long[0];
extraPlayedAdGroups = new boolean[0];
componentListener = new ComponentListener();
controlDispatcher = new DefaultControlDispatcher();
updateProgressAction = this::updateProgress;
hideAction = this::hide;
@ -695,13 +691,13 @@ public class PlayerControlView extends FrameLayout {
@Player.RepeatMode int currentMode = player.getRepeatMode();
if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
&& currentMode != Player.REPEAT_MODE_OFF) {
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_OFF);
player.setRepeatMode(Player.REPEAT_MODE_OFF);
} else if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_ONE
&& currentMode == Player.REPEAT_MODE_ALL) {
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_ONE);
player.setRepeatMode(Player.REPEAT_MODE_ONE);
} else if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL
&& currentMode == Player.REPEAT_MODE_ONE) {
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_ALL);
player.setRepeatMode(Player.REPEAT_MODE_ALL);
}
}
updateRepeatModeButton();
@ -867,11 +863,8 @@ public class PlayerControlView extends FrameLayout {
if (player != null) {
enableSeeking = player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM);
enablePrevious = player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS);
enableRewind =
player.isCommandAvailable(COMMAND_SEEK_BACK) && controlDispatcher.isRewindEnabled();
enableFastForward =
player.isCommandAvailable(COMMAND_SEEK_FORWARD)
&& controlDispatcher.isFastForwardEnabled();
enableRewind = player.isCommandAvailable(COMMAND_SEEK_BACK);
enableFastForward = player.isCommandAvailable(COMMAND_SEEK_FORWARD);
enableNext = player.isCommandAvailable(COMMAND_SEEK_TO_NEXT);
}
@ -1123,8 +1116,8 @@ public class PlayerControlView extends FrameLayout {
updateProgress();
}
private boolean seekTo(Player player, int windowIndex, long positionMs) {
return controlDispatcher.dispatchSeekTo(player, windowIndex, positionMs);
private void seekTo(Player player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
}
@Override
@ -1183,10 +1176,10 @@ public class PlayerControlView extends FrameLayout {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
if (player.getPlaybackState() != Player.STATE_ENDED) {
controlDispatcher.dispatchFastForward(player);
player.seekForward();
}
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {
controlDispatcher.dispatchRewind(player);
player.seekBack();
} else if (event.getRepeatCount() == 0) {
switch (keyCode) {
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
@ -1200,10 +1193,10 @@ public class PlayerControlView extends FrameLayout {
dispatchPause(player);
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
controlDispatcher.dispatchNext(player);
player.seekToNext();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
controlDispatcher.dispatchPrevious(player);
player.seekToPrevious();
break;
default:
break;
@ -1233,15 +1226,15 @@ public class PlayerControlView extends FrameLayout {
private void dispatchPlay(Player player) {
@State int state = player.getPlaybackState();
if (state == Player.STATE_IDLE) {
controlDispatcher.dispatchPrepare(player);
player.prepare();
} else if (state == Player.STATE_ENDED) {
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
}
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ true);
player.play();
}
private void dispatchPause(Player player) {
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ false);
player.pause();
}
@SuppressLint("InlinedApi")
@ -1343,24 +1336,24 @@ public class PlayerControlView extends FrameLayout {
return;
}
if (nextButton == view) {
controlDispatcher.dispatchNext(player);
player.seekToNext();
} else if (previousButton == view) {
controlDispatcher.dispatchPrevious(player);
player.seekToPrevious();
} else if (fastForwardButton == view) {
if (player.getPlaybackState() != Player.STATE_ENDED) {
controlDispatcher.dispatchFastForward(player);
player.seekForward();
}
} else if (rewindButton == view) {
controlDispatcher.dispatchRewind(player);
player.seekBack();
} else if (playButton == view) {
dispatchPlay(player);
} else if (pauseButton == view) {
dispatchPause(player);
} else if (repeatToggleButton == view) {
controlDispatcher.dispatchSetRepeatMode(
player, RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
player.setRepeatMode(
RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
} else if (shuffleButton == view) {
controlDispatcher.dispatchSetShuffleModeEnabled(player, !player.getShuffleModeEnabled());
player.setShuffleModeEnabled(!player.getShuffleModeEnabled());
}
}
}

View File

@ -52,8 +52,6 @@ import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.media.app.NotificationCompat.MediaStyle;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.util.NotificationUtil;
import com.google.android.exoplayer2.util.Util;
@ -682,7 +680,6 @@ public class PlayerNotificationManager {
@Nullable private NotificationCompat.Builder builder;
@Nullable private List<NotificationCompat.Action> builderActions;
@Nullable private Player player;
private ControlDispatcher controlDispatcher;
private boolean isNotificationStarted;
private int currentNotificationTag;
@Nullable private MediaSessionCompat.Token mediaSessionToken;
@ -731,7 +728,6 @@ public class PlayerNotificationManager {
this.customActionReceiver = customActionReceiver;
this.smallIconResourceId = smallIconResourceId;
this.groupKey = groupKey;
controlDispatcher = new DefaultControlDispatcher();
instanceId = instanceIdCounter++;
// This fails the nullness checker because handleMessage() is 'called' while `this` is still
// @UnderInitialization. No tasks are scheduled on mainHandler before the constructor completes,
@ -1308,10 +1304,8 @@ public class PlayerNotificationManager {
*/
protected List<String> getActions(Player player) {
boolean enablePrevious = player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS);
boolean enableRewind =
player.isCommandAvailable(COMMAND_SEEK_BACK) && controlDispatcher.isRewindEnabled();
boolean enableFastForward =
player.isCommandAvailable(COMMAND_SEEK_FORWARD) && controlDispatcher.isFastForwardEnabled();
boolean enableRewind = player.isCommandAvailable(COMMAND_SEEK_BACK);
boolean enableFastForward = player.isCommandAvailable(COMMAND_SEEK_FORWARD);
boolean enableNext = player.isCommandAvailable(COMMAND_SEEK_TO_NEXT);
List<String> stringActions = new ArrayList<>();
@ -1535,23 +1529,23 @@ public class PlayerNotificationManager {
String action = intent.getAction();
if (ACTION_PLAY.equals(action)) {
if (player.getPlaybackState() == Player.STATE_IDLE) {
controlDispatcher.dispatchPrepare(player);
player.prepare();
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
player.seekToDefaultPosition(player.getCurrentWindowIndex());
}
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ true);
player.play();
} else if (ACTION_PAUSE.equals(action)) {
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ false);
player.pause();
} else if (ACTION_PREVIOUS.equals(action)) {
controlDispatcher.dispatchPrevious(player);
player.seekToPrevious();
} else if (ACTION_REWIND.equals(action)) {
controlDispatcher.dispatchRewind(player);
player.seekBack();
} else if (ACTION_FAST_FORWARD.equals(action)) {
controlDispatcher.dispatchFastForward(player);
player.seekForward();
} else if (ACTION_NEXT.equals(action)) {
controlDispatcher.dispatchNext(player);
player.seekToNext();
} else if (ACTION_STOP.equals(action)) {
controlDispatcher.dispatchStop(player, /* reset= */ true);
player.stop(/* reset= */ true);
} else if (ACTION_DISMISS.equals(action)) {
stopNotification(/* dismissedByUser= */ true);
} else if (action != null

View File

@ -59,8 +59,6 @@ import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.ForwardingPlayer;
import com.google.android.exoplayer2.Player;
@ -409,7 +407,6 @@ public class StyledPlayerControlView extends FrameLayout {
private final String fullScreenEnterContentDescription;
@Nullable private Player player;
private ControlDispatcher controlDispatcher;
@Nullable private ProgressUpdateListener progressUpdateListener;
@Nullable private OnFullScreenModeChangedListener onFullScreenModeChangedListener;
@ -543,7 +540,6 @@ public class StyledPlayerControlView extends FrameLayout {
playedAdGroups = new boolean[0];
extraAdGroupTimesMs = new long[0];
extraPlayedAdGroups = new boolean[0];
controlDispatcher = new DefaultControlDispatcher();
updateProgressAction = this::updateProgress;
durationView = findViewById(R.id.exo_duration);
@ -916,13 +912,13 @@ public class StyledPlayerControlView extends FrameLayout {
@Player.RepeatMode int currentMode = player.getRepeatMode();
if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
&& currentMode != Player.REPEAT_MODE_OFF) {
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_OFF);
player.setRepeatMode(Player.REPEAT_MODE_OFF);
} else if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_ONE
&& currentMode == Player.REPEAT_MODE_ALL) {
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_ONE);
player.setRepeatMode(Player.REPEAT_MODE_ONE);
} else if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL
&& currentMode == Player.REPEAT_MODE_ONE) {
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_ALL);
player.setRepeatMode(Player.REPEAT_MODE_ALL);
}
}
controlViewLayoutManager.setShowButton(
@ -1106,11 +1102,8 @@ public class StyledPlayerControlView extends FrameLayout {
if (player != null) {
enableSeeking = player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM);
enablePrevious = player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS);
enableRewind =
player.isCommandAvailable(COMMAND_SEEK_BACK) && controlDispatcher.isRewindEnabled();
enableFastForward =
player.isCommandAvailable(COMMAND_SEEK_FORWARD)
&& controlDispatcher.isFastForwardEnabled();
enableRewind = player.isCommandAvailable(COMMAND_SEEK_BACK);
enableFastForward = player.isCommandAvailable(COMMAND_SEEK_FORWARD);
enableNext = player.isCommandAvailable(COMMAND_SEEK_TO_NEXT);
}
@ -1132,9 +1125,7 @@ public class StyledPlayerControlView extends FrameLayout {
private void updateRewindButton() {
long rewindMs =
controlDispatcher instanceof DefaultControlDispatcher && player != null
? ((DefaultControlDispatcher) controlDispatcher).getRewindIncrementMs(player)
: C.DEFAULT_SEEK_BACK_INCREMENT_MS;
player != null ? player.getSeekBackIncrement() : C.DEFAULT_SEEK_BACK_INCREMENT_MS;
int rewindSec = (int) (rewindMs / 1_000);
if (rewindButtonTextView != null) {
rewindButtonTextView.setText(String.valueOf(rewindSec));
@ -1148,9 +1139,7 @@ public class StyledPlayerControlView extends FrameLayout {
private void updateFastForwardButton() {
long fastForwardMs =
controlDispatcher instanceof DefaultControlDispatcher && player != null
? ((DefaultControlDispatcher) controlDispatcher).getFastForwardIncrementMs(player)
: C.DEFAULT_SEEK_FORWARD_INCREMENT_MS;
player != null ? player.getSeekForwardIncrement() : C.DEFAULT_SEEK_FORWARD_INCREMENT_MS;
int fastForwardSec = (int) (fastForwardMs / 1_000);
if (fastForwardButtonTextView != null) {
fastForwardButtonTextView.setText(String.valueOf(fastForwardSec));
@ -1429,8 +1418,7 @@ public class StyledPlayerControlView extends FrameLayout {
if (player == null) {
return;
}
controlDispatcher.dispatchSetPlaybackParameters(
player, player.getPlaybackParameters().withSpeed(speed));
player.setPlaybackParameters(player.getPlaybackParameters().withSpeed(speed));
}
/* package */ void requestPlayPauseFocus() {
@ -1472,8 +1460,8 @@ public class StyledPlayerControlView extends FrameLayout {
updateProgress();
}
private boolean seekTo(Player player, int windowIndex, long positionMs) {
return controlDispatcher.dispatchSeekTo(player, windowIndex, positionMs);
private void seekTo(Player player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
}
private void onFullScreenButtonClicked(View v) {
@ -1554,10 +1542,10 @@ public class StyledPlayerControlView extends FrameLayout {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
if (player.getPlaybackState() != Player.STATE_ENDED) {
controlDispatcher.dispatchFastForward(player);
player.seekForward();
}
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {
controlDispatcher.dispatchRewind(player);
player.seekBack();
} else if (event.getRepeatCount() == 0) {
switch (keyCode) {
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
@ -1571,10 +1559,10 @@ public class StyledPlayerControlView extends FrameLayout {
dispatchPause(player);
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
controlDispatcher.dispatchNext(player);
player.seekToNext();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
controlDispatcher.dispatchPrevious(player);
player.seekToPrevious();
break;
default:
break;
@ -1633,15 +1621,15 @@ public class StyledPlayerControlView extends FrameLayout {
private void dispatchPlay(Player player) {
@State int state = player.getPlaybackState();
if (state == Player.STATE_IDLE) {
controlDispatcher.dispatchPrepare(player);
player.prepare();
} else if (state == Player.STATE_ENDED) {
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
}
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ true);
player.play();
}
private void dispatchPause(Player player) {
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ false);
player.pause();
}
@SuppressLint("InlinedApi")
@ -1784,22 +1772,22 @@ public class StyledPlayerControlView extends FrameLayout {
}
controlViewLayoutManager.resetHideCallbacks();
if (nextButton == view) {
controlDispatcher.dispatchNext(player);
player.seekToNext();
} else if (previousButton == view) {
controlDispatcher.dispatchPrevious(player);
player.seekToPrevious();
} else if (fastForwardButton == view) {
if (player.getPlaybackState() != Player.STATE_ENDED) {
controlDispatcher.dispatchFastForward(player);
player.seekForward();
}
} else if (rewindButton == view) {
controlDispatcher.dispatchRewind(player);
player.seekBack();
} else if (playPauseButton == view) {
dispatchPlayPause(player);
} else if (repeatToggleButton == view) {
controlDispatcher.dispatchSetRepeatMode(
player, RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
player.setRepeatMode(
RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
} else if (shuffleButton == view) {
controlDispatcher.dispatchSetShuffleModeEnabled(player, !player.getShuffleModeEnabled());
player.setShuffleModeEnabled(!player.getShuffleModeEnabled());
} else if (settingsButton == view) {
controlViewLayoutManager.removeHideCallbacks();
displaySettingsWindow(settingsAdapter);