Log warning with stack trace if player is accessed from the wrong thread.

This doesn't break apps which violate this policy. But it creates a clear
warning which is also likely to be reported in analytics tools.

Issue:#4463

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=213442510
This commit is contained in:
tonihei 2018-09-18 06:57:40 -07:00 committed by Oliver Woodman
parent db33b3bbd1
commit a92344ac9e

View file

@ -109,6 +109,7 @@ public class SimpleExoPlayer
private List<Cue> currentCues;
private VideoFrameMetadataListener videoFrameMetadataListener;
private CameraMotionListener cameraMotionListener;
private boolean hasNotifiedFullWrongThreadWarning;
/**
* @param context A {@link Context}.
@ -266,6 +267,7 @@ public class SimpleExoPlayer
*/
@Override
public void setVideoScalingMode(@C.VideoScalingMode int videoScalingMode) {
verifyApplicationThread();
this.videoScalingMode = videoScalingMode;
for (Renderer renderer : renderers) {
if (renderer.getTrackType() == C.TRACK_TYPE_VIDEO) {
@ -285,11 +287,13 @@ public class SimpleExoPlayer
@Override
public void clearVideoSurface() {
verifyApplicationThread();
setVideoSurface(null);
}
@Override
public void clearVideoSurface(Surface surface) {
verifyApplicationThread();
if (surface != null && surface == this.surface) {
setVideoSurface(null);
}
@ -297,6 +301,7 @@ public class SimpleExoPlayer
@Override
public void setVideoSurface(@Nullable Surface surface) {
verifyApplicationThread();
removeSurfaceCallbacks();
setVideoSurfaceInternal(surface, false);
int newSurfaceSize = surface == null ? 0 : C.LENGTH_UNSET;
@ -305,6 +310,7 @@ public class SimpleExoPlayer
@Override
public void setVideoSurfaceHolder(SurfaceHolder surfaceHolder) {
verifyApplicationThread();
removeSurfaceCallbacks();
this.surfaceHolder = surfaceHolder;
if (surfaceHolder == null) {
@ -326,6 +332,7 @@ public class SimpleExoPlayer
@Override
public void clearVideoSurfaceHolder(SurfaceHolder surfaceHolder) {
verifyApplicationThread();
if (surfaceHolder != null && surfaceHolder == this.surfaceHolder) {
setVideoSurfaceHolder(null);
}
@ -343,6 +350,7 @@ public class SimpleExoPlayer
@Override
public void setVideoTextureView(TextureView textureView) {
verifyApplicationThread();
removeSurfaceCallbacks();
this.textureView = textureView;
if (textureView == null) {
@ -367,6 +375,7 @@ public class SimpleExoPlayer
@Override
public void clearVideoTextureView(TextureView textureView) {
verifyApplicationThread();
if (textureView != null && textureView == this.textureView) {
setVideoTextureView(null);
}
@ -389,6 +398,7 @@ public class SimpleExoPlayer
@Override
public void setAudioAttributes(AudioAttributes audioAttributes, boolean handleAudioFocus) {
verifyApplicationThread();
if (!Util.areEqual(this.audioAttributes, audioAttributes)) {
this.audioAttributes = audioAttributes;
for (Renderer renderer : renderers) {
@ -424,6 +434,7 @@ public class SimpleExoPlayer
@Override
public void setAuxEffectInfo(AuxEffectInfo auxEffectInfo) {
verifyApplicationThread();
for (Renderer renderer : renderers) {
if (renderer.getTrackType() == C.TRACK_TYPE_AUDIO) {
player
@ -442,6 +453,7 @@ public class SimpleExoPlayer
@Override
public void setVolume(float audioVolume) {
verifyApplicationThread();
audioVolume = Util.constrainValue(audioVolume, /* min= */ 0, /* max= */ 1);
if (this.audioVolume == audioVolume) {
return;
@ -500,6 +512,7 @@ public class SimpleExoPlayer
* @param listener The listener to be added.
*/
public void addAnalyticsListener(AnalyticsListener listener) {
verifyApplicationThread();
analyticsCollector.addListener(listener);
}
@ -509,6 +522,7 @@ public class SimpleExoPlayer
* @param listener The listener to be removed.
*/
public void removeAnalyticsListener(AnalyticsListener listener) {
verifyApplicationThread();
analyticsCollector.removeListener(listener);
}
@ -571,6 +585,7 @@ public class SimpleExoPlayer
@Override
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
verifyApplicationThread();
videoFrameMetadataListener = listener;
for (Renderer renderer : renderers) {
if (renderer.getTrackType() == C.TRACK_TYPE_VIDEO) {
@ -585,6 +600,7 @@ public class SimpleExoPlayer
@Override
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
verifyApplicationThread();
if (videoFrameMetadataListener != listener) {
return;
}
@ -601,6 +617,7 @@ public class SimpleExoPlayer
@Override
public void setCameraMotionListener(CameraMotionListener listener) {
verifyApplicationThread();
cameraMotionListener = listener;
for (Renderer renderer : renderers) {
if (renderer.getTrackType() == C.TRACK_TYPE_CAMERA_MOTION) {
@ -615,6 +632,7 @@ public class SimpleExoPlayer
@Override
public void clearCameraMotionListener(CameraMotionListener listener) {
verifyApplicationThread();
if (cameraMotionListener != listener) {
return;
}
@ -814,26 +832,31 @@ public class SimpleExoPlayer
@Override
public void addListener(Player.EventListener listener) {
verifyApplicationThread();
player.addListener(listener);
}
@Override
public void removeListener(Player.EventListener listener) {
verifyApplicationThread();
player.removeListener(listener);
}
@Override
public int getPlaybackState() {
verifyApplicationThread();
return player.getPlaybackState();
}
@Override
public @Nullable ExoPlaybackException getPlaybackError() {
verifyApplicationThread();
return player.getPlaybackError();
}
@Override
public void retry() {
verifyApplicationThread();
if (mediaSource != null
&& (getPlaybackError() != null || getPlaybackState() == Player.STATE_IDLE)) {
prepare(mediaSource, /* resetPosition= */ false, /* resetState= */ false);
@ -847,6 +870,7 @@ public class SimpleExoPlayer
@Override
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
verifyApplicationThread();
if (this.mediaSource != null) {
this.mediaSource.removeEventListener(analyticsCollector);
analyticsCollector.resetForNewMediaSource();
@ -861,6 +885,7 @@ public class SimpleExoPlayer
@Override
public void setPlayWhenReady(boolean playWhenReady) {
verifyApplicationThread();
@AudioFocusManager.PlayerCommand
int playerCommand = audioFocusManager.handleSetPlayWhenReady(playWhenReady, getPlaybackState());
updatePlayWhenReady(playWhenReady, playerCommand);
@ -868,80 +893,95 @@ public class SimpleExoPlayer
@Override
public boolean getPlayWhenReady() {
verifyApplicationThread();
return player.getPlayWhenReady();
}
@Override
public @RepeatMode int getRepeatMode() {
verifyApplicationThread();
return player.getRepeatMode();
}
@Override
public void setRepeatMode(@RepeatMode int repeatMode) {
verifyApplicationThread();
player.setRepeatMode(repeatMode);
}
@Override
public void setShuffleModeEnabled(boolean shuffleModeEnabled) {
verifyApplicationThread();
player.setShuffleModeEnabled(shuffleModeEnabled);
}
@Override
public boolean getShuffleModeEnabled() {
verifyApplicationThread();
return player.getShuffleModeEnabled();
}
@Override
public boolean isLoading() {
verifyApplicationThread();
return player.isLoading();
}
@Override
public void seekToDefaultPosition() {
verifyApplicationThread();
analyticsCollector.notifySeekStarted();
player.seekToDefaultPosition();
}
@Override
public void seekToDefaultPosition(int windowIndex) {
verifyApplicationThread();
analyticsCollector.notifySeekStarted();
player.seekToDefaultPosition(windowIndex);
}
@Override
public void seekTo(long positionMs) {
verifyApplicationThread();
analyticsCollector.notifySeekStarted();
player.seekTo(positionMs);
}
@Override
public void seekTo(int windowIndex, long positionMs) {
verifyApplicationThread();
analyticsCollector.notifySeekStarted();
player.seekTo(windowIndex, positionMs);
}
@Override
public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) {
verifyApplicationThread();
player.setPlaybackParameters(playbackParameters);
}
@Override
public PlaybackParameters getPlaybackParameters() {
verifyApplicationThread();
return player.getPlaybackParameters();
}
@Override
public void setSeekParameters(@Nullable SeekParameters seekParameters) {
verifyApplicationThread();
player.setSeekParameters(seekParameters);
}
@Override
public SeekParameters getSeekParameters() {
verifyApplicationThread();
return player.getSeekParameters();
}
@Override
public @Nullable Object getCurrentTag() {
verifyApplicationThread();
return player.getCurrentTag();
}
@ -952,6 +992,7 @@ public class SimpleExoPlayer
@Override
public void stop(boolean reset) {
verifyApplicationThread();
player.stop(reset);
if (mediaSource != null) {
mediaSource.removeEventListener(analyticsCollector);
@ -992,6 +1033,7 @@ public class SimpleExoPlayer
@Override
public PlayerMessage createMessage(PlayerMessage.Target target) {
verifyApplicationThread();
return player.createMessage(target);
}
@ -1004,116 +1046,139 @@ public class SimpleExoPlayer
@Override
public int getRendererCount() {
verifyApplicationThread();
return player.getRendererCount();
}
@Override
public int getRendererType(int index) {
verifyApplicationThread();
return player.getRendererType(index);
}
@Override
public TrackGroupArray getCurrentTrackGroups() {
verifyApplicationThread();
return player.getCurrentTrackGroups();
}
@Override
public TrackSelectionArray getCurrentTrackSelections() {
verifyApplicationThread();
return player.getCurrentTrackSelections();
}
@Override
public Timeline getCurrentTimeline() {
verifyApplicationThread();
return player.getCurrentTimeline();
}
@Override
public @Nullable Object getCurrentManifest() {
verifyApplicationThread();
return player.getCurrentManifest();
}
@Override
public int getCurrentPeriodIndex() {
verifyApplicationThread();
return player.getCurrentPeriodIndex();
}
@Override
public int getCurrentWindowIndex() {
verifyApplicationThread();
return player.getCurrentWindowIndex();
}
@Override
public int getNextWindowIndex() {
verifyApplicationThread();
return player.getNextWindowIndex();
}
@Override
public int getPreviousWindowIndex() {
verifyApplicationThread();
return player.getPreviousWindowIndex();
}
@Override
public long getDuration() {
verifyApplicationThread();
return player.getDuration();
}
@Override
public long getCurrentPosition() {
verifyApplicationThread();
return player.getCurrentPosition();
}
@Override
public long getBufferedPosition() {
verifyApplicationThread();
return player.getBufferedPosition();
}
@Override
public int getBufferedPercentage() {
verifyApplicationThread();
return player.getBufferedPercentage();
}
@Override
public long getTotalBufferedDuration() {
verifyApplicationThread();
return player.getTotalBufferedDuration();
}
@Override
public boolean isCurrentWindowDynamic() {
verifyApplicationThread();
return player.isCurrentWindowDynamic();
}
@Override
public boolean isCurrentWindowSeekable() {
verifyApplicationThread();
return player.isCurrentWindowSeekable();
}
@Override
public boolean isPlayingAd() {
verifyApplicationThread();
return player.isPlayingAd();
}
@Override
public int getCurrentAdGroupIndex() {
verifyApplicationThread();
return player.getCurrentAdGroupIndex();
}
@Override
public int getCurrentAdIndexInAdGroup() {
verifyApplicationThread();
return player.getCurrentAdIndexInAdGroup();
}
@Override
public long getContentDuration() {
verifyApplicationThread();
return player.getContentDuration();
}
@Override
public long getContentPosition() {
verifyApplicationThread();
return player.getContentPosition();
}
@Override
public long getContentBufferedPosition() {
verifyApplicationThread();
return player.getContentBufferedPosition();
}
@ -1183,12 +1248,23 @@ public class SimpleExoPlayer
private void updatePlayWhenReady(
boolean playWhenReady, @AudioFocusManager.PlayerCommand int playerCommand) {
player.setPlayWhenReady(
playWhenReady && playerCommand != AudioFocusManager.PLAYER_COMMAND_DO_NOT_PLAY,
playerCommand != AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY);
}
private void verifyApplicationThread() {
if (Looper.myLooper() != getApplicationLooper()) {
Log.w(
TAG,
"Player is accessed on the wrong thread. See "
+ "https://google.github.io/ExoPlayer/faqs.html#"
+ "what-do-player-is-accessed-on-the-wrong-thread-warnings-mean",
hasNotifiedFullWrongThreadWarning ? null : new IllegalStateException());
hasNotifiedFullWrongThreadWarning = true;
}
}
private final class ComponentListener
implements VideoRendererEventListener,
AudioRendererEventListener,