Commit 18eccf9a by tonihei

Make sure not to create new playback sessions while still IDLE.

The first session should only be created once we have the media items
and/or called prepare. Otherwise the first session is created with
an EventTime having an empty timeline making it less useful.

issue:#7193
PiperOrigin-RevId: 308100555
parent 1062edf5
...@@ -243,7 +243,7 @@ public final class PlaybackStatsListener ...@@ -243,7 +243,7 @@ public final class PlaybackStatsListener
EventTime eventTime, boolean playWhenReady, @Player.State int playbackState) { EventTime eventTime, boolean playWhenReady, @Player.State int playbackState) {
this.playWhenReady = playWhenReady; this.playWhenReady = playWhenReady;
this.playbackState = playbackState; this.playbackState = playbackState;
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
boolean belongsToPlayback = sessionManager.belongsToSession(eventTime, session); boolean belongsToPlayback = sessionManager.belongsToSession(eventTime, session);
playbackStatsTrackers playbackStatsTrackers
...@@ -256,7 +256,7 @@ public final class PlaybackStatsListener ...@@ -256,7 +256,7 @@ public final class PlaybackStatsListener
public void onPlaybackSuppressionReasonChanged( public void onPlaybackSuppressionReasonChanged(
EventTime eventTime, int playbackSuppressionReason) { EventTime eventTime, int playbackSuppressionReason) {
isSuppressed = playbackSuppressionReason != Player.PLAYBACK_SUPPRESSION_REASON_NONE; isSuppressed = playbackSuppressionReason != Player.PLAYBACK_SUPPRESSION_REASON_NONE;
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
boolean belongsToPlayback = sessionManager.belongsToSession(eventTime, session); boolean belongsToPlayback = sessionManager.belongsToSession(eventTime, session);
playbackStatsTrackers playbackStatsTrackers
...@@ -268,7 +268,7 @@ public final class PlaybackStatsListener ...@@ -268,7 +268,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onTimelineChanged(EventTime eventTime, int reason) { public void onTimelineChanged(EventTime eventTime, int reason) {
sessionManager.handleTimelineUpdate(eventTime); sessionManager.handleTimelineUpdate(eventTime);
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onPositionDiscontinuity(eventTime); playbackStatsTrackers.get(session).onPositionDiscontinuity(eventTime);
...@@ -279,7 +279,7 @@ public final class PlaybackStatsListener ...@@ -279,7 +279,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onPositionDiscontinuity(EventTime eventTime, int reason) { public void onPositionDiscontinuity(EventTime eventTime, int reason) {
sessionManager.handlePositionDiscontinuity(eventTime, reason); sessionManager.handlePositionDiscontinuity(eventTime, reason);
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onPositionDiscontinuity(eventTime); playbackStatsTrackers.get(session).onPositionDiscontinuity(eventTime);
...@@ -289,7 +289,7 @@ public final class PlaybackStatsListener ...@@ -289,7 +289,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onSeekStarted(EventTime eventTime) { public void onSeekStarted(EventTime eventTime) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onSeekStarted(eventTime); playbackStatsTrackers.get(session).onSeekStarted(eventTime);
...@@ -299,7 +299,7 @@ public final class PlaybackStatsListener ...@@ -299,7 +299,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onSeekProcessed(EventTime eventTime) { public void onSeekProcessed(EventTime eventTime) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onSeekProcessed(eventTime); playbackStatsTrackers.get(session).onSeekProcessed(eventTime);
...@@ -309,7 +309,7 @@ public final class PlaybackStatsListener ...@@ -309,7 +309,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onPlayerError(EventTime eventTime, ExoPlaybackException error) { public void onPlayerError(EventTime eventTime, ExoPlaybackException error) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onFatalError(eventTime, error); playbackStatsTrackers.get(session).onFatalError(eventTime, error);
...@@ -321,7 +321,7 @@ public final class PlaybackStatsListener ...@@ -321,7 +321,7 @@ public final class PlaybackStatsListener
public void onPlaybackParametersChanged( public void onPlaybackParametersChanged(
EventTime eventTime, PlaybackParameters playbackParameters) { EventTime eventTime, PlaybackParameters playbackParameters) {
playbackSpeed = playbackParameters.speed; playbackSpeed = playbackParameters.speed;
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (PlaybackStatsTracker tracker : playbackStatsTrackers.values()) { for (PlaybackStatsTracker tracker : playbackStatsTrackers.values()) {
tracker.onPlaybackSpeedChanged(eventTime, playbackSpeed); tracker.onPlaybackSpeedChanged(eventTime, playbackSpeed);
} }
...@@ -330,7 +330,7 @@ public final class PlaybackStatsListener ...@@ -330,7 +330,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onTracksChanged( public void onTracksChanged(
EventTime eventTime, TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { EventTime eventTime, TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onTracksChanged(eventTime, trackSelections); playbackStatsTrackers.get(session).onTracksChanged(eventTime, trackSelections);
...@@ -341,7 +341,7 @@ public final class PlaybackStatsListener ...@@ -341,7 +341,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onLoadStarted( public void onLoadStarted(
EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onLoadStarted(eventTime); playbackStatsTrackers.get(session).onLoadStarted(eventTime);
...@@ -351,7 +351,7 @@ public final class PlaybackStatsListener ...@@ -351,7 +351,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onDownstreamFormatChanged(EventTime eventTime, MediaLoadData mediaLoadData) { public void onDownstreamFormatChanged(EventTime eventTime, MediaLoadData mediaLoadData) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onDownstreamFormatChanged(eventTime, mediaLoadData); playbackStatsTrackers.get(session).onDownstreamFormatChanged(eventTime, mediaLoadData);
...@@ -366,7 +366,7 @@ public final class PlaybackStatsListener ...@@ -366,7 +366,7 @@ public final class PlaybackStatsListener
int height, int height,
int unappliedRotationDegrees, int unappliedRotationDegrees,
float pixelWidthHeightRatio) { float pixelWidthHeightRatio) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onVideoSizeChanged(eventTime, width, height); playbackStatsTrackers.get(session).onVideoSizeChanged(eventTime, width, height);
...@@ -377,7 +377,7 @@ public final class PlaybackStatsListener ...@@ -377,7 +377,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onBandwidthEstimate( public void onBandwidthEstimate(
EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) { EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onBandwidthData(totalLoadTimeMs, totalBytesLoaded); playbackStatsTrackers.get(session).onBandwidthData(totalLoadTimeMs, totalBytesLoaded);
...@@ -388,7 +388,7 @@ public final class PlaybackStatsListener ...@@ -388,7 +388,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onAudioUnderrun( public void onAudioUnderrun(
EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onAudioUnderrun(); playbackStatsTrackers.get(session).onAudioUnderrun();
...@@ -398,7 +398,7 @@ public final class PlaybackStatsListener ...@@ -398,7 +398,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onDroppedVideoFrames(EventTime eventTime, int droppedFrames, long elapsedMs) { public void onDroppedVideoFrames(EventTime eventTime, int droppedFrames, long elapsedMs) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onDroppedVideoFrames(droppedFrames); playbackStatsTrackers.get(session).onDroppedVideoFrames(droppedFrames);
...@@ -413,7 +413,7 @@ public final class PlaybackStatsListener ...@@ -413,7 +413,7 @@ public final class PlaybackStatsListener
MediaLoadData mediaLoadData, MediaLoadData mediaLoadData,
IOException error, IOException error,
boolean wasCanceled) { boolean wasCanceled) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onNonFatalError(eventTime, error); playbackStatsTrackers.get(session).onNonFatalError(eventTime, error);
...@@ -423,7 +423,7 @@ public final class PlaybackStatsListener ...@@ -423,7 +423,7 @@ public final class PlaybackStatsListener
@Override @Override
public void onDrmSessionManagerError(EventTime eventTime, Exception error) { public void onDrmSessionManagerError(EventTime eventTime, Exception error) {
sessionManager.updateSessions(eventTime); maybeAddSession(eventTime);
for (String session : playbackStatsTrackers.keySet()) { for (String session : playbackStatsTrackers.keySet()) {
if (sessionManager.belongsToSession(eventTime, session)) { if (sessionManager.belongsToSession(eventTime, session)) {
playbackStatsTrackers.get(session).onNonFatalError(eventTime, error); playbackStatsTrackers.get(session).onNonFatalError(eventTime, error);
...@@ -431,6 +431,13 @@ public final class PlaybackStatsListener ...@@ -431,6 +431,13 @@ public final class PlaybackStatsListener
} }
} }
private void maybeAddSession(EventTime eventTime) {
boolean isCompletelyIdle = eventTime.timeline.isEmpty() && playbackState == Player.STATE_IDLE;
if (!isCompletelyIdle) {
sessionManager.updateSessions(eventTime);
}
}
/** Tracker for playback stats of a single playback. */ /** Tracker for playback stats of a single playback. */
private static final class PlaybackStatsTracker { private static final class PlaybackStatsTracker {
......
...@@ -21,6 +21,8 @@ import androidx.annotation.Nullable; ...@@ -21,6 +21,8 @@ import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.testutil.FakeTimeline;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -28,7 +30,7 @@ import org.junit.runner.RunWith; ...@@ -28,7 +30,7 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public final class PlaybackStatsListenerTest { public final class PlaybackStatsListenerTest {
private static final AnalyticsListener.EventTime TEST_EVENT_TIME = private static final AnalyticsListener.EventTime EMPTY_TIMELINE_EVENT_TIME =
new AnalyticsListener.EventTime( new AnalyticsListener.EventTime(
/* realtimeMs= */ 500, /* realtimeMs= */ 500,
Timeline.EMPTY, Timeline.EMPTY,
...@@ -37,6 +39,41 @@ public final class PlaybackStatsListenerTest { ...@@ -37,6 +39,41 @@ public final class PlaybackStatsListenerTest {
/* eventPlaybackPositionMs= */ 0, /* eventPlaybackPositionMs= */ 0,
/* currentPlaybackPositionMs= */ 0, /* currentPlaybackPositionMs= */ 0,
/* totalBufferedDurationMs= */ 0); /* totalBufferedDurationMs= */ 0);
private static final Timeline TEST_TIMELINE = new FakeTimeline(/* windowCount= */ 1);
private static final AnalyticsListener.EventTime TEST_EVENT_TIME =
new AnalyticsListener.EventTime(
/* realtimeMs= */ 700,
TEST_TIMELINE,
/* windowIndex= */ 0,
new MediaSource.MediaPeriodId(
TEST_TIMELINE.getPeriod(
/* periodIndex= */ 0, new Timeline.Period(), /* setIds= */ true)
.uid,
/* windowSequenceNumber= */ 42),
/* eventPlaybackPositionMs= */ 123,
/* currentPlaybackPositionMs= */ 123,
/* totalBufferedDurationMs= */ 456);
@Test
public void stateChangeEvent_toNonIdle_createsInitialPlaybackStats() {
PlaybackStatsListener playbackStatsListener =
new PlaybackStatsListener(/* keepHistory= */ true, /* callback= */ null);
playbackStatsListener.onPlayerStateChanged(
EMPTY_TIMELINE_EVENT_TIME, /* playWhenReady= */ false, Player.STATE_BUFFERING);
assertThat(playbackStatsListener.getPlaybackStats()).isNotNull();
}
@Test
public void timelineChangeEvent_toNonEmpty_createsInitialPlaybackStats() {
PlaybackStatsListener playbackStatsListener =
new PlaybackStatsListener(/* keepHistory= */ true, /* callback= */ null);
playbackStatsListener.onTimelineChanged(TEST_EVENT_TIME, Player.TIMELINE_CHANGE_REASON_DYNAMIC);
assertThat(playbackStatsListener.getPlaybackStats()).isNotNull();
}
@Test @Test
public void playback_withKeepHistory_updatesStats() { public void playback_withKeepHistory_updatesStats() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment