mirror of
https://github.com/androidx/media.git
synced 2025-05-17 04:29:55 +08:00
Make LeanbackPlayerAdapter use a ControlDispatcher + Misc cleanup
1. Make LeanbackPlayerAdapter use a ControlDispatcher. This allows apps to suppress control events in some circumstances, and is in-line with our mobile controls. 2. Misc simplifications and cleanup to LeanbackPlayerAdapter. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=166852816
This commit is contained in:
parent
44dc3c3ab3
commit
55e928f75a
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.ext.leanback;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v17.leanback.R;
|
||||
import android.support.v17.leanback.media.PlaybackGlueHost;
|
||||
import android.support.v17.leanback.media.PlayerAdapter;
|
||||
@ -25,6 +26,8 @@ import android.util.Pair;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ControlDispatcher;
|
||||
import com.google.android.exoplayer2.DefaultControlDispatcher;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
@ -48,13 +51,13 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
private final SimpleExoPlayer player;
|
||||
private final Handler handler;
|
||||
private final ComponentListener componentListener;
|
||||
private final Runnable updatePlayerRunnable;
|
||||
private final Runnable updateProgressRunnable;
|
||||
|
||||
private ControlDispatcher controlDispatcher;
|
||||
private ErrorMessageProvider<? super ExoPlaybackException> errorMessageProvider;
|
||||
private SurfaceHolderGlueHost surfaceHolderGlueHost;
|
||||
private boolean initialized;
|
||||
private boolean hasSurface;
|
||||
private boolean isBuffering;
|
||||
private boolean lastNotifiedPreparedState;
|
||||
|
||||
/**
|
||||
* Builds an instance. Note that the {@code PlayerAdapter} does not manage the lifecycle of the
|
||||
@ -70,7 +73,8 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
this.player = player;
|
||||
handler = new Handler();
|
||||
componentListener = new ComponentListener();
|
||||
updatePlayerRunnable = new Runnable() {
|
||||
controlDispatcher = new DefaultControlDispatcher();
|
||||
updateProgressRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Callback callback = getCallback();
|
||||
@ -81,34 +85,15 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToHost(PlaybackGlueHost host) {
|
||||
if (host instanceof SurfaceHolderGlueHost) {
|
||||
surfaceHolderGlueHost = ((SurfaceHolderGlueHost) host);
|
||||
surfaceHolderGlueHost.setSurfaceHolderCallback(componentListener);
|
||||
}
|
||||
notifyListeners();
|
||||
player.addListener(componentListener);
|
||||
player.addVideoListener(componentListener);
|
||||
}
|
||||
|
||||
private void notifyListeners() {
|
||||
boolean oldIsPrepared = isPrepared();
|
||||
int playbackState = player.getPlaybackState();
|
||||
boolean isInitialized = playbackState != Player.STATE_IDLE;
|
||||
isBuffering = playbackState == Player.STATE_BUFFERING;
|
||||
boolean hasEnded = playbackState == Player.STATE_ENDED;
|
||||
|
||||
initialized = isInitialized;
|
||||
Callback callback = getCallback();
|
||||
if (oldIsPrepared != isPrepared()) {
|
||||
callback.onPreparedStateChanged(this);
|
||||
}
|
||||
callback.onPlayStateChanged(this);
|
||||
callback.onBufferingStateChanged(this, isBuffering || !initialized);
|
||||
if (hasEnded) {
|
||||
callback.onPlayCompleted(this);
|
||||
}
|
||||
/**
|
||||
* Sets the {@link ControlDispatcher}.
|
||||
*
|
||||
* @param controlDispatcher The {@link ControlDispatcher}, or null to use
|
||||
* {@link DefaultControlDispatcher}.
|
||||
*/
|
||||
public void setControlDispatcher(@Nullable ControlDispatcher controlDispatcher) {
|
||||
this.controlDispatcher = controlDispatcher == null ? new DefaultControlDispatcher()
|
||||
: controlDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,6 +106,19 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
this.errorMessageProvider = errorMessageProvider;
|
||||
}
|
||||
|
||||
// PlayerAdapter implementation.
|
||||
|
||||
@Override
|
||||
public void onAttachedToHost(PlaybackGlueHost host) {
|
||||
if (host instanceof SurfaceHolderGlueHost) {
|
||||
surfaceHolderGlueHost = ((SurfaceHolderGlueHost) host);
|
||||
surfaceHolderGlueHost.setSurfaceHolderCallback(componentListener);
|
||||
}
|
||||
notifyStateChanged();
|
||||
player.addListener(componentListener);
|
||||
player.addVideoListener(componentListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromHost() {
|
||||
player.removeListener(componentListener);
|
||||
@ -129,56 +127,59 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
surfaceHolderGlueHost.setSurfaceHolderCallback(null);
|
||||
surfaceHolderGlueHost = null;
|
||||
}
|
||||
initialized = false;
|
||||
hasSurface = false;
|
||||
Callback callback = getCallback();
|
||||
callback.onBufferingStateChanged(this, false);
|
||||
callback.onPlayStateChanged(this);
|
||||
callback.onPreparedStateChanged(this);
|
||||
maybeNotifyPreparedStateChanged(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressUpdatingEnabled(final boolean enabled) {
|
||||
handler.removeCallbacks(updatePlayerRunnable);
|
||||
public void setProgressUpdatingEnabled(boolean enabled) {
|
||||
handler.removeCallbacks(updateProgressRunnable);
|
||||
if (enabled) {
|
||||
handler.post(updatePlayerRunnable);
|
||||
handler.post(updateProgressRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return initialized && player.getPlayWhenReady();
|
||||
int playbackState = player.getPlaybackState();
|
||||
return playbackState != Player.STATE_IDLE && playbackState != Player.STATE_ENDED
|
||||
&& player.getPlayWhenReady();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
long durationMs = player.getDuration();
|
||||
return durationMs != C.TIME_UNSET ? durationMs : -1;
|
||||
return durationMs == C.TIME_UNSET ? -1 : durationMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentPosition() {
|
||||
return initialized ? player.getCurrentPosition() : -1;
|
||||
return player.getPlaybackState() == Player.STATE_IDLE ? -1 : player.getCurrentPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
if (player.getPlaybackState() == Player.STATE_ENDED) {
|
||||
player.seekToDefaultPosition();
|
||||
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
|
||||
}
|
||||
if (controlDispatcher.dispatchSetPlayWhenReady(player, true)) {
|
||||
getCallback().onPlayStateChanged(this);
|
||||
}
|
||||
player.setPlayWhenReady(true);
|
||||
getCallback().onPlayStateChanged(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
player.setPlayWhenReady(false);
|
||||
getCallback().onPlayStateChanged(this);
|
||||
if (controlDispatcher.dispatchSetPlayWhenReady(player, false)) {
|
||||
getCallback().onPlayStateChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekTo(long positionMs) {
|
||||
player.seekTo(positionMs);
|
||||
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), positionMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -188,13 +189,35 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
|
||||
@Override
|
||||
public boolean isPrepared() {
|
||||
return initialized && (surfaceHolderGlueHost == null || hasSurface);
|
||||
return player.getPlaybackState() != Player.STATE_IDLE
|
||||
&& (surfaceHolderGlueHost == null || hasSurface);
|
||||
}
|
||||
|
||||
private void setVideoSurface(Surface surface) {
|
||||
// Internal methods.
|
||||
|
||||
/* package */ void setVideoSurface(Surface surface) {
|
||||
hasSurface = surface != null;
|
||||
player.setVideoSurface(surface);
|
||||
getCallback().onPreparedStateChanged(this);
|
||||
maybeNotifyPreparedStateChanged(getCallback());
|
||||
}
|
||||
|
||||
/* package */ void notifyStateChanged() {
|
||||
int playbackState = player.getPlaybackState();
|
||||
Callback callback = getCallback();
|
||||
maybeNotifyPreparedStateChanged(callback);
|
||||
callback.onPlayStateChanged(this);
|
||||
callback.onBufferingStateChanged(this, playbackState == Player.STATE_BUFFERING);
|
||||
if (playbackState == Player.STATE_ENDED) {
|
||||
callback.onPlayCompleted(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeNotifyPreparedStateChanged(Callback callback) {
|
||||
boolean isPrepared = isPrepared();
|
||||
if (lastNotifiedPreparedState != isPrepared) {
|
||||
lastNotifiedPreparedState = isPrepared;
|
||||
callback.onPreparedStateChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ComponentListener implements Player.EventListener,
|
||||
@ -208,7 +231,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@ -221,7 +244,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
notifyListeners();
|
||||
notifyStateChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -292,4 +315,3 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Dispatches operations to the {@link Player}.
|
||||
* <p>
|
||||
* Implementations may choose to suppress (e.g. prevent playback from resuming if audio focus is
|
||||
* denied) or modify (e.g. change the seek position to prevent a user from seeking past a
|
||||
* non-skippable advert) operations.
|
||||
*/
|
||||
public interface ControlDispatcher {
|
||||
|
||||
/**
|
||||
* 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#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);
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Default {@link ControlDispatcher} that dispatches all operations to the player without
|
||||
* modification.
|
||||
*/
|
||||
public class DefaultControlDispatcher implements ControlDispatcher {
|
||||
|
||||
@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 dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode) {
|
||||
player.setRepeatMode(repeatMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled) {
|
||||
player.setShuffleModeEnabled(shuffleModeEnabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -34,7 +34,6 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
@ -180,6 +179,12 @@ public class PlaybackControlView extends FrameLayout {
|
||||
ExoPlayerLibraryInfo.registerModule("goog.exo.ui");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link com.google.android.exoplayer2.ControlDispatcher}.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ControlDispatcher extends com.google.android.exoplayer2.ControlDispatcher {}
|
||||
|
||||
/**
|
||||
* Listener to be notified about changes of the visibility of the UI control.
|
||||
*/
|
||||
@ -194,86 +199,13 @@ public class PlaybackControlView extends FrameLayout {
|
||||
|
||||
}
|
||||
|
||||
private static final class DefaultControlDispatcher
|
||||
extends com.google.android.exoplayer2.DefaultControlDispatcher implements ControlDispatcher {}
|
||||
/**
|
||||
* Dispatches operations to the {@link Player}.
|
||||
* <p>
|
||||
* Implementations may choose to suppress (e.g. prevent playback from resuming if audio focus is
|
||||
* denied) or modify (e.g. change the seek position to prevent a user from seeking past a
|
||||
* non-skippable advert) operations.
|
||||
* @deprecated Use {@link com.google.android.exoplayer2.DefaultControlDispatcher}.
|
||||
*/
|
||||
public interface ControlDispatcher {
|
||||
|
||||
/**
|
||||
* 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#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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Default {@link ControlDispatcher} that dispatches operations to the player without
|
||||
* modification.
|
||||
*/
|
||||
public static final ControlDispatcher DEFAULT_CONTROL_DISPATCHER = new ControlDispatcher() {
|
||||
|
||||
@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 dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode) {
|
||||
player.setRepeatMode(repeatMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled) {
|
||||
player.setShuffleModeEnabled(shuffleModeEnabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
@Deprecated
|
||||
public static final ControlDispatcher DEFAULT_CONTROL_DISPATCHER = new DefaultControlDispatcher();
|
||||
|
||||
/**
|
||||
* The default fast forward increment, in milliseconds.
|
||||
@ -325,7 +257,7 @@ public class PlaybackControlView extends FrameLayout {
|
||||
private final String repeatAllButtonContentDescription;
|
||||
|
||||
private Player player;
|
||||
private ControlDispatcher controlDispatcher;
|
||||
private com.google.android.exoplayer2.ControlDispatcher controlDispatcher;
|
||||
private VisibilityListener visibilityListener;
|
||||
|
||||
private boolean isAttachedToWindow;
|
||||
@ -400,7 +332,7 @@ public class PlaybackControlView extends FrameLayout {
|
||||
extraAdGroupTimesMs = new long[0];
|
||||
extraPlayedAdGroups = new boolean[0];
|
||||
componentListener = new ComponentListener();
|
||||
controlDispatcher = DEFAULT_CONTROL_DISPATCHER;
|
||||
controlDispatcher = new com.google.android.exoplayer2.DefaultControlDispatcher();
|
||||
|
||||
LayoutInflater.from(context).inflate(controllerLayoutId, this);
|
||||
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
|
||||
@ -534,14 +466,15 @@ public class PlaybackControlView extends FrameLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link ControlDispatcher}.
|
||||
* Sets the {@link com.google.android.exoplayer2.ControlDispatcher}.
|
||||
*
|
||||
* @param controlDispatcher The {@link ControlDispatcher}, or null to use
|
||||
* {@link #DEFAULT_CONTROL_DISPATCHER}.
|
||||
* @param controlDispatcher The {@link com.google.android.exoplayer2.ControlDispatcher}, or null
|
||||
* to use {@link com.google.android.exoplayer2.DefaultControlDispatcher}.
|
||||
*/
|
||||
public void setControlDispatcher(ControlDispatcher controlDispatcher) {
|
||||
this.controlDispatcher = controlDispatcher == null ? DEFAULT_CONTROL_DISPATCHER
|
||||
: controlDispatcher;
|
||||
public void setControlDispatcher(
|
||||
@Nullable com.google.android.exoplayer2.ControlDispatcher controlDispatcher) {
|
||||
this.controlDispatcher = controlDispatcher == null
|
||||
? new com.google.android.exoplayer2.DefaultControlDispatcher() : controlDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,8 @@ import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ControlDispatcher;
|
||||
import com.google.android.exoplayer2.DefaultControlDispatcher;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
@ -47,7 +49,6 @@ import com.google.android.exoplayer2.text.TextOutput;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||
import com.google.android.exoplayer2.ui.PlaybackControlView.ControlDispatcher;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.RepeatModeUtil;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -616,9 +617,9 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
||||
* Sets the {@link ControlDispatcher}.
|
||||
*
|
||||
* @param controlDispatcher The {@link ControlDispatcher}, or null to use
|
||||
* {@link PlaybackControlView#DEFAULT_CONTROL_DISPATCHER}.
|
||||
* {@link DefaultControlDispatcher}.
|
||||
*/
|
||||
public void setControlDispatcher(ControlDispatcher controlDispatcher) {
|
||||
public void setControlDispatcher(@Nullable ControlDispatcher controlDispatcher) {
|
||||
Assertions.checkState(controller != null);
|
||||
controller.setControlDispatcher(controlDispatcher);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user