Merge listeners in ExoPlayerImpl and add missing constants

There are two sets of listeners in ExoPlayerImpl at the moment,
which can be merged together to use a single ListenerSet. This has
the added advantage that the events that were previously sent
through the ArraySet get additional guarantees provided by ListenerSet
(e.g. correct event ordering and onEvents triggered).

Also add missing constants for onEvents to ensure all Player.Listener
methods have an corresponding constant.

#minor-release

PiperOrigin-RevId: 427415349
This commit is contained in:
tonihei 2022-02-09 10:11:28 +00:00 committed by Ian Baker
parent 64b56cf184
commit dc0a293c3f
3 changed files with 191 additions and 119 deletions

View File

@ -714,7 +714,12 @@ public interface Player {
*/ */
default void onMediaMetadataChanged(MediaMetadata mediaMetadata) {} default void onMediaMetadataChanged(MediaMetadata mediaMetadata) {}
/** Called when the playlist {@link MediaMetadata} changes. */ /**
* Called when the playlist {@link MediaMetadata} changes.
*
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*/
default void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {} default void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {}
/** /**
@ -932,6 +937,9 @@ public interface Player {
/** /**
* Called when the audio session ID changes. * Called when the audio session ID changes.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param audioSessionId The audio session ID. * @param audioSessionId The audio session ID.
*/ */
@UnstableApi @UnstableApi
@ -940,6 +948,9 @@ public interface Player {
/** /**
* Called when the audio attributes change. * Called when the audio attributes change.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param audioAttributes The audio attributes. * @param audioAttributes The audio attributes.
*/ */
default void onAudioAttributesChanged(AudioAttributes audioAttributes) {} default void onAudioAttributesChanged(AudioAttributes audioAttributes) {}
@ -947,6 +958,9 @@ public interface Player {
/** /**
* Called when the volume changes. * Called when the volume changes.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param volume The new volume, with 0 being silence and 1 being unity gain. * @param volume The new volume, with 0 being silence and 1 being unity gain.
*/ */
default void onVolumeChanged(float volume) {} default void onVolumeChanged(float volume) {}
@ -954,19 +968,40 @@ public interface Player {
/** /**
* Called when skipping silences is enabled or disabled in the audio stream. * Called when skipping silences is enabled or disabled in the audio stream.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled. * @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled.
*/ */
default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {} default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {}
/** Called when the device information changes. */ /**
* Called when the device information changes
*
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param deviceInfo The new {@link DeviceInfo}.
*/
default void onDeviceInfoChanged(DeviceInfo deviceInfo) {} default void onDeviceInfoChanged(DeviceInfo deviceInfo) {}
/** Called when the device volume or mute state changes. */ /**
* Called when the device volume or mute state changes.
*
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param volume The new device volume, with 0 being silence and 1 being unity gain.
* @param muted Whether the device is muted.
*/
default void onDeviceVolumeChanged(int volume, boolean muted) {} default void onDeviceVolumeChanged(int volume, boolean muted) {}
/** /**
* Called each time there's a change in the size of the video being rendered. * Called each time there's a change in the size of the video being rendered.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param videoSize The new size of the video. * @param videoSize The new size of the video.
*/ */
default void onVideoSizeChanged(VideoSize videoSize) {} default void onVideoSizeChanged(VideoSize videoSize) {}
@ -975,6 +1010,9 @@ public interface Player {
* Called each time there's a change in the size of the surface onto which the video is being * Called each time there's a change in the size of the surface onto which the video is being
* rendered. * rendered.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if * @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if
* the video is not rendered onto a surface. * the video is not rendered onto a surface.
* @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if * @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if
@ -985,6 +1023,9 @@ public interface Player {
/** /**
* Called when a frame is rendered for the first time since setting the surface, or since the * Called when a frame is rendered for the first time since setting the surface, or since the
* renderer was reset, or since the stream being rendered was changed. * renderer was reset, or since the stream being rendered was changed.
*
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*/ */
default void onRenderedFirstFrame() {} default void onRenderedFirstFrame() {}
@ -994,6 +1035,9 @@ public interface Player {
* <p>{@code cues} is in ascending order of priority. If any of the cue boxes overlap when * <p>{@code cues} is in ascending order of priority. If any of the cue boxes overlap when
* displayed, the {@link Cue} nearer the end of the list should be shown on top. * displayed, the {@link Cue} nearer the end of the list should be shown on top.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param cues The {@link Cue Cues}. May be empty. * @param cues The {@link Cue Cues}. May be empty.
*/ */
default void onCues(List<Cue> cues) {} default void onCues(List<Cue> cues) {}
@ -1001,6 +1045,9 @@ public interface Player {
/** /**
* Called when there is metadata associated with the current playback time. * Called when there is metadata associated with the current playback time.
* *
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param metadata The metadata. * @param metadata The metadata.
*/ */
@UnstableApi @UnstableApi
@ -1252,6 +1299,17 @@ public interface Player {
EVENT_SEEK_FORWARD_INCREMENT_CHANGED, EVENT_SEEK_FORWARD_INCREMENT_CHANGED,
EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED, EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED,
EVENT_TRACK_SELECTION_PARAMETERS_CHANGED, EVENT_TRACK_SELECTION_PARAMETERS_CHANGED,
EVENT_AUDIO_ATTRIBUTES_CHANGED,
EVENT_AUDIO_SESSION_ID,
EVENT_VOLUME_CHANGED,
EVENT_SKIP_SILENCE_ENABLED_CHANGED,
EVENT_SURFACE_SIZE_CHANGED,
EVENT_VIDEO_SIZE_CHANGED,
EVENT_RENDERED_FIRST_FRAME,
EVENT_CUES,
EVENT_METADATA,
EVENT_DEVICE_INFO_CHANGED,
EVENT_DEVICE_VOLUME_CHANGED
}) })
@interface Event {} @interface Event {}
/** {@link #getCurrentTimeline()} changed. */ /** {@link #getCurrentTimeline()} changed. */
@ -1297,6 +1355,31 @@ public interface Player {
int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = 18; int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = 18;
/** {@link #getTrackSelectionParameters()} changed. */ /** {@link #getTrackSelectionParameters()} changed. */
int EVENT_TRACK_SELECTION_PARAMETERS_CHANGED = 19; int EVENT_TRACK_SELECTION_PARAMETERS_CHANGED = 19;
/** {@link #getAudioAttributes()} changed. */
int EVENT_AUDIO_ATTRIBUTES_CHANGED = 20;
/** The audio session id was set. */
int EVENT_AUDIO_SESSION_ID = 21;
/** {@link #getVolume()} changed. */
int EVENT_VOLUME_CHANGED = 22;
/** Skipping silences in the audio stream is enabled or disabled. */
int EVENT_SKIP_SILENCE_ENABLED_CHANGED = 23;
/** The size of the surface onto which the video is being rendered changed. */
int EVENT_SURFACE_SIZE_CHANGED = 24;
/** {@link #getVideoSize()} changed. */
int EVENT_VIDEO_SIZE_CHANGED = 25;
/**
* A frame is rendered for the first time since setting the surface, or since the renderer was
* reset, or since the stream being rendered was changed.
*/
int EVENT_RENDERED_FIRST_FRAME = 26;
/** {@link #getCurrentCues()} changed. */
int EVENT_CUES = 27;
/** Metadata associated with the current playback time changed. */
int EVENT_METADATA = 28;
/** {@link #getDeviceInfo()} changed. */
int EVENT_DEVICE_INFO_CHANGED = 29;
/** {@link #getDeviceVolume()} changed. */
int EVENT_DEVICE_VOLUME_CHANGED = 30;
/** /**
* Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link * Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link

View File

@ -45,9 +45,20 @@ import static androidx.media3.common.Player.DISCONTINUITY_REASON_AUTO_TRANSITION
import static androidx.media3.common.Player.DISCONTINUITY_REASON_INTERNAL; import static androidx.media3.common.Player.DISCONTINUITY_REASON_INTERNAL;
import static androidx.media3.common.Player.DISCONTINUITY_REASON_REMOVE; import static androidx.media3.common.Player.DISCONTINUITY_REASON_REMOVE;
import static androidx.media3.common.Player.DISCONTINUITY_REASON_SEEK; import static androidx.media3.common.Player.DISCONTINUITY_REASON_SEEK;
import static androidx.media3.common.Player.EVENT_AUDIO_ATTRIBUTES_CHANGED;
import static androidx.media3.common.Player.EVENT_AUDIO_SESSION_ID;
import static androidx.media3.common.Player.EVENT_CUES;
import static androidx.media3.common.Player.EVENT_DEVICE_INFO_CHANGED;
import static androidx.media3.common.Player.EVENT_DEVICE_VOLUME_CHANGED;
import static androidx.media3.common.Player.EVENT_MEDIA_METADATA_CHANGED; import static androidx.media3.common.Player.EVENT_MEDIA_METADATA_CHANGED;
import static androidx.media3.common.Player.EVENT_METADATA;
import static androidx.media3.common.Player.EVENT_PLAYLIST_METADATA_CHANGED; import static androidx.media3.common.Player.EVENT_PLAYLIST_METADATA_CHANGED;
import static androidx.media3.common.Player.EVENT_RENDERED_FIRST_FRAME;
import static androidx.media3.common.Player.EVENT_SKIP_SILENCE_ENABLED_CHANGED;
import static androidx.media3.common.Player.EVENT_SURFACE_SIZE_CHANGED;
import static androidx.media3.common.Player.EVENT_TRACK_SELECTION_PARAMETERS_CHANGED; import static androidx.media3.common.Player.EVENT_TRACK_SELECTION_PARAMETERS_CHANGED;
import static androidx.media3.common.Player.EVENT_VIDEO_SIZE_CHANGED;
import static androidx.media3.common.Player.EVENT_VOLUME_CHANGED;
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO; import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO;
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED; import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED;
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT; import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT;
@ -191,8 +202,6 @@ import java.util.concurrent.TimeoutException;
private final ExoPlayerImplInternal internalPlayer; private final ExoPlayerImplInternal internalPlayer;
private final ListenerSet<Listener> listeners; private final ListenerSet<Listener> listeners;
// TODO(b/187152483): Remove this once all events are dispatched via ListenerSet.
private final CopyOnWriteArraySet<Listener> listenerArraySet;
private final CopyOnWriteArraySet<AudioOffloadListener> audioOffloadListeners; private final CopyOnWriteArraySet<AudioOffloadListener> audioOffloadListeners;
private final Timeline.Period period; private final Timeline.Period period;
private final Timeline.Window window; private final Timeline.Window window;
@ -320,7 +329,6 @@ import java.util.concurrent.TimeoutException;
applicationLooper, applicationLooper,
clock, clock,
(listener, flags) -> listener.onEvents(wrappingPlayer, new Events(flags))); (listener, flags) -> listener.onEvents(wrappingPlayer, new Events(flags)));
listenerArraySet = new CopyOnWriteArraySet<>();
audioOffloadListeners = new CopyOnWriteArraySet<>(); audioOffloadListeners = new CopyOnWriteArraySet<>();
mediaSourceHolderSnapshots = new ArrayList<>(); mediaSourceHolderSnapshots = new ArrayList<>();
shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */ 0); shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */ 0);
@ -1346,27 +1354,28 @@ import java.util.concurrent.TimeoutException;
} }
} }
public void setAudioAttributes(AudioAttributes audioAttributes, boolean handleAudioFocus) { public void setAudioAttributes(AudioAttributes newAudioAttributes, boolean handleAudioFocus) {
verifyApplicationThread(); verifyApplicationThread();
if (playerReleased) { if (playerReleased) {
return; return;
} }
if (!Util.areEqual(this.audioAttributes, audioAttributes)) { if (!Util.areEqual(this.audioAttributes, newAudioAttributes)) {
this.audioAttributes = audioAttributes; this.audioAttributes = newAudioAttributes;
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, audioAttributes); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, newAudioAttributes);
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage)); streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(newAudioAttributes.usage));
// TODO(internal b/187152483): Events should be dispatched via ListenerSet // Queue event only and flush after updating playWhenReady in case both events are triggered.
for (Listener listener : listenerArraySet) { listeners.queueEvent(
listener.onAudioAttributesChanged(audioAttributes); EVENT_AUDIO_ATTRIBUTES_CHANGED,
} listener -> listener.onAudioAttributesChanged(newAudioAttributes));
} }
audioFocusManager.setAudioAttributes(handleAudioFocus ? audioAttributes : null); audioFocusManager.setAudioAttributes(handleAudioFocus ? newAudioAttributes : null);
boolean playWhenReady = getPlayWhenReady(); boolean playWhenReady = getPlayWhenReady();
@AudioFocusManager.PlayerCommand @AudioFocusManager.PlayerCommand
int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, getPlaybackState()); int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, getPlaybackState());
updatePlayWhenReady( updatePlayWhenReady(
playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playWhenReady, playerCommand)); playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playWhenReady, playerCommand));
listeners.flushEvents();
} }
public AudioAttributes getAudioAttributes() { public AudioAttributes getAudioAttributes() {
@ -1392,10 +1401,9 @@ import java.util.concurrent.TimeoutException;
this.audioSessionId = audioSessionId; this.audioSessionId = audioSessionId;
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
sendRendererMessage(TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId); sendRendererMessage(TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
// TODO(internal b/187152483): Events should be dispatched via ListenerSet int finalAudioSessionId = audioSessionId;
for (Listener listener : listenerArraySet) { listeners.sendEvent(
listener.onAudioSessionIdChanged(audioSessionId); EVENT_AUDIO_SESSION_ID, listener -> listener.onAudioSessionIdChanged(finalAudioSessionId));
}
} }
public int getAudioSessionId() { public int getAudioSessionId() {
@ -1419,10 +1427,8 @@ import java.util.concurrent.TimeoutException;
} }
this.volume = volume; this.volume = volume;
sendVolumeToRenderers(); sendVolumeToRenderers();
// TODO(internal b/187152483): Events should be dispatched via ListenerSet float finalVolume = volume;
for (Listener listener : listenerArraySet) { listeners.sendEvent(EVENT_VOLUME_CHANGED, listener -> listener.onVolumeChanged(finalVolume));
listener.onVolumeChanged(volume);
}
} }
public float getVolume() { public float getVolume() {
@ -1433,14 +1439,16 @@ import java.util.concurrent.TimeoutException;
return skipSilenceEnabled; return skipSilenceEnabled;
} }
public void setSkipSilenceEnabled(boolean skipSilenceEnabled) { public void setSkipSilenceEnabled(boolean newSkipSilenceEnabled) {
verifyApplicationThread(); verifyApplicationThread();
if (this.skipSilenceEnabled == skipSilenceEnabled) { if (skipSilenceEnabled == newSkipSilenceEnabled) {
return; return;
} }
this.skipSilenceEnabled = skipSilenceEnabled; skipSilenceEnabled = newSkipSilenceEnabled;
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_SKIP_SILENCE_ENABLED, skipSilenceEnabled); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_SKIP_SILENCE_ENABLED, newSkipSilenceEnabled);
notifySkipSilenceEnabledChanged(); listeners.sendEvent(
EVENT_SKIP_SILENCE_ENABLED_CHANGED,
listener -> listener.onSkipSilenceEnabledChanged(newSkipSilenceEnabled));
} }
public AnalyticsCollector getAnalyticsCollector() { public AnalyticsCollector getAnalyticsCollector() {
@ -1552,14 +1560,12 @@ import java.util.concurrent.TimeoutException;
// Don't verify application thread. We allow calls to this method from any thread. // Don't verify application thread. We allow calls to this method from any thread.
checkNotNull(listener); checkNotNull(listener);
listeners.add(listener); listeners.add(listener);
listenerArraySet.add(listener);
} }
public void removeListener(Listener listener) { public void removeListener(Listener listener) {
// Don't verify application thread. We allow calls to this method from any thread. // Don't verify application thread. We allow calls to this method from any thread.
checkNotNull(listener); checkNotNull(listener);
listeners.remove(listener); listeners.remove(listener);
listenerArraySet.remove(listener);
} }
public void setHandleWakeLock(boolean handleWakeLock) { public void setHandleWakeLock(boolean handleWakeLock) {
@ -2445,10 +2451,8 @@ import java.util.concurrent.TimeoutException;
if (width != surfaceWidth || height != surfaceHeight) { if (width != surfaceWidth || height != surfaceHeight) {
surfaceWidth = width; surfaceWidth = width;
surfaceHeight = height; surfaceHeight = height;
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.sendEvent(
for (Listener listener : listenerArraySet) { EVENT_SURFACE_SIZE_CHANGED, listener -> listener.onSurfaceSizeChanged(width, height));
listener.onSurfaceSizeChanged(width, height);
}
} }
} }
@ -2457,13 +2461,6 @@ import java.util.concurrent.TimeoutException;
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_VOLUME, scaledVolume); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_VOLUME, scaledVolume);
} }
private void notifySkipSilenceEnabledChanged() {
// TODO(internal b/187152483): Events should be dispatched via ListenerSet
for (Listener listener : listenerArraySet) {
listener.onSkipSilenceEnabledChanged(skipSilenceEnabled);
}
}
private void updatePlayWhenReady( private void updatePlayWhenReady(
boolean playWhenReady, boolean playWhenReady,
@AudioFocusManager.PlayerCommand int playerCommand, @AudioFocusManager.PlayerCommand int playerCommand,
@ -2670,22 +2667,17 @@ import java.util.concurrent.TimeoutException;
} }
@Override @Override
public void onVideoSizeChanged(VideoSize videoSize) { public void onVideoSizeChanged(VideoSize newVideoSize) {
ExoPlayerImpl.this.videoSize = videoSize; videoSize = newVideoSize;
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.sendEvent(
for (Listener listener : listenerArraySet) { EVENT_VIDEO_SIZE_CHANGED, listener -> listener.onVideoSizeChanged(newVideoSize));
listener.onVideoSizeChanged(videoSize);
}
} }
@Override @Override
public void onRenderedFirstFrame(Object output, long renderTimeMs) { public void onRenderedFirstFrame(Object output, long renderTimeMs) {
analyticsCollector.onRenderedFirstFrame(output, renderTimeMs); analyticsCollector.onRenderedFirstFrame(output, renderTimeMs);
if (videoOutput == output) { if (videoOutput == output) {
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.sendEvent(EVENT_RENDERED_FIRST_FRAME, Listener::onRenderedFirstFrame);
for (Listener listener : listenerArraySet) {
listener.onRenderedFirstFrame();
}
} }
} }
@ -2756,12 +2748,14 @@ import java.util.concurrent.TimeoutException;
} }
@Override @Override
public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { public void onSkipSilenceEnabledChanged(boolean newSkipSilenceEnabled) {
if (ExoPlayerImpl.this.skipSilenceEnabled == skipSilenceEnabled) { if (skipSilenceEnabled == newSkipSilenceEnabled) {
return; return;
} }
ExoPlayerImpl.this.skipSilenceEnabled = skipSilenceEnabled; skipSilenceEnabled = newSkipSilenceEnabled;
notifySkipSilenceEnabledChanged(); listeners.sendEvent(
EVENT_SKIP_SILENCE_ENABLED_CHANGED,
listener -> listener.onSkipSilenceEnabledChanged(newSkipSilenceEnabled));
} }
@Override @Override
@ -2779,10 +2773,7 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void onCues(List<Cue> cues) { public void onCues(List<Cue> cues) {
currentCues = cues; currentCues = cues;
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.sendEvent(EVENT_CUES, listener -> listener.onCues(cues));
for (Listener listeners : listenerArraySet) {
listeners.onCues(cues);
}
} }
// MetadataOutput implementation // MetadataOutput implementation
@ -2794,14 +2785,12 @@ import java.util.concurrent.TimeoutException;
MediaMetadata newMediaMetadata = buildUpdatedMediaMetadata(); MediaMetadata newMediaMetadata = buildUpdatedMediaMetadata();
if (!newMediaMetadata.equals(mediaMetadata)) { if (!newMediaMetadata.equals(mediaMetadata)) {
mediaMetadata = newMediaMetadata; mediaMetadata = newMediaMetadata;
listeners.sendEvent( listeners.queueEvent(
EVENT_MEDIA_METADATA_CHANGED, EVENT_MEDIA_METADATA_CHANGED,
listener -> listener.onMediaMetadataChanged(mediaMetadata)); listener -> listener.onMediaMetadataChanged(mediaMetadata));
} }
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.queueEvent(EVENT_METADATA, listener -> listener.onMetadata(metadata));
for (Listener listener : listenerArraySet) { listeners.flushEvents();
listener.onMetadata(metadata);
}
} }
// SurfaceHolder.Callback implementation // SurfaceHolder.Callback implementation
@ -2891,22 +2880,19 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void onStreamTypeChanged(@C.StreamType int streamType) { public void onStreamTypeChanged(@C.StreamType int streamType) {
DeviceInfo deviceInfo = createDeviceInfo(streamVolumeManager); DeviceInfo newDeviceInfo = createDeviceInfo(streamVolumeManager);
if (!deviceInfo.equals(ExoPlayerImpl.this.deviceInfo)) { if (!newDeviceInfo.equals(deviceInfo)) {
ExoPlayerImpl.this.deviceInfo = deviceInfo; deviceInfo = newDeviceInfo;
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.sendEvent(
for (Listener listener : listenerArraySet) { EVENT_DEVICE_INFO_CHANGED, listener -> listener.onDeviceInfoChanged(newDeviceInfo));
listener.onDeviceInfoChanged(deviceInfo);
}
} }
} }
@Override @Override
public void onStreamVolumeChanged(int streamVolume, boolean streamMuted) { public void onStreamVolumeChanged(int streamVolume, boolean streamMuted) {
// TODO(internal b/187152483): Events should be dispatched via ListenerSet listeners.sendEvent(
for (Listener listener : listenerArraySet) { EVENT_DEVICE_VOLUME_CHANGED,
listener.onDeviceVolumeChanged(streamVolume, streamMuted); listener -> listener.onDeviceVolumeChanged(streamVolume, streamMuted));
}
} }
// Player.AudioOffloadListener implementation. // Player.AudioOffloadListener implementation.

View File

@ -272,6 +272,28 @@ public interface AnalyticsListener {
/** {@link Player#getMaxSeekToPreviousPosition()} changed. */ /** {@link Player#getMaxSeekToPreviousPosition()} changed. */
int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED =
Player.EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED; Player.EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED;
/** Audio attributes changed. */
int EVENT_AUDIO_ATTRIBUTES_CHANGED = Player.EVENT_AUDIO_ATTRIBUTES_CHANGED;
/** An audio session id was set. */
int EVENT_AUDIO_SESSION_ID = Player.EVENT_AUDIO_SESSION_ID;
/** The volume changed. */
int EVENT_VOLUME_CHANGED = Player.EVENT_VOLUME_CHANGED;
/** Skipping silences was enabled or disabled in the audio stream. */
int EVENT_SKIP_SILENCE_ENABLED_CHANGED = Player.EVENT_SKIP_SILENCE_ENABLED_CHANGED;
/** The surface size changed. */
int EVENT_SURFACE_SIZE_CHANGED = Player.EVENT_SURFACE_SIZE_CHANGED;
/** The video size changed. */
int EVENT_VIDEO_SIZE_CHANGED = Player.EVENT_VIDEO_SIZE_CHANGED;
/**
* The first frame has been rendered since setting the surface, since the renderer was reset or
* since the stream changed.
*/
int EVENT_RENDERED_FIRST_FRAME = Player.EVENT_RENDERED_FIRST_FRAME;
/** Metadata associated with the current playback time was reported. */
int EVENT_METADATA = Player.EVENT_METADATA;
// TODO: Forward EVENT_CUES, EVENT_DEVICE_INFO_CHANGED and EVENT_DEVICE_VOLUME_CHANGED.
/** A source started loading data. */ /** A source started loading data. */
int EVENT_LOAD_STARTED = 1000; // Intentional gap to leave space for new Player events int EVENT_LOAD_STARTED = 1000; // Intentional gap to leave space for new Player events
/** A source started completed loading data. */ /** A source started completed loading data. */
@ -286,73 +308,54 @@ public interface AnalyticsListener {
int EVENT_UPSTREAM_DISCARDED = 1005; int EVENT_UPSTREAM_DISCARDED = 1005;
/** The bandwidth estimate has been updated. */ /** The bandwidth estimate has been updated. */
int EVENT_BANDWIDTH_ESTIMATE = 1006; int EVENT_BANDWIDTH_ESTIMATE = 1006;
/** Metadata associated with the current playback time was reported. */
int EVENT_METADATA = 1007;
/** An audio renderer was enabled. */ /** An audio renderer was enabled. */
int EVENT_AUDIO_ENABLED = 1008; int EVENT_AUDIO_ENABLED = 1007;
/** An audio renderer created a decoder. */ /** An audio renderer created a decoder. */
int EVENT_AUDIO_DECODER_INITIALIZED = 1009; int EVENT_AUDIO_DECODER_INITIALIZED = 1008;
/** The format consumed by an audio renderer changed. */ /** The format consumed by an audio renderer changed. */
int EVENT_AUDIO_INPUT_FORMAT_CHANGED = 1010; int EVENT_AUDIO_INPUT_FORMAT_CHANGED = 1009;
/** The audio position has increased for the first time since the last pause or position reset. */ /** The audio position has increased for the first time since the last pause or position reset. */
int EVENT_AUDIO_POSITION_ADVANCING = 1011; int EVENT_AUDIO_POSITION_ADVANCING = 1010;
/** An audio underrun occurred. */ /** An audio underrun occurred. */
int EVENT_AUDIO_UNDERRUN = 1012; int EVENT_AUDIO_UNDERRUN = 1011;
/** An audio renderer released a decoder. */ /** An audio renderer released a decoder. */
int EVENT_AUDIO_DECODER_RELEASED = 1013; int EVENT_AUDIO_DECODER_RELEASED = 1012;
/** An audio renderer was disabled. */ /** An audio renderer was disabled. */
int EVENT_AUDIO_DISABLED = 1014; int EVENT_AUDIO_DISABLED = 1013;
/** An audio session id was set. */
int EVENT_AUDIO_SESSION_ID = 1015;
/** Audio attributes changed. */
int EVENT_AUDIO_ATTRIBUTES_CHANGED = 1016;
/** Skipping silences was enabled or disabled in the audio stream. */
int EVENT_SKIP_SILENCE_ENABLED_CHANGED = 1017;
/** The audio sink encountered a non-fatal error. */ /** The audio sink encountered a non-fatal error. */
int EVENT_AUDIO_SINK_ERROR = 1018; int EVENT_AUDIO_SINK_ERROR = 1014;
/** The volume changed. */
int EVENT_VOLUME_CHANGED = 1019;
/** A video renderer was enabled. */ /** A video renderer was enabled. */
int EVENT_VIDEO_ENABLED = 1020; int EVENT_VIDEO_ENABLED = 1015;
/** A video renderer created a decoder. */ /** A video renderer created a decoder. */
int EVENT_VIDEO_DECODER_INITIALIZED = 1021; int EVENT_VIDEO_DECODER_INITIALIZED = 1016;
/** The format consumed by a video renderer changed. */ /** The format consumed by a video renderer changed. */
int EVENT_VIDEO_INPUT_FORMAT_CHANGED = 1022; int EVENT_VIDEO_INPUT_FORMAT_CHANGED = 1017;
/** Video frames have been dropped. */ /** Video frames have been dropped. */
int EVENT_DROPPED_VIDEO_FRAMES = 1023; int EVENT_DROPPED_VIDEO_FRAMES = 1018;
/** A video renderer released a decoder. */ /** A video renderer released a decoder. */
int EVENT_VIDEO_DECODER_RELEASED = 1024; int EVENT_VIDEO_DECODER_RELEASED = 1019;
/** A video renderer was disabled. */ /** A video renderer was disabled. */
int EVENT_VIDEO_DISABLED = 1025; int EVENT_VIDEO_DISABLED = 1020;
/** Video frame processing offset data has been reported. */ /** Video frame processing offset data has been reported. */
int EVENT_VIDEO_FRAME_PROCESSING_OFFSET = 1026; int EVENT_VIDEO_FRAME_PROCESSING_OFFSET = 1021;
/**
* The first frame has been rendered since setting the surface, since the renderer was reset or
* since the stream changed.
*/
int EVENT_RENDERED_FIRST_FRAME = 1027;
/** The video size changed. */
int EVENT_VIDEO_SIZE_CHANGED = 1028;
/** The surface size changed. */
int EVENT_SURFACE_SIZE_CHANGED = 1029;
/** A DRM session has been acquired. */ /** A DRM session has been acquired. */
int EVENT_DRM_SESSION_ACQUIRED = 1030; int EVENT_DRM_SESSION_ACQUIRED = 1022;
/** DRM keys were loaded. */ /** DRM keys were loaded. */
int EVENT_DRM_KEYS_LOADED = 1031; int EVENT_DRM_KEYS_LOADED = 1023;
/** A non-fatal DRM session manager error occurred. */ /** A non-fatal DRM session manager error occurred. */
int EVENT_DRM_SESSION_MANAGER_ERROR = 1032; int EVENT_DRM_SESSION_MANAGER_ERROR = 1024;
/** DRM keys were restored. */ /** DRM keys were restored. */
int EVENT_DRM_KEYS_RESTORED = 1033; int EVENT_DRM_KEYS_RESTORED = 1025;
/** DRM keys were removed. */ /** DRM keys were removed. */
int EVENT_DRM_KEYS_REMOVED = 1034; int EVENT_DRM_KEYS_REMOVED = 1026;
/** A DRM session has been released. */ /** A DRM session has been released. */
int EVENT_DRM_SESSION_RELEASED = 1035; int EVENT_DRM_SESSION_RELEASED = 1027;
/** The player was released. */ /** The player was released. */
int EVENT_PLAYER_RELEASED = 1036; int EVENT_PLAYER_RELEASED = 1028;
/** The audio codec encountered an error. */ /** The audio codec encountered an error. */
int EVENT_AUDIO_CODEC_ERROR = 1037; int EVENT_AUDIO_CODEC_ERROR = 1029;
/** The video codec encountered an error. */ /** The video codec encountered an error. */
int EVENT_VIDEO_CODEC_ERROR = 1038; int EVENT_VIDEO_CODEC_ERROR = 1030;
/** Time information of an event. */ /** Time information of an event. */
final class EventTime { final class EventTime {