diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 8966812010..9bc9753e15 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -7,8 +7,6 @@ * Moved initial bitrate estimate from `AdaptiveTrackSelection` to `DefaultBandwidthMeter`. * Updated default max buffer length in `DefaultLoadControl`. -* Added `AnalyticsListener` interface which can be registered in - `SimpleExoPlayer` to receive detailed meta data for each ExoPlayer event. * UI components: * Add support for listening to `AspectRatioFrameLayout`'s aspect ratio update ([#3736](https://github.com/google/ExoPlayer/issues/3736)). diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java index 8095ed9c64..b89968e168 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java @@ -17,7 +17,6 @@ package com.google.android.exoplayer2; import android.content.Context; import android.support.annotation.Nullable; -import com.google.android.exoplayer2.analytics.AnalyticsCollector; import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.trackselection.TrackSelector; @@ -176,27 +175,6 @@ public final class ExoPlayerFactory { return new SimpleExoPlayer(renderersFactory, trackSelector, loadControl, drmSessionManager); } - /** - * Creates a {@link SimpleExoPlayer} instance. - * - * @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance. - * @param trackSelector The {@link TrackSelector} that will be used by the instance. - * @param loadControl The {@link LoadControl} that will be used by the instance. - * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance - * will not be used for DRM protected playbacks. - * @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that - * will collect and forward all player events. - */ - public static SimpleExoPlayer newSimpleInstance( - RenderersFactory renderersFactory, - TrackSelector trackSelector, - LoadControl loadControl, - @Nullable DrmSessionManager drmSessionManager, - AnalyticsCollector.Factory analyticsCollectorFactory) { - return new SimpleExoPlayer( - renderersFactory, trackSelector, loadControl, drmSessionManager, analyticsCollectorFactory); - } - /** * Creates an {@link ExoPlayer} instance. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java index b998027eb3..e6979b4a60 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java @@ -27,12 +27,9 @@ import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; -import com.google.android.exoplayer2.analytics.AnalyticsCollector; -import com.google.android.exoplayer2.analytics.AnalyticsListener; import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.decoder.DecoderCounters; -import com.google.android.exoplayer2.drm.DefaultDrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.metadata.Metadata; @@ -66,7 +63,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player protected final Renderer[] renderers; private final ExoPlayer player; - private final Handler eventHandler; private final ComponentListener componentListener; private final CopyOnWriteArraySet videoListeners; @@ -74,7 +70,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player private final CopyOnWriteArraySet metadataOutputs; private final CopyOnWriteArraySet videoDebugListeners; private final CopyOnWriteArraySet audioDebugListeners; - private final AnalyticsCollector analyticsCollector; private Format videoFormat; private Format audioFormat; @@ -90,7 +85,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player private int audioSessionId; private AudioAttributes audioAttributes; private float audioVolume; - private MediaSource mediaSource; /** * @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance. @@ -104,12 +98,7 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player TrackSelector trackSelector, LoadControl loadControl, @Nullable DrmSessionManager drmSessionManager) { - this( - renderersFactory, - trackSelector, - loadControl, - drmSessionManager, - new AnalyticsCollector.Factory()); + this(renderersFactory, trackSelector, loadControl, drmSessionManager, Clock.DEFAULT); } /** @@ -118,32 +107,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player * @param loadControl The {@link LoadControl} that will be used by the instance. * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance * will not be used for DRM protected playbacks. - * @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that - * will collect and forward all player events. - */ - protected SimpleExoPlayer( - RenderersFactory renderersFactory, - TrackSelector trackSelector, - LoadControl loadControl, - @Nullable DrmSessionManager drmSessionManager, - AnalyticsCollector.Factory analyticsCollectorFactory) { - this( - renderersFactory, - trackSelector, - loadControl, - drmSessionManager, - analyticsCollectorFactory, - Clock.DEFAULT); - } - - /** - * @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance. - * @param trackSelector The {@link TrackSelector} that will be used by the instance. - * @param loadControl The {@link LoadControl} that will be used by the instance. - * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance - * will not be used for DRM protected playbacks. - * @param analyticsCollectorFactory A factory for creating the {@link AnalyticsCollector} that - * will collect and forward all player events. * @param clock The {@link Clock} that will be used by the instance. Should always be {@link * Clock#DEFAULT}, unless the player is being used from a test. */ @@ -152,7 +115,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player TrackSelector trackSelector, LoadControl loadControl, @Nullable DrmSessionManager drmSessionManager, - AnalyticsCollector.Factory analyticsCollectorFactory, Clock clock) { componentListener = new ComponentListener(); videoListeners = new CopyOnWriteArraySet<>(); @@ -161,7 +123,7 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player videoDebugListeners = new CopyOnWriteArraySet<>(); audioDebugListeners = new CopyOnWriteArraySet<>(); Looper eventLooper = Looper.myLooper() != null ? Looper.myLooper() : Looper.getMainLooper(); - eventHandler = new Handler(eventLooper); + Handler eventHandler = new Handler(eventLooper); renderers = renderersFactory.createRenderers( eventHandler, @@ -179,14 +141,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player // Build the player and associated objects. player = createExoPlayerImpl(renderers, trackSelector, loadControl, clock); - analyticsCollector = analyticsCollectorFactory.createAnalyticsCollector(player, clock); - addListener(analyticsCollector); - addVideoDebugListener(analyticsCollector); - addAudioDebugListener(analyticsCollector); - addMetadataOutput(analyticsCollector); - if (drmSessionManager instanceof DefaultDrmSessionManager) { - ((DefaultDrmSessionManager) drmSessionManager).addListener(eventHandler, analyticsCollector); - } } @Override @@ -329,29 +283,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player return Util.getStreamTypeForAudioUsage(audioAttributes.usage); } - /** Returns the {@link AnalyticsCollector} used for collecting analytics events. */ - public AnalyticsCollector getAnalyticsCollector() { - return analyticsCollector; - } - - /** - * Adds an {@link AnalyticsListener} to receive analytics events. - * - * @param listener The listener to be added. - */ - public void addAnalyticsListener(AnalyticsListener listener) { - analyticsCollector.addListener(listener); - } - - /** - * Removes an {@link AnalyticsListener}. - * - * @param listener The listener to be removed. - */ - public void removeAnalyticsListener(AnalyticsListener listener) { - analyticsCollector.removeListener(listener); - } - /** * Sets the attributes for audio playback, used by the underlying audio track. If not set, the * default audio attributes will be used. They are suitable for general media playback. @@ -655,19 +586,11 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player @Override public void prepare(MediaSource mediaSource) { - prepare(mediaSource, /* resetPosition= */ true, /* resetState= */ true); + player.prepare(mediaSource); } @Override public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) { - if (this.mediaSource != mediaSource) { - if (this.mediaSource != null) { - this.mediaSource.removeEventListener(analyticsCollector); - analyticsCollector.resetForNewMediaSource(); - } - mediaSource.addEventListener(eventHandler, analyticsCollector); - this.mediaSource = mediaSource; - } player.prepare(mediaSource, resetPosition, resetState); } @@ -708,25 +631,21 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player @Override public void seekToDefaultPosition() { - analyticsCollector.notifySeekStarted(); player.seekToDefaultPosition(); } @Override public void seekToDefaultPosition(int windowIndex) { - analyticsCollector.notifySeekStarted(); player.seekToDefaultPosition(windowIndex); } @Override public void seekTo(long positionMs) { - analyticsCollector.notifySeekStarted(); player.seekTo(positionMs); } @Override public void seekTo(int windowIndex, long positionMs) { - analyticsCollector.notifySeekStarted(); player.seekTo(windowIndex, positionMs); } @@ -752,17 +671,12 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player @Override public void stop() { - stop(/* reset= */ false); + player.stop(); } @Override public void stop(boolean reset) { player.stop(reset); - if (mediaSource != null) { - mediaSource.removeEventListener(analyticsCollector); - mediaSource = null; - analyticsCollector.resetForNewMediaSource(); - } } @Override @@ -775,9 +689,6 @@ public class SimpleExoPlayer implements ExoPlayer, Player.VideoComponent, Player } surface = null; } - if (mediaSource != null) { - mediaSource.removeEventListener(analyticsCollector); - } } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java index 093ac4f7f4..3a937a832d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java @@ -44,7 +44,6 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -158,22 +157,6 @@ public class AnalyticsCollector } } - /** - * Resets the analytics collector for a new media source. Should be called before the player is - * prepared with a new media source. - */ - public final void resetForNewMediaSource() { - // Copying the list is needed because onMediaPeriodReleased will modify the list. - List activeMediaPeriods = - new ArrayList<>(mediaPeriodQueueTracker.activeMediaPeriods); - Timeline timeline = mediaPeriodQueueTracker.timeline; - for (MediaPeriodId mediaPeriod : activeMediaPeriods) { - int windowIndex = - timeline.isEmpty() ? 0 : timeline.getPeriod(mediaPeriod.periodIndex, period).windowIndex; - onMediaPeriodReleased(windowIndex, mediaPeriod); - } - } - // MetadataOutput implementation. @Override @@ -648,9 +631,6 @@ public class AnalyticsCollector /** Keeps track of the active media periods and currently playing and reading media period. */ private static final class MediaPeriodQueueTracker { - // TODO: Investigate reporting MediaPeriodId in renderer events and adding a listener of queue - // changes, which would hopefully remove the need to track the queue here. - private final ArrayList activeMediaPeriods; private final Period period; @@ -783,14 +763,13 @@ public class AnalyticsCollector } private void updateLastReportedPlayingMediaPeriod() { - if (!activeMediaPeriods.isEmpty()) { - lastReportedPlayingMediaPeriod = activeMediaPeriods.get(0); - } + lastReportedPlayingMediaPeriod = + activeMediaPeriods.isEmpty() ? null : activeMediaPeriods.get(0); } private MediaPeriodId updateMediaPeriodIdToNewTimeline( MediaPeriodId mediaPeriodId, Timeline newTimeline) { - if (newTimeline.isEmpty() || timeline.isEmpty()) { + if (newTimeline.isEmpty()) { return mediaPeriodId; } Object uid = timeline.getPeriod(mediaPeriodId.periodIndex, period, /* setIds= */ true).uid; diff --git a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java deleted file mode 100644 index 2320563750..0000000000 --- a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java +++ /dev/null @@ -1,1144 +0,0 @@ -/* - * Copyright (C) 2018 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.analytics; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Handler; -import android.os.SystemClock; -import android.support.annotation.Nullable; -import android.view.Surface; -import com.google.android.exoplayer2.ExoPlaybackException; -import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.PlaybackParameters; -import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.Renderer; -import com.google.android.exoplayer2.RenderersFactory; -import com.google.android.exoplayer2.SimpleExoPlayer; -import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.Timeline.Window; -import com.google.android.exoplayer2.audio.AudioRendererEventListener; -import com.google.android.exoplayer2.decoder.DecoderCounters; -import com.google.android.exoplayer2.drm.DrmSessionManager; -import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; -import com.google.android.exoplayer2.metadata.Metadata; -import com.google.android.exoplayer2.metadata.MetadataOutput; -import com.google.android.exoplayer2.source.ConcatenatingMediaSource; -import com.google.android.exoplayer2.source.MediaSource; -import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; -import com.google.android.exoplayer2.source.MediaSourceEventListener.LoadEventInfo; -import com.google.android.exoplayer2.source.MediaSourceEventListener.MediaLoadData; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.testutil.ActionSchedule; -import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable; -import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner; -import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner.Builder; -import com.google.android.exoplayer2.testutil.FakeMediaSource; -import com.google.android.exoplayer2.testutil.FakeRenderer; -import com.google.android.exoplayer2.testutil.FakeTimeline; -import com.google.android.exoplayer2.testutil.RobolectricUtil; -import com.google.android.exoplayer2.text.TextOutput; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.util.Util; -import com.google.android.exoplayer2.video.VideoRendererEventListener; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -/** Integration test for {@link AnalyticsCollector}. */ -@RunWith(RobolectricTestRunner.class) -@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class}) -public final class AnalyticsCollectorTest { - - private static final int EVENT_PLAYER_STATE_CHANGED = 0; - private static final int EVENT_TIMELINE_CHANGED = 1; - private static final int EVENT_POSITION_DISCONTINUITY = 2; - private static final int EVENT_SEEK_STARTED = 3; - private static final int EVENT_SEEK_PROCESSED = 4; - private static final int EVENT_PLAYBACK_PARAMETERS_CHANGED = 5; - private static final int EVENT_REPEAT_MODE_CHANGED = 6; - private static final int EVENT_SHUFFLE_MODE_CHANGED = 7; - private static final int EVENT_LOADING_CHANGED = 8; - private static final int EVENT_PLAYER_ERROR = 9; - private static final int EVENT_TRACKS_CHANGED = 10; - private static final int EVENT_LOAD_STARTED = 11; - private static final int EVENT_LOAD_COMPLETED = 12; - private static final int EVENT_LOAD_CANCELED = 13; - private static final int EVENT_LOAD_ERROR = 14; - private static final int EVENT_DOWNSTREAM_FORMAT_CHANGED = 15; - private static final int EVENT_UPSTREAM_DISCARDED = 16; - private static final int EVENT_MEDIA_PERIOD_CREATED = 17; - private static final int EVENT_MEDIA_PERIOD_RELEASED = 18; - private static final int EVENT_READING_STARTED = 19; - private static final int EVENT_BANDWIDTH_ESTIMATE = 20; - private static final int EVENT_VIEWPORT_SIZE_CHANGED = 21; - private static final int EVENT_NETWORK_TYPE_CHANGED = 22; - private static final int EVENT_METADATA = 23; - private static final int EVENT_DECODER_ENABLED = 24; - private static final int EVENT_DECODER_INIT = 25; - private static final int EVENT_DECODER_FORMAT_CHANGED = 26; - private static final int EVENT_DECODER_DISABLED = 27; - private static final int EVENT_AUDIO_SESSION_ID = 28; - private static final int EVENT_AUDIO_UNDERRUN = 29; - private static final int EVENT_DROPPED_VIDEO_FRAMES = 30; - private static final int EVENT_VIDEO_SIZE_CHANGED = 31; - private static final int EVENT_RENDERED_FIRST_FRAME = 32; - private static final int EVENT_AD_LOAD_ERROR = 33; - private static final int EVENT_INTERNAL_AD_LOAD_ERROR = 34; - private static final int EVENT_AD_CLICKED = 35; - private static final int EVENT_AD_TAPPED = 36; - private static final int EVENT_DRM_KEYS_LOADED = 37; - private static final int EVENT_DRM_ERROR = 38; - private static final int EVENT_DRM_KEYS_RESTORED = 39; - private static final int EVENT_DRM_KEYS_REMOVED = 40; - - private static final int TIMEOUT_MS = 10000; - private static final Timeline SINGLE_PERIOD_TIMELINE = new FakeTimeline(/* windowCount= */ 1); - private static final EventWindowAndPeriodId WINDOW_0 = - new EventWindowAndPeriodId(/* windowIndex= */ 0, /* mediaPeriodId= */ null); - private static final EventWindowAndPeriodId WINDOW_1 = - new EventWindowAndPeriodId(/* windowIndex= */ 1, /* mediaPeriodId= */ null); - private static final EventWindowAndPeriodId PERIOD_0 = - new EventWindowAndPeriodId( - /* windowIndex= */ 0, - new MediaPeriodId(/* periodIndex= */ 0, /* windowSequenceNumber= */ 0)); - private static final EventWindowAndPeriodId PERIOD_1 = - new EventWindowAndPeriodId( - /* windowIndex= */ 1, - new MediaPeriodId(/* periodIndex= */ 1, /* windowSequenceNumber= */ 1)); - private static final EventWindowAndPeriodId PERIOD_0_SEQ_0 = PERIOD_0; - private static final EventWindowAndPeriodId PERIOD_1_SEQ_1 = PERIOD_1; - private static final EventWindowAndPeriodId PERIOD_0_SEQ_1 = - new EventWindowAndPeriodId( - /* windowIndex= */ 0, - new MediaPeriodId(/* periodIndex= */ 0, /* windowSequenceNumber= */ 1)); - private static final EventWindowAndPeriodId PERIOD_1_SEQ_0 = - new EventWindowAndPeriodId( - /* windowIndex= */ 1, - new MediaPeriodId(/* periodIndex= */ 1, /* windowSequenceNumber= */ 0)); - private static final EventWindowAndPeriodId PERIOD_1_SEQ_2 = - new EventWindowAndPeriodId( - /* windowIndex= */ 1, - new MediaPeriodId(/* periodIndex= */ 1, /* windowSequenceNumber= */ 2)); - - @Test - public void testEmptyTimeline() throws Exception { - FakeMediaSource mediaSource = - new FakeMediaSource( - Timeline.EMPTY, /* manifest= */ null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady */, WINDOW_0 /* BUFFERING */, WINDOW_0 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testSinglePeriod() throws Exception { - FakeMediaSource mediaSource = - new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, - /* manifest= */ null, - Builder.VIDEO_FORMAT, - Builder.AUDIO_FORMAT); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady */, - WINDOW_0 /* BUFFERING */, - PERIOD_0 /* READY */, - PERIOD_0 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0 /* started */, PERIOD_0 /* stopped */); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly(WINDOW_0 /* manifest */, PERIOD_0 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly(WINDOW_0 /* manifest */, PERIOD_0 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0 /* audio */, PERIOD_0 /* video */); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_READING_STARTED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0 /* audio */, PERIOD_0 /* video */); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0 /* audio */, PERIOD_0 /* video */); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0 /* audio */, PERIOD_0 /* video */); - assertThat(listener.getEvents(EVENT_AUDIO_SESSION_ID)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(PERIOD_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testAutomaticPeriodTransition() throws Exception { - MediaSource mediaSource = - new ConcatenatingMediaSource( - new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, - /* manifest= */ null, - Builder.VIDEO_FORMAT, - Builder.AUDIO_FORMAT), - new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, - /* manifest= */ null, - Builder.VIDEO_FORMAT, - Builder.AUDIO_FORMAT)); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady */, - WINDOW_0 /* BUFFERING */, - PERIOD_0 /* READY */, - PERIOD_1 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0); - assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(PERIOD_1); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0, PERIOD_0, PERIOD_0, PERIOD_0); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly( - PERIOD_0 /* audio */, PERIOD_0 /* video */, PERIOD_1 /* audio */, PERIOD_1 /* video */); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_READING_STARTED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0 /* audio */, PERIOD_0 /* video */); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly( - PERIOD_0 /* audio */, PERIOD_0 /* video */, PERIOD_1 /* audio */, PERIOD_1 /* video */); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly( - PERIOD_0 /* audio */, PERIOD_0 /* video */, PERIOD_1 /* audio */, PERIOD_1 /* video */); - assertThat(listener.getEvents(EVENT_AUDIO_SESSION_ID)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(PERIOD_1); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(PERIOD_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testPeriodTransitionWithRendererChange() throws Exception { - MediaSource mediaSource = - new ConcatenatingMediaSource( - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT), - new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.AUDIO_FORMAT)); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady */, - WINDOW_0 /* BUFFERING */, - PERIOD_0 /* READY */, - PERIOD_1 /* BUFFERING */, - PERIOD_1 /* READY */, - PERIOD_1 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0); - assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(PERIOD_1); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0, PERIOD_0, PERIOD_0, PERIOD_0); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_READING_STARTED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_AUDIO_SESSION_ID)).containsExactly(PERIOD_1); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(PERIOD_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testSeekToOtherPeriod() throws Exception { - MediaSource mediaSource = - new ConcatenatingMediaSource( - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT), - new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.AUDIO_FORMAT)); - ActionSchedule actionSchedule = - new ActionSchedule.Builder("AnalyticsCollectorTest") - .pause() - .waitForPlaybackState(Player.STATE_READY) - .seek(/* windowIndex= */ 1, /* positionMs= */ 0) - .play() - .build(); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady=true */, - WINDOW_0 /* BUFFERING */, - WINDOW_0 /* setPlayWhenReady=false */, - PERIOD_0 /* READY */, - PERIOD_1 /* BUFFERING */, - PERIOD_1 /* READY */, - PERIOD_1 /* setPlayWhenReady=true */, - PERIOD_1 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0); - assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(PERIOD_1); - assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(PERIOD_1); - List loadingEvents = listener.getEvents(EVENT_LOADING_CHANGED); - assertThat(loadingEvents).hasSize(4); - assertThat(loadingEvents).containsAllOf(PERIOD_0, PERIOD_0); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_READING_STARTED)).containsExactly(PERIOD_0, PERIOD_1); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0 /* video */, PERIOD_1 /* audio */); - assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_AUDIO_SESSION_ID)).containsExactly(PERIOD_1); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(PERIOD_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testSeekBackAfterReadingAhead() throws Exception { - MediaSource mediaSource = - new ConcatenatingMediaSource( - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT), - new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, - /* manifest= */ null, - Builder.VIDEO_FORMAT, - Builder.AUDIO_FORMAT)); - long periodDurationMs = - SINGLE_PERIOD_TIMELINE.getWindow(/* windowIndex= */ 0, new Window()).getDurationMs(); - ActionSchedule actionSchedule = - new ActionSchedule.Builder("AnalyticsCollectorTest") - .pause() - .waitForPlaybackState(Player.STATE_READY) - .playUntilPosition(/* windowIndex= */ 0, periodDurationMs) - .seek(/* positionMs= */ 0) - .waitForPlaybackState(Player.STATE_READY) - .play() - .build(); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady=true */, - WINDOW_0 /* BUFFERING */, - WINDOW_0 /* setPlayWhenReady=false */, - PERIOD_0 /* READY */, - PERIOD_0 /* setPlayWhenReady=true */, - PERIOD_0 /* setPlayWhenReady=false */, - PERIOD_0 /* BUFFERING */, - PERIOD_0 /* READY */, - PERIOD_0 /* setPlayWhenReady=true */, - PERIOD_1_SEQ_2 /* BUFFERING */, - PERIOD_1_SEQ_2 /* READY */, - PERIOD_1_SEQ_2 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0); - assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0, PERIOD_0, PERIOD_0, PERIOD_0, PERIOD_0, PERIOD_0); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(PERIOD_0, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1_SEQ_1 /* media */, - PERIOD_1_SEQ_2 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0 /* media */, - WINDOW_1 /* manifest */, - PERIOD_1_SEQ_1 /* media */, - PERIOD_1_SEQ_2 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_1, PERIOD_1_SEQ_2, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_1, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_1); - assertThat(listener.getEvents(EVENT_READING_STARTED)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_1, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0, PERIOD_0, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_1, PERIOD_1_SEQ_2, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_1, PERIOD_1_SEQ_2, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_AUDIO_SESSION_ID)).containsExactly(PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)) - .containsExactly(PERIOD_0, PERIOD_0, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_2); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)) - .containsExactly(PERIOD_0, PERIOD_1_SEQ_2); - listener.assertNoMoreEvents(); - } - - @Test - public void testPrepareNewSource() throws Exception { - MediaSource mediaSource1 = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT); - MediaSource mediaSource2 = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT); - ActionSchedule actionSchedule = - new ActionSchedule.Builder("AnalyticsCollectorTest") - .pause() - .waitForPlaybackState(Player.STATE_READY) - .prepareSource(mediaSource2) - .play() - .build(); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource1, actionSchedule); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady=true */, - WINDOW_0 /* BUFFERING */, - WINDOW_0 /* setPlayWhenReady=false */, - PERIOD_0_SEQ_0 /* READY */, - WINDOW_0 /* BUFFERING */, - WINDOW_0 /* setPlayWhenReady=true */, - PERIOD_0_SEQ_1 /* READY */, - PERIOD_0_SEQ_1 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)) - .containsExactly(WINDOW_0 /* prepared */, WINDOW_0 /* reset */, WINDOW_0 /* prepared */); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0, PERIOD_0_SEQ_1, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)) - .containsExactly( - PERIOD_0_SEQ_0 /* prepared */, WINDOW_0 /* reset */, PERIOD_0_SEQ_1 /* prepared */); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_0 /* media */, - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_1 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_0 /* media */, - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_1 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_READING_STARTED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_1); - listener.assertNoMoreEvents(); - } - - @Test - public void testReprepareAfterError() throws Exception { - MediaSource mediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT); - ActionSchedule actionSchedule = - new ActionSchedule.Builder("AnalyticsCollectorTest") - .waitForPlaybackState(Player.STATE_READY) - .throwPlaybackException(ExoPlaybackException.createForSource(new IOException())) - .waitForPlaybackState(Player.STATE_IDLE) - .prepareSource(mediaSource, /* resetPosition= */ false, /* resetState= */ false) - .waitForPlaybackState(Player.STATE_ENDED) - .build(); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady=true */, - WINDOW_0 /* BUFFERING */, - PERIOD_0_SEQ_0 /* READY */, - WINDOW_0 /* IDLE */, - WINDOW_0 /* BUFFERING */, - PERIOD_0_SEQ_0 /* READY */, - PERIOD_0_SEQ_0 /* ENDED */); - // assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)).doesNotContain(PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)) - .containsExactly(WINDOW_0 /* prepared */, WINDOW_0 /* prepared */); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0, PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_PLAYER_ERROR)).containsExactly(WINDOW_0); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_0 /* media */, - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_0 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_0 /* media */, - WINDOW_0 /* manifest */, - PERIOD_0_SEQ_0 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_READING_STARTED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testDynamicTimelineChange() throws Exception { - MediaSource childMediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT); - final ConcatenatingMediaSource concatenatedMediaSource = - new ConcatenatingMediaSource(childMediaSource, childMediaSource); - long periodDurationMs = - SINGLE_PERIOD_TIMELINE.getWindow(/* windowIndex= */ 0, new Window()).getDurationMs(); - ActionSchedule actionSchedule = - new ActionSchedule.Builder("AnalyticsCollectorTest") - .pause() - .waitForPlaybackState(Player.STATE_READY) - // Ensure second period is already being read from. - .playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ periodDurationMs) - .executeRunnable( - new Runnable() { - @Override - public void run() { - concatenatedMediaSource.moveMediaSource( - /* currentIndex= */ 0, /* newIndex= */ 1); - } - }) - .waitForTimelineChanged(/* expectedTimeline= */ null) - .play() - .build(); - TestAnalyticsListener listener = runAnalyticsTest(concatenatedMediaSource, actionSchedule); - - assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) - .containsExactly( - WINDOW_0 /* setPlayWhenReady=true */, - WINDOW_0 /* BUFFERING */, - WINDOW_0 /* setPlayWhenReady=false */, - PERIOD_0_SEQ_0 /* READY */, - PERIOD_0_SEQ_0 /* setPlayWhenReady=true */, - PERIOD_0_SEQ_0 /* setPlayWhenReady=false */, - PERIOD_1_SEQ_0 /* setPlayWhenReady=true */, - PERIOD_1_SEQ_0 /* BUFFERING */, - PERIOD_1_SEQ_0 /* ENDED */); - assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)) - .containsExactly(WINDOW_0, PERIOD_1_SEQ_0); - assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0, PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_LOAD_STARTED)) - .containsExactly( - WINDOW_0 /* manifest */, PERIOD_0_SEQ_0 /* media */, PERIOD_1_SEQ_1 /* media */); - assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)) - .containsExactly( - WINDOW_0 /* manifest */, PERIOD_0_SEQ_0 /* media */, PERIOD_1_SEQ_1 /* media */); - assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_1_SEQ_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_1_SEQ_1); - assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(PERIOD_0_SEQ_1); - assertThat(listener.getEvents(EVENT_READING_STARTED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_1_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_ENABLED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DECODER_INIT)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_1_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)) - .containsExactly(PERIOD_0_SEQ_0, PERIOD_1_SEQ_1); - assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(PERIOD_0_SEQ_0); - assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(PERIOD_0_SEQ_0); - listener.assertNoMoreEvents(); - } - - @Test - public void testNotifyExternalEvents() throws Exception { - MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null); - final NetworkInfo networkInfo = - ((ConnectivityManager) - RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE)) - .getActiveNetworkInfo(); - ActionSchedule actionSchedule = - new ActionSchedule.Builder("AnalyticsCollectorTest") - .pause() - .waitForPlaybackState(Player.STATE_READY) - .executeRunnable( - new PlayerRunnable() { - @Override - public void run(SimpleExoPlayer player) { - player.getAnalyticsCollector().notifyNetworkTypeChanged(networkInfo); - player - .getAnalyticsCollector() - .notifyViewportSizeChanged(/* width= */ 320, /* height= */ 240); - player.getAnalyticsCollector().notifySeekStarted(); - } - }) - .seek(/* positionMs= */ 0) - .play() - .build(); - TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule); - - assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_VIEWPORT_SIZE_CHANGED)).containsExactly(PERIOD_0); - assertThat(listener.getEvents(EVENT_NETWORK_TYPE_CHANGED)).containsExactly(PERIOD_0); - } - - private static TestAnalyticsListener runAnalyticsTest(MediaSource mediaSource) throws Exception { - return runAnalyticsTest(mediaSource, /* actionSchedule= */ null); - } - - private static TestAnalyticsListener runAnalyticsTest( - MediaSource mediaSource, @Nullable ActionSchedule actionSchedule) throws Exception { - RenderersFactory renderersFactory = - new RenderersFactory() { - @Override - public Renderer[] createRenderers( - Handler eventHandler, - VideoRendererEventListener videoRendererEventListener, - AudioRendererEventListener audioRendererEventListener, - TextOutput textRendererOutput, - MetadataOutput metadataRendererOutput, - @Nullable DrmSessionManager drmSessionManager) { - return new Renderer[] { - new FakeVideoRenderer(eventHandler, videoRendererEventListener), - new FakeAudioRenderer(eventHandler, audioRendererEventListener) - }; - } - }; - TestAnalyticsListener listener = new TestAnalyticsListener(); - try { - new ExoPlayerTestRunner.Builder() - .setMediaSource(mediaSource) - .setRenderersFactory(renderersFactory) - .setAnalyticsListener(listener) - .setActionSchedule(actionSchedule) - .build() - .start() - .blockUntilActionScheduleFinished(TIMEOUT_MS) - .blockUntilEnded(TIMEOUT_MS); - } catch (ExoPlaybackException e) { - // Ignore ExoPlaybackException as these may be expected. - } - return listener; - } - - private static final class FakeVideoRenderer extends FakeRenderer { - - private final VideoRendererEventListener.EventDispatcher eventDispatcher; - private final DecoderCounters decoderCounters; - private Format format; - private boolean renderedFirstFrame; - - public FakeVideoRenderer(Handler handler, VideoRendererEventListener eventListener) { - super(Builder.VIDEO_FORMAT); - eventDispatcher = new VideoRendererEventListener.EventDispatcher(handler, eventListener); - decoderCounters = new DecoderCounters(); - } - - @Override - protected void onEnabled(boolean joining) throws ExoPlaybackException { - super.onEnabled(joining); - eventDispatcher.enabled(decoderCounters); - renderedFirstFrame = false; - } - - @Override - protected void onStopped() throws ExoPlaybackException { - super.onStopped(); - eventDispatcher.droppedFrames(/* droppedFrameCount= */ 0, /* elapsedMs= */ 0); - } - - @Override - protected void onDisabled() { - super.onDisabled(); - eventDispatcher.disabled(decoderCounters); - } - - @Override - protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { - super.onPositionReset(positionUs, joining); - renderedFirstFrame = false; - } - - @Override - protected void onFormatChanged(Format format) { - eventDispatcher.inputFormatChanged(format); - eventDispatcher.decoderInitialized( - /* decoderName= */ "fake.video.decoder", - /* initializedTimestampMs= */ SystemClock.elapsedRealtime(), - /* initializationDurationMs= */ 0); - this.format = format; - } - - @Override - protected void onBufferRead() { - if (!renderedFirstFrame) { - eventDispatcher.videoSizeChanged( - format.width, format.height, format.rotationDegrees, format.pixelWidthHeightRatio); - eventDispatcher.renderedFirstFrame(/* surface= */ null); - renderedFirstFrame = true; - } - } - } - - private static final class FakeAudioRenderer extends FakeRenderer { - - private final AudioRendererEventListener.EventDispatcher eventDispatcher; - private final DecoderCounters decoderCounters; - private boolean notifiedAudioSessionId; - - public FakeAudioRenderer(Handler handler, AudioRendererEventListener eventListener) { - super(Builder.AUDIO_FORMAT); - eventDispatcher = new AudioRendererEventListener.EventDispatcher(handler, eventListener); - decoderCounters = new DecoderCounters(); - } - - @Override - protected void onEnabled(boolean joining) throws ExoPlaybackException { - super.onEnabled(joining); - eventDispatcher.enabled(decoderCounters); - notifiedAudioSessionId = false; - } - - @Override - protected void onDisabled() { - super.onDisabled(); - eventDispatcher.disabled(decoderCounters); - } - - @Override - protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { - super.onPositionReset(positionUs, joining); - } - - @Override - protected void onFormatChanged(Format format) { - eventDispatcher.inputFormatChanged(format); - eventDispatcher.decoderInitialized( - /* decoderName= */ "fake.audio.decoder", - /* initializedTimestampMs= */ SystemClock.elapsedRealtime(), - /* initializationDurationMs= */ 0); - } - - @Override - protected void onBufferRead() { - if (!notifiedAudioSessionId) { - eventDispatcher.audioSessionId(/* audioSessionId= */ 0); - notifiedAudioSessionId = true; - } - } - } - - private static final class EventWindowAndPeriodId { - - private final int windowIndex; - private final @Nullable MediaPeriodId mediaPeriodId; - - public EventWindowAndPeriodId(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { - this.windowIndex = windowIndex; - this.mediaPeriodId = mediaPeriodId; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof EventWindowAndPeriodId)) { - return false; - } - EventWindowAndPeriodId event = (EventWindowAndPeriodId) other; - return windowIndex == event.windowIndex && Util.areEqual(mediaPeriodId, event.mediaPeriodId); - } - - @Override - public String toString() { - return mediaPeriodId != null - ? "Event{" - + "window=" - + windowIndex - + ", period=" - + mediaPeriodId.periodIndex - + ", sequence=" - + mediaPeriodId.windowSequenceNumber - + '}' - : "Event{" + "window=" + windowIndex + ", period = null}"; - } - - @Override - public int hashCode() { - return 31 * windowIndex + (mediaPeriodId == null ? 0 : mediaPeriodId.hashCode()); - } - } - - private static final class TestAnalyticsListener implements AnalyticsListener { - - private final ArrayList reportedEvents; - - public TestAnalyticsListener() { - reportedEvents = new ArrayList<>(); - } - - public List getEvents(int eventType) { - ArrayList eventTimes = new ArrayList<>(); - Iterator eventIterator = reportedEvents.iterator(); - while (eventIterator.hasNext()) { - ReportedEvent event = eventIterator.next(); - if (event.eventType == eventType) { - eventTimes.add(event.eventWindowAndPeriodId); - eventIterator.remove(); - } - } - return eventTimes; - } - - public void assertNoMoreEvents() { - assertThat(reportedEvents).isEmpty(); - } - - @Override - public void onPlayerStateChanged( - EventTime eventTime, boolean playWhenReady, int playbackState) { - reportedEvents.add(new ReportedEvent(EVENT_PLAYER_STATE_CHANGED, eventTime)); - } - - @Override - public void onTimelineChanged(EventTime eventTime, int reason) { - reportedEvents.add(new ReportedEvent(EVENT_TIMELINE_CHANGED, eventTime)); - } - - @Override - public void onPositionDiscontinuity(EventTime eventTime, int reason) { - reportedEvents.add(new ReportedEvent(EVENT_POSITION_DISCONTINUITY, eventTime)); - } - - @Override - public void onSeekStarted(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_SEEK_STARTED, eventTime)); - } - - @Override - public void onSeekProcessed(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_SEEK_PROCESSED, eventTime)); - } - - @Override - public void onPlaybackParametersChanged( - EventTime eventTime, PlaybackParameters playbackParameters) { - reportedEvents.add(new ReportedEvent(EVENT_PLAYBACK_PARAMETERS_CHANGED, eventTime)); - } - - @Override - public void onRepeatModeChanged(EventTime eventTime, int repeatMode) { - reportedEvents.add(new ReportedEvent(EVENT_REPEAT_MODE_CHANGED, eventTime)); - } - - @Override - public void onShuffleModeChanged(EventTime eventTime, boolean shuffleModeEnabled) { - reportedEvents.add(new ReportedEvent(EVENT_SHUFFLE_MODE_CHANGED, eventTime)); - } - - @Override - public void onLoadingChanged(EventTime eventTime, boolean isLoading) { - reportedEvents.add(new ReportedEvent(EVENT_LOADING_CHANGED, eventTime)); - } - - @Override - public void onPlayerError(EventTime eventTime, ExoPlaybackException error) { - reportedEvents.add(new ReportedEvent(EVENT_PLAYER_ERROR, eventTime)); - } - - @Override - public void onTracksChanged( - EventTime eventTime, TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - reportedEvents.add(new ReportedEvent(EVENT_TRACKS_CHANGED, eventTime)); - } - - @Override - public void onLoadStarted( - EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { - reportedEvents.add(new ReportedEvent(EVENT_LOAD_STARTED, eventTime)); - } - - @Override - public void onLoadCompleted( - EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { - reportedEvents.add(new ReportedEvent(EVENT_LOAD_COMPLETED, eventTime)); - } - - @Override - public void onLoadCanceled( - EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { - reportedEvents.add(new ReportedEvent(EVENT_LOAD_CANCELED, eventTime)); - } - - @Override - public void onLoadError( - EventTime eventTime, - LoadEventInfo loadEventInfo, - MediaLoadData mediaLoadData, - IOException error, - boolean wasCanceled) { - reportedEvents.add(new ReportedEvent(EVENT_LOAD_ERROR, eventTime)); - } - - @Override - public void onDownstreamFormatChanged(EventTime eventTime, MediaLoadData mediaLoadData) { - reportedEvents.add(new ReportedEvent(EVENT_DOWNSTREAM_FORMAT_CHANGED, eventTime)); - } - - @Override - public void onUpstreamDiscarded(EventTime eventTime, MediaLoadData mediaLoadData) { - reportedEvents.add(new ReportedEvent(EVENT_UPSTREAM_DISCARDED, eventTime)); - } - - @Override - public void onMediaPeriodCreated(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_MEDIA_PERIOD_CREATED, eventTime)); - } - - @Override - public void onMediaPeriodReleased(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_MEDIA_PERIOD_RELEASED, eventTime)); - } - - @Override - public void onReadingStarted(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_READING_STARTED, eventTime)); - } - - @Override - public void onBandwidthEstimate( - EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) { - reportedEvents.add(new ReportedEvent(EVENT_BANDWIDTH_ESTIMATE, eventTime)); - } - - @Override - public void onViewportSizeChange(EventTime eventTime, int width, int height) { - reportedEvents.add(new ReportedEvent(EVENT_VIEWPORT_SIZE_CHANGED, eventTime)); - } - - @Override - public void onNetworkTypeChanged(EventTime eventTime, @Nullable NetworkInfo networkInfo) { - reportedEvents.add(new ReportedEvent(EVENT_NETWORK_TYPE_CHANGED, eventTime)); - } - - @Override - public void onMetadata(EventTime eventTime, Metadata metadata) { - reportedEvents.add(new ReportedEvent(EVENT_METADATA, eventTime)); - } - - @Override - public void onDecoderEnabled( - EventTime eventTime, int trackType, DecoderCounters decoderCounters) { - reportedEvents.add(new ReportedEvent(EVENT_DECODER_ENABLED, eventTime)); - } - - @Override - public void onDecoderInitialized( - EventTime eventTime, int trackType, String decoderName, long initializationDurationMs) { - reportedEvents.add(new ReportedEvent(EVENT_DECODER_INIT, eventTime)); - } - - @Override - public void onDecoderInputFormatChanged(EventTime eventTime, int trackType, Format format) { - reportedEvents.add(new ReportedEvent(EVENT_DECODER_FORMAT_CHANGED, eventTime)); - } - - @Override - public void onDecoderDisabled( - EventTime eventTime, int trackType, DecoderCounters decoderCounters) { - reportedEvents.add(new ReportedEvent(EVENT_DECODER_DISABLED, eventTime)); - } - - @Override - public void onAudioSessionId(EventTime eventTime, int audioSessionId) { - reportedEvents.add(new ReportedEvent(EVENT_AUDIO_SESSION_ID, eventTime)); - } - - @Override - public void onAudioUnderrun( - EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { - reportedEvents.add(new ReportedEvent(EVENT_AUDIO_UNDERRUN, eventTime)); - } - - @Override - public void onDroppedVideoFrames(EventTime eventTime, int droppedFrames, long elapsedMs) { - reportedEvents.add(new ReportedEvent(EVENT_DROPPED_VIDEO_FRAMES, eventTime)); - } - - @Override - public void onVideoSizeChanged( - EventTime eventTime, - int width, - int height, - int unappliedRotationDegrees, - float pixelWidthHeightRatio) { - reportedEvents.add(new ReportedEvent(EVENT_VIDEO_SIZE_CHANGED, eventTime)); - } - - @Override - public void onRenderedFirstFrame(EventTime eventTime, Surface surface) { - reportedEvents.add(new ReportedEvent(EVENT_RENDERED_FIRST_FRAME, eventTime)); - } - - @Override - public void onAdLoadError(EventTime eventTime, IOException error) { - reportedEvents.add(new ReportedEvent(EVENT_AD_LOAD_ERROR, eventTime)); - } - - @Override - public void onInternalAdLoadError(EventTime eventTime, RuntimeException error) { - reportedEvents.add(new ReportedEvent(EVENT_INTERNAL_AD_LOAD_ERROR, eventTime)); - } - - @Override - public void onAdClicked(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_AD_CLICKED, eventTime)); - } - - @Override - public void onAdTapped(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_AD_TAPPED, eventTime)); - } - - @Override - public void onDrmKeysLoaded(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_DRM_KEYS_LOADED, eventTime)); - } - - @Override - public void onDrmSessionManagerError(EventTime eventTime, Exception error) { - reportedEvents.add(new ReportedEvent(EVENT_DRM_ERROR, eventTime)); - } - - @Override - public void onDrmKeysRestored(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_DRM_KEYS_RESTORED, eventTime)); - } - - @Override - public void onDrmKeysRemoved(EventTime eventTime) { - reportedEvents.add(new ReportedEvent(EVENT_DRM_KEYS_REMOVED, eventTime)); - } - - private static final class ReportedEvent { - - public final int eventType; - public final EventWindowAndPeriodId eventWindowAndPeriodId; - - public ReportedEvent(int eventType, EventTime eventTime) { - this.eventType = eventType; - this.eventWindowAndPeriodId = - new EventWindowAndPeriodId(eventTime.windowIndex, eventTime.mediaPeriodId); - } - } - } -} diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java index cf7470b80a..6855ca4cc3 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java @@ -28,8 +28,6 @@ import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.analytics.AnalyticsCollector; -import com.google.android.exoplayer2.analytics.AnalyticsListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; @@ -88,7 +86,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener private Player.EventListener eventListener; private VideoRendererEventListener videoRendererEventListener; private AudioRendererEventListener audioRendererEventListener; - private AnalyticsListener analyticsListener; private Integer expectedPlayerEndedCount; /** @@ -264,17 +261,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener return this; } - /** - * Sets an {@link AnalyticsListener} to be registered. - * - * @param analyticsListener An {@link AnalyticsListener} to be registered. - * @return This builder. - */ - public Builder setAnalyticsListener(AnalyticsListener analyticsListener) { - this.analyticsListener = analyticsListener; - return this; - } - /** * Sets the number of times the test runner is expected to reach the {@link Player#STATE_ENDED} * or {@link Player#STATE_IDLE}. The default is 1. This affects how long @@ -344,7 +330,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener eventListener, videoRendererEventListener, audioRendererEventListener, - analyticsListener, expectedPlayerEndedCount); } } @@ -358,7 +343,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener private final @Nullable Player.EventListener eventListener; private final @Nullable VideoRendererEventListener videoRendererEventListener; private final @Nullable AudioRendererEventListener audioRendererEventListener; - private final @Nullable AnalyticsListener analyticsListener; private final HandlerThread playerThread; private final HandlerWrapper handler; @@ -385,7 +369,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener @Nullable Player.EventListener eventListener, @Nullable VideoRendererEventListener videoRendererEventListener, @Nullable AudioRendererEventListener audioRendererEventListener, - @Nullable AnalyticsListener analyticsListener, int expectedPlayerEndedCount) { this.clock = clock; this.mediaSource = mediaSource; @@ -396,7 +379,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener this.eventListener = eventListener; this.videoRendererEventListener = videoRendererEventListener; this.audioRendererEventListener = audioRendererEventListener; - this.analyticsListener = analyticsListener; this.timelines = new ArrayList<>(); this.manifests = new ArrayList<>(); this.timelineChangeReasons = new ArrayList<>(); @@ -435,9 +417,6 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener if (audioRendererEventListener != null) { player.addAudioDebugListener(audioRendererEventListener); } - if (analyticsListener != null) { - player.addAnalyticsListener(analyticsListener); - } player.setPlayWhenReady(true); if (actionSchedule != null) { actionSchedule.start( @@ -657,13 +636,7 @@ public final class ExoPlayerTestRunner extends Player.DefaultEventListener TrackSelector trackSelector, LoadControl loadControl, Clock clock) { - super( - renderersFactory, - trackSelector, - loadControl, - /* drmSessionManager= */ null, - new AnalyticsCollector.Factory(), - clock); + super(renderersFactory, trackSelector, loadControl, /* drmSessionManager= */ null, clock); } } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java index 0d65d7fcc7..171e237fd1 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java @@ -85,7 +85,6 @@ public class FakeRenderer extends BaseRenderer { if (result == C.RESULT_FORMAT_READ) { formatReadCount++; assertThat(expectedFormats).contains(formatHolder.format); - onFormatChanged(formatHolder.format); } else if (result == C.RESULT_BUFFER_READ) { if (buffer.isEndOfStream()) { isEnded = true; @@ -93,7 +92,6 @@ public class FakeRenderer extends BaseRenderer { } lastSamplePositionUs = buffer.timeUs; sampleBufferReadCount++; - onBufferRead(); } else { Assertions.checkState(result == C.RESULT_NOTHING_READ); return; @@ -117,9 +115,4 @@ public class FakeRenderer extends BaseRenderer { ? (FORMAT_HANDLED | ADAPTIVE_SEAMLESS) : FORMAT_UNSUPPORTED_TYPE; } - /** Called when the renderer reads a new format. */ - protected void onFormatChanged(Format format) {} - - /** Called when the renderer read a sample from the buffer. */ - protected void onBufferRead() {} }