Avoid creating empty playback metrics

In some cases we create empty playback metrics with no corresponding
events (e.g. when an app seeks to a new media item and immediately
releases the player). There is no benefit in having completely empty
metrics entries, so it's cleaner to not report them in such cases.

#minor-release

PiperOrigin-RevId: 425609010
This commit is contained in:
tonihei 2022-02-01 14:25:04 +00:00 committed by Andrew Lewis
parent 45cbfd2977
commit aef808cb91

View File

@ -136,6 +136,7 @@ public final class MediaMetricsListener
private int droppedFrames; private int droppedFrames;
private int playedFrames; private int playedFrames;
private int audioUnderruns; private int audioUnderruns;
private boolean reportedEventsForCurrentSession;
/** /**
* Creates the listener. * Creates the listener.
@ -361,6 +362,7 @@ public final class MediaMetricsListener
.setSubErrorCode(errorInfo.subErrorCode) .setSubErrorCode(errorInfo.subErrorCode)
.setException(error) .setException(error)
.build()); .build());
reportedEventsForCurrentSession = true;
pendingPlayerError = null; pendingPlayerError = null;
} }
@ -431,6 +433,7 @@ public final class MediaMetricsListener
int newPlaybackState = resolveNewPlaybackState(player); int newPlaybackState = resolveNewPlaybackState(player);
if (currentPlaybackState != newPlaybackState) { if (currentPlaybackState != newPlaybackState) {
currentPlaybackState = newPlaybackState; currentPlaybackState = newPlaybackState;
reportedEventsForCurrentSession = true;
playbackSession.reportPlaybackStateEvent( playbackSession.reportPlaybackStateEvent(
new PlaybackStateEvent.Builder() new PlaybackStateEvent.Builder()
.setState(currentPlaybackState) .setState(currentPlaybackState)
@ -563,6 +566,7 @@ public final class MediaMetricsListener
} else { } else {
builder.setTrackState(TrackChangeEvent.TRACK_STATE_OFF); builder.setTrackState(TrackChangeEvent.TRACK_STATE_OFF);
} }
reportedEventsForCurrentSession = true;
playbackSession.reportTrackChangeEvent(builder.build()); playbackSession.reportTrackChangeEvent(builder.build());
} }
@ -588,26 +592,26 @@ public final class MediaMetricsListener
} }
metricsBuilder.setPlaybackType( metricsBuilder.setPlaybackType(
window.isLive() ? PlaybackMetrics.PLAYBACK_TYPE_LIVE : PlaybackMetrics.PLAYBACK_TYPE_VOD); window.isLive() ? PlaybackMetrics.PLAYBACK_TYPE_LIVE : PlaybackMetrics.PLAYBACK_TYPE_VOD);
reportedEventsForCurrentSession = true;
} }
private void finishCurrentSession() { private void finishCurrentSession() {
if (metricsBuilder == null) { if (metricsBuilder != null && reportedEventsForCurrentSession) {
return; metricsBuilder.setAudioUnderrunCount(audioUnderruns);
metricsBuilder.setVideoFramesDropped(droppedFrames);
metricsBuilder.setVideoFramesPlayed(playedFrames);
@Nullable Long networkTimeMs = bandwidthTimeMs.get(activeSessionId);
metricsBuilder.setNetworkTransferDurationMillis(networkTimeMs == null ? 0 : networkTimeMs);
// TODO(b/181121847): Report localBytesRead. This requires additional callbacks or plumbing.
@Nullable Long networkBytes = bandwidthBytes.get(activeSessionId);
metricsBuilder.setNetworkBytesRead(networkBytes == null ? 0 : networkBytes);
// TODO(b/181121847): Detect stream sources mixed and local depending on localBytesRead.
metricsBuilder.setStreamSource(
networkBytes != null && networkBytes > 0
? PlaybackMetrics.STREAM_SOURCE_NETWORK
: PlaybackMetrics.STREAM_SOURCE_UNKNOWN);
playbackSession.reportPlaybackMetrics(metricsBuilder.build());
} }
metricsBuilder.setAudioUnderrunCount(audioUnderruns);
metricsBuilder.setVideoFramesDropped(droppedFrames);
metricsBuilder.setVideoFramesPlayed(playedFrames);
@Nullable Long networkTimeMs = bandwidthTimeMs.get(activeSessionId);
metricsBuilder.setNetworkTransferDurationMillis(networkTimeMs == null ? 0 : networkTimeMs);
// TODO(b/181121847): Report localBytesRead. This requires additional callbacks or plumbing.
@Nullable Long networkBytes = bandwidthBytes.get(activeSessionId);
metricsBuilder.setNetworkBytesRead(networkBytes == null ? 0 : networkBytes);
// TODO(b/181121847): Detect stream sources mixed and local depending on localBytesRead.
metricsBuilder.setStreamSource(
networkBytes != null && networkBytes > 0
? PlaybackMetrics.STREAM_SOURCE_NETWORK
: PlaybackMetrics.STREAM_SOURCE_UNKNOWN);
playbackSession.reportPlaybackMetrics(metricsBuilder.build());
metricsBuilder = null; metricsBuilder = null;
activeSessionId = null; activeSessionId = null;
audioUnderruns = 0; audioUnderruns = 0;
@ -616,6 +620,7 @@ public final class MediaMetricsListener
currentVideoFormat = null; currentVideoFormat = null;
currentAudioFormat = null; currentAudioFormat = null;
currentTextFormat = null; currentTextFormat = null;
reportedEventsForCurrentSession = false;
} }
private static int getTrackChangeReason(@C.SelectionReason int trackSelectionReason) { private static int getTrackChangeReason(@C.SelectionReason int trackSelectionReason) {