Commit 74e2384f by tonihei Committed by Oliver Woodman

Add response headers to LoadEventInfo.

The response headers of the last load are available from the loading source
when creating media source events and can be easily forwarded.

Issue:#4361
Issue:#4615

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=209900693
parent 4bf5e499
......@@ -101,6 +101,10 @@
* Add uri field to `LoadEventInfo` in `MediaSourceEventListener` or
`AnalyticsListener` callbacks. This uri is the redirected uri if redirection
occurred ([#2054](https://github.com/google/ExoPlayer/issues/2054)).
* Add response headers field to `LoadEventInfo` in `MediaSourceEventListener` or
`AnalyticsListener` callbacks
([#4361](https://github.com/google/ExoPlayer/issues/4361) and
[#4615](https://github.com/google/ExoPlayer/issues/4615)).
* Allow `MediaCodecSelector`s to return multiple compatible decoders for
`MediaCodecRenderer`, and provide an (optional) `MediaCodecSelector` that
falls back to less preferred decoders like `MediaCodec.createDecoderByType`
......
......@@ -503,6 +503,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......@@ -524,6 +525,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......@@ -570,6 +572,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
eventDispatcher.loadError(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......@@ -697,7 +700,6 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(dataType));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......
......@@ -28,6 +28,9 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/** Interface for callbacks to be notified of {@link MediaSource} events. */
......@@ -44,6 +47,8 @@ public interface MediaSourceEventListener {
* after redirection.
*/
public final Uri uri;
/** The response headers associated with the load, or an empty map if unavailable. */
public final Map<String, List<String>> responseHeaders;
/** The value of {@link SystemClock#elapsedRealtime} at the time of the load event. */
public final long elapsedRealtimeMs;
/** The duration of the load up to the event time. */
......@@ -58,6 +63,8 @@ public interface MediaSourceEventListener {
* @param uri The {@link Uri} from which data is being read. The uri must be identical to the
* one in {@code dataSpec.uri} unless redirection has occurred. If redirection has occurred,
* this is the uri after redirection.
* @param responseHeaders The response headers associated with the load, or an empty map if
* unavailable.
* @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} at the time of the
* load event.
* @param loadDurationMs The duration of the load up to the event time.
......@@ -65,9 +72,15 @@ public interface MediaSourceEventListener {
* network responses, this is the decompressed size.
*/
public LoadEventInfo(
DataSpec dataSpec, Uri uri, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
long elapsedRealtimeMs,
long loadDurationMs,
long bytesLoaded) {
this.dataSpec = dataSpec;
this.uri = uri;
this.responseHeaders = responseHeaders;
this.elapsedRealtimeMs = elapsedRealtimeMs;
this.loadDurationMs = loadDurationMs;
this.bytesLoaded = bytesLoaded;
......@@ -168,7 +181,8 @@ public interface MediaSourceEventListener {
* @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not
* belong to a specific media period.
* @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The value of {@link
* LoadEventInfo#uri} won't reflect potential redirection yet.
* LoadEventInfo#uri} won't reflect potential redirection yet and {@link
* LoadEventInfo#responseHeaders} will be empty.
* @param mediaLoadData The {@link MediaLoadData} defining the data being loaded.
*/
void onLoadStarted(
......@@ -370,10 +384,9 @@ public interface MediaSourceEventListener {
}
/** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */
public void loadStarted(DataSpec dataSpec, Uri uri, int dataType, long elapsedRealtimeMs) {
public void loadStarted(DataSpec dataSpec, int dataType, long elapsedRealtimeMs) {
loadStarted(
dataSpec,
uri,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
......@@ -387,7 +400,6 @@ public interface MediaSourceEventListener {
/** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */
public void loadStarted(
DataSpec dataSpec,
Uri uri,
int dataType,
int trackType,
@Nullable Format trackFormat,
......@@ -398,7 +410,12 @@ public interface MediaSourceEventListener {
long elapsedRealtimeMs) {
loadStarted(
new LoadEventInfo(
dataSpec, uri, elapsedRealtimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0),
dataSpec,
dataSpec.uri,
/* responseHeaders= */ Collections.emptyMap(),
elapsedRealtimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ 0),
new MediaLoadData(
dataType,
trackType,
......@@ -423,6 +440,7 @@ public interface MediaSourceEventListener {
public void loadCompleted(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
long elapsedRealtimeMs,
long loadDurationMs,
......@@ -430,6 +448,7 @@ public interface MediaSourceEventListener {
loadCompleted(
dataSpec,
uri,
responseHeaders,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
......@@ -446,6 +465,7 @@ public interface MediaSourceEventListener {
public void loadCompleted(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
int trackType,
@Nullable Format trackFormat,
......@@ -457,7 +477,8 @@ public interface MediaSourceEventListener {
long loadDurationMs,
long bytesLoaded) {
loadCompleted(
new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new LoadEventInfo(
dataSpec, uri, responseHeaders, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new MediaLoadData(
dataType,
trackType,
......@@ -483,6 +504,7 @@ public interface MediaSourceEventListener {
public void loadCanceled(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
long elapsedRealtimeMs,
long loadDurationMs,
......@@ -490,6 +512,7 @@ public interface MediaSourceEventListener {
loadCanceled(
dataSpec,
uri,
responseHeaders,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
......@@ -506,6 +529,7 @@ public interface MediaSourceEventListener {
public void loadCanceled(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
int trackType,
@Nullable Format trackFormat,
......@@ -517,7 +541,8 @@ public interface MediaSourceEventListener {
long loadDurationMs,
long bytesLoaded) {
loadCanceled(
new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new LoadEventInfo(
dataSpec, uri, responseHeaders, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new MediaLoadData(
dataType,
trackType,
......@@ -546,6 +571,7 @@ public interface MediaSourceEventListener {
public void loadError(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
long elapsedRealtimeMs,
long loadDurationMs,
......@@ -555,6 +581,7 @@ public interface MediaSourceEventListener {
loadError(
dataSpec,
uri,
responseHeaders,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
......@@ -576,6 +603,7 @@ public interface MediaSourceEventListener {
public void loadError(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
int trackType,
@Nullable Format trackFormat,
......@@ -589,7 +617,8 @@ public interface MediaSourceEventListener {
IOException error,
boolean wasCanceled) {
loadError(
new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new LoadEventInfo(
dataSpec, uri, responseHeaders, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new MediaLoadData(
dataType,
trackType,
......
......@@ -155,7 +155,6 @@ import java.util.Arrays;
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(C.DATA_TYPE_MEDIA));
eventDispatcher.loadStarted(
dataSpec,
dataSpec.uri,
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
......@@ -211,6 +210,7 @@ import java.util.Arrays;
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
......@@ -229,6 +229,7 @@ import java.util.Arrays;
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......@@ -269,6 +270,7 @@ import java.util.Arrays;
eventDispatcher.loadError(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
......
......@@ -43,6 +43,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -556,6 +557,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
.loadError(
dataSpec,
dataSpec.uri,
/* responseHeaders= */ Collections.emptyMap(),
C.DATA_TYPE_AD,
C.TRACK_TYPE_UNKNOWN,
/* loadDurationMs= */ 0,
......@@ -595,6 +597,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
.loadError(
new DataSpec(adUri),
adUri,
/* responseHeaders= */ Collections.emptyMap(),
C.DATA_TYPE_AD,
C.TRACK_TYPE_UNKNOWN,
/* loadDurationMs= */ 0,
......
......@@ -432,6 +432,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
......@@ -451,6 +452,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
......@@ -518,6 +520,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
......@@ -585,7 +588,6 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
loadable.type,
primaryTrackType,
loadable.trackFormat,
......
......@@ -24,6 +24,8 @@ import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* A {@link Loadable} for objects that can be parsed from binary data using a {@link Parser}.
......@@ -132,6 +134,14 @@ public final class ParsingLoadable<T> implements Loadable {
return dataSource.getLastOpenedUri();
}
/**
* Returns the response headers associated with the load. Must only be called after the load
* completed, failed, or was canceled.
*/
public Map<String, List<String>> getResponseHeaders() {
return dataSource.getLastResponseHeaders();
}
@Override
public final void cancelLoad() {
// Do nothing.
......
......@@ -709,6 +709,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -800,6 +801,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -814,6 +816,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -829,6 +832,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -844,6 +848,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -1031,8 +1036,7 @@ public final class DashMediaSource extends BaseMediaSource {
private <T> void startLoading(ParsingLoadable<T> loadable,
Loader.Callback<ParsingLoadable<T>> callback, int minRetryCount) {
long elapsedRealtimeMs = loader.startLoading(loadable, callback, minRetryCount);
manifestEventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs);
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
}
private long getNowUnixTimeUs() {
......
......@@ -571,7 +571,6 @@ import java.util.List;
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
loadable.type,
trackType,
loadable.trackFormat,
......@@ -596,6 +595,7 @@ import java.util.List;
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
trackType,
loadable.trackFormat,
......@@ -619,6 +619,7 @@ import java.util.List;
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
trackType,
loadable.trackFormat,
......@@ -680,6 +681,7 @@ import java.util.List;
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
trackType,
loadable.trackFormat,
......
......@@ -123,7 +123,6 @@ public final class DefaultHlsPlaylistTracker
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(masterPlaylistLoadable.type));
eventDispatcher.loadStarted(
masterPlaylistLoadable.dataSpec,
masterPlaylistLoadable.dataSpec.uri,
masterPlaylistLoadable.type,
elapsedRealtime);
}
......@@ -234,6 +233,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
......@@ -249,6 +249,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
......@@ -269,6 +270,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
......@@ -496,6 +498,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
......@@ -514,6 +517,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
......@@ -555,6 +559,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
......@@ -583,7 +588,6 @@ public final class DefaultHlsPlaylistTracker
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(mediaPlaylistLoadable.type));
eventDispatcher.loadStarted(
mediaPlaylistLoadable.dataSpec,
mediaPlaylistLoadable.dataSpec.uri,
mediaPlaylistLoadable.type,
elapsedRealtime);
}
......
......@@ -569,6 +569,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestEventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -585,6 +586,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestEventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -602,6 +604,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
......@@ -692,8 +695,7 @@ public final class SsMediaSource extends BaseMediaSource
long elapsedRealtimeMs =
manifestLoader.startLoading(
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
manifestEventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs);
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
}
}
......@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSpec;
import java.io.IOException;
import java.util.Collections;
/**
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting
......@@ -115,7 +116,6 @@ public class FakeMediaPeriod implements MediaPeriod {
public synchronized void prepare(Callback callback, long positionUs) {
eventDispatcher.loadStarted(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......@@ -228,6 +228,7 @@ public class FakeMediaPeriod implements MediaPeriod {
eventDispatcher.loadCompleted(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
......
......@@ -40,6 +40,7 @@ import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
......@@ -225,6 +226,7 @@ public class FakeMediaSource extends BaseMediaSource {
new LoadEventInfo(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
elapsedRealTimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ 0),
......@@ -233,6 +235,7 @@ public class FakeMediaSource extends BaseMediaSource {
new LoadEventInfo(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
elapsedRealTimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ MANIFEST_LOAD_BYTES),
......
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