diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/PlaybackStatsListener.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/PlaybackStatsListener.java index afff94cb58..8b9967addb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/PlaybackStatsListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/PlaybackStatsListener.java @@ -282,18 +282,16 @@ public final class PlaybackStatsListener } private void maybeAddSessions(Player player, Events events) { - if (player.getCurrentTimeline().isEmpty() && player.getPlaybackState() == Player.STATE_IDLE) { - // Player is completely idle. Don't add new sessions. - return; - } + boolean isCompletelyIdle = + player.getCurrentTimeline().isEmpty() && player.getPlaybackState() == Player.STATE_IDLE; for (int i = 0; i < events.size(); i++) { @EventFlags int event = events.get(i); EventTime eventTime = events.getEventTime(event); if (event == EVENT_TIMELINE_CHANGED) { sessionManager.updateSessionsWithTimelineChange(eventTime); - } else if (event == EVENT_POSITION_DISCONTINUITY) { + } else if (!isCompletelyIdle && event == EVENT_POSITION_DISCONTINUITY) { sessionManager.updateSessionsWithDiscontinuity(eventTime, discontinuityReason); - } else { + } else if (!isCompletelyIdle) { sessionManager.updateSessions(eventTime); } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/analytics/PlaybackStatsListenerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/analytics/PlaybackStatsListenerTest.java index bd5dfb97a5..0fa1a4a85b 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/analytics/PlaybackStatsListenerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/analytics/PlaybackStatsListenerTest.java @@ -152,6 +152,35 @@ public final class PlaybackStatsListenerTest { verify(callback).onPlaybackStatsReady(any(), any()); } + @Test + public void playlistClear_callsAllPendingCallbacks() throws Exception { + PlaybackStatsListener.Callback callback = mock(PlaybackStatsListener.Callback.class); + PlaybackStatsListener playbackStatsListener = + new PlaybackStatsListener(/* keepHistory= */ true, callback); + player.addAnalyticsListener(playbackStatsListener); + + MediaSource mediaSource = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1)); + player.setMediaSources(ImmutableList.of(mediaSource, mediaSource)); + player.prepare(); + TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY); + // Play close to the end of the first item to ensure the second session is already created, but + // the first one isn't finished yet. + TestPlayerRunHelper.playUntilPosition( + player, /* windowIndex= */ 0, /* positionMs= */ player.getDuration()); + runUntilPendingCommandsAreFullyHandled(player); + player.clearMediaItems(); + ShadowLooper.idleMainLooper(); + + ArgumentCaptor eventTimeCaptor = + ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); + verify(callback, times(2)).onPlaybackStatsReady(eventTimeCaptor.capture(), any()); + assertThat( + eventTimeCaptor.getAllValues().stream() + .map(eventTime -> eventTime.windowIndex) + .collect(Collectors.toList())) + .containsExactly(0, 1); + } + @Test public void playerRelease_callsAllPendingCallbacks() throws Exception { PlaybackStatsListener.Callback callback = mock(PlaybackStatsListener.Callback.class);