diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e40bfe8d81..59f30b8a0a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -15,6 +15,9 @@ * Add VR player demo. * Wrap decoder exceptions in a new `DecoderException` class and report as renderer error. +* Do not pass the manifest to callbacks of Player.EventListener and + SourceInfoRefreshListener anymore. Instead make it accessible through + Player.getCurrentManifest() and Timeline.Window.manifest. ### 2.10.3 ### diff --git a/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java b/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java index c92ebd7e94..d2a1ca0860 100644 --- a/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java +++ b/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java @@ -264,8 +264,7 @@ import org.json.JSONObject; } @Override - public void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) { + public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) { updateCurrentItemIndex(); } diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java index 03518ac18a..6a33aa0428 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java @@ -460,11 +460,6 @@ public final class CastPlayer extends BasePlayer { return currentTimeline; } - @Override - @Nullable public Object getCurrentManifest() { - return null; - } - @Override public int getCurrentPeriodIndex() { return getCurrentWindowIndex(); @@ -592,8 +587,7 @@ public final class CastPlayer extends BasePlayer { waitingForInitialTimeline = false; notificationsBatch.add( new ListenerNotificationTask( - listener -> - listener.onTimelineChanged(currentTimeline, /* manifest= */ null, reason))); + listener -> listener.onTimelineChanged(currentTimeline, reason))); } } diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTimeline.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTimeline.java index 800c19047b..b84f1c1f2b 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTimeline.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTimeline.java @@ -117,6 +117,7 @@ import java.util.Arrays; Object tag = setTag ? ids[windowIndex] : null; return window.set( tag, + /* manifest= */ null, /* presentationStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET, /* isSeekable= */ !isDynamic, diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index 5a266c290d..249271dc61 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -946,8 +946,7 @@ public final class ImaAdsLoader // Player.EventListener implementation. @Override - public void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) { + public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) { if (timeline.isEmpty()) { // The player is being reset or contains no media. return; diff --git a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/FakePlayer.java b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/FakePlayer.java index a9d6a37fac..a9572b7a8d 100644 --- a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/FakePlayer.java +++ b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/FakePlayer.java @@ -51,9 +51,7 @@ import java.util.ArrayList; public void updateTimeline(Timeline timeline) { for (Player.EventListener listener : listeners) { listener.onTimelineChanged( - timeline, - null, - prepared ? TIMELINE_CHANGE_REASON_DYNAMIC : TIMELINE_CHANGE_REASON_PREPARED); + timeline, prepared ? TIMELINE_CHANGE_REASON_DYNAMIC : TIMELINE_CHANGE_REASON_PREPARED); } prepared = true; } diff --git a/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java b/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java index 1fece6bc8e..370e5515e8 100644 --- a/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java +++ b/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java @@ -288,8 +288,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab } @Override - public void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) { + public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) { Callback callback = getCallback(); callback.onDurationChanged(LeanbackPlayerAdapter.this); callback.onCurrentPositionChanged(LeanbackPlayerAdapter.this); diff --git a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java index 3136e3cca9..be085ae30b 100644 --- a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java +++ b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java @@ -1020,8 +1020,7 @@ public final class MediaSessionConnector { // Player.EventListener implementation. @Override - public void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) { + public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) { Player player = Assertions.checkNotNull(MediaSessionConnector.this.player); int windowCount = player.getCurrentTimeline().getWindowCount(); int windowIndex = player.getCurrentWindowIndex(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/BasePlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/BasePlayer.java index 774f1b452c..bb14ac147b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/BasePlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/BasePlayer.java @@ -94,11 +94,19 @@ public abstract class BasePlayer implements Player { @Override @Nullable public final Object getCurrentTag() { - int windowIndex = getCurrentWindowIndex(); Timeline timeline = getCurrentTimeline(); - return windowIndex >= timeline.getWindowCount() + return timeline.isEmpty() ? null - : timeline.getWindow(windowIndex, window, /* setTag= */ true).tag; + : timeline.getWindow(getCurrentWindowIndex(), window, /* setTag= */ true).tag; + } + + @Override + @Nullable + public final Object getCurrentManifest() { + Timeline timeline = getCurrentTimeline(); + return timeline.isEmpty() + ? null + : timeline.getWindow(getCurrentWindowIndex(), window, /* setTag= */ false).manifest; } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index 945bd32d30..73107aa98e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -547,11 +547,6 @@ import java.util.concurrent.CopyOnWriteArrayList; return playbackInfo.timeline; } - @Override - public Object getCurrentManifest() { - return playbackInfo.manifest; - } - // Not private so it can be called from an inner class without going through a thunk method. /* package */ void handleEvent(Message msg) { switch (msg.what) { @@ -639,7 +634,6 @@ import java.util.concurrent.CopyOnWriteArrayList; long contentPositionUs = resetPosition ? C.TIME_UNSET : playbackInfo.contentPositionUs; return new PlaybackInfo( resetState ? Timeline.EMPTY : playbackInfo.timeline, - resetState ? null : playbackInfo.manifest, mediaPeriodId, startPositionUs, contentPositionUs, @@ -713,7 +707,7 @@ import java.util.concurrent.CopyOnWriteArrayList; private final @Player.TimelineChangeReason int timelineChangeReason; private final boolean seekProcessed; private final boolean playbackStateChanged; - private final boolean timelineOrManifestChanged; + private final boolean timelineChanged; private final boolean isLoadingChanged; private final boolean trackSelectorResultChanged; private final boolean playWhenReady; @@ -737,9 +731,7 @@ import java.util.concurrent.CopyOnWriteArrayList; this.seekProcessed = seekProcessed; this.playWhenReady = playWhenReady; playbackStateChanged = previousPlaybackInfo.playbackState != playbackInfo.playbackState; - timelineOrManifestChanged = - previousPlaybackInfo.timeline != playbackInfo.timeline - || previousPlaybackInfo.manifest != playbackInfo.manifest; + timelineChanged = previousPlaybackInfo.timeline != playbackInfo.timeline; isLoadingChanged = previousPlaybackInfo.isLoading != playbackInfo.isLoading; trackSelectorResultChanged = previousPlaybackInfo.trackSelectorResult != playbackInfo.trackSelectorResult; @@ -747,12 +739,10 @@ import java.util.concurrent.CopyOnWriteArrayList; @Override public void run() { - if (timelineOrManifestChanged || timelineChangeReason == TIMELINE_CHANGE_REASON_PREPARED) { + if (timelineChanged || timelineChangeReason == TIMELINE_CHANGE_REASON_PREPARED) { invokeAll( listenerSnapshot, - listener -> - listener.onTimelineChanged( - playbackInfo.timeline, playbackInfo.manifest, timelineChangeReason)); + listener -> listener.onTimelineChanged(playbackInfo.timeline, timelineChangeReason)); } if (positionDiscontinuity) { invokeAll( diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index a6d4352880..5f53427fca 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -267,9 +267,10 @@ import java.util.concurrent.atomic.AtomicBoolean; // MediaSource.SourceInfoRefreshListener implementation. @Override - public void onSourceInfoRefreshed(MediaSource source, Timeline timeline, Object manifest) { - handler.obtainMessage(MSG_REFRESH_SOURCE_INFO, - new MediaSourceRefreshInfo(source, timeline, manifest)).sendToTarget(); + public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) { + handler + .obtainMessage(MSG_REFRESH_SOURCE_INFO, new MediaSourceRefreshInfo(source, timeline)) + .sendToTarget(); } // MediaPeriod.Callback implementation. @@ -899,7 +900,6 @@ import java.util.concurrent.atomic.AtomicBoolean; playbackInfo = new PlaybackInfo( resetState ? Timeline.EMPTY : playbackInfo.timeline, - resetState ? null : playbackInfo.manifest, mediaPeriodId, startPositionUs, contentPositionUs, @@ -1276,9 +1276,8 @@ import java.util.concurrent.atomic.AtomicBoolean; Timeline oldTimeline = playbackInfo.timeline; Timeline timeline = sourceRefreshInfo.timeline; - Object manifest = sourceRefreshInfo.manifest; queue.setTimeline(timeline); - playbackInfo = playbackInfo.copyWithTimeline(timeline, manifest); + playbackInfo = playbackInfo.copyWithTimeline(timeline); resolvePendingMessagePositions(); MediaPeriodId newPeriodId = playbackInfo.periodId; @@ -1881,12 +1880,10 @@ import java.util.concurrent.atomic.AtomicBoolean; public final MediaSource source; public final Timeline timeline; - public final Object manifest; - public MediaSourceRefreshInfo(MediaSource source, Timeline timeline, Object manifest) { + public MediaSourceRefreshInfo(MediaSource source, Timeline timeline) { this.source = source; this.timeline = timeline; - this.manifest = manifest; } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/PlaybackInfo.java b/library/core/src/main/java/com/google/android/exoplayer2/PlaybackInfo.java index d3e4a0e626..1eedae08b6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/PlaybackInfo.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/PlaybackInfo.java @@ -16,7 +16,6 @@ package com.google.android.exoplayer2; import androidx.annotation.CheckResult; -import androidx.annotation.Nullable; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.trackselection.TrackSelectorResult; @@ -35,8 +34,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; /** The current {@link Timeline}. */ public final Timeline timeline; - /** The current manifest. */ - @Nullable public final Object manifest; /** The {@link MediaPeriodId} of the currently playing media period in the {@link #timeline}. */ public final MediaPeriodId periodId; /** @@ -91,7 +88,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; long startPositionUs, TrackSelectorResult emptyTrackSelectorResult) { return new PlaybackInfo( Timeline.EMPTY, - /* manifest= */ null, DUMMY_MEDIA_PERIOD_ID, startPositionUs, /* contentPositionUs= */ C.TIME_UNSET, @@ -109,7 +105,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; * Create playback info. * * @param timeline See {@link #timeline}. - * @param manifest See {@link #manifest}. * @param periodId See {@link #periodId}. * @param startPositionUs See {@link #startPositionUs}. * @param contentPositionUs See {@link #contentPositionUs}. @@ -124,7 +119,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; */ public PlaybackInfo( Timeline timeline, - @Nullable Object manifest, MediaPeriodId periodId, long startPositionUs, long contentPositionUs, @@ -137,7 +131,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; long totalBufferedDurationUs, long positionUs) { this.timeline = timeline; - this.manifest = manifest; this.periodId = periodId; this.startPositionUs = startPositionUs; this.contentPositionUs = contentPositionUs; @@ -187,7 +180,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; long totalBufferedDurationUs) { return new PlaybackInfo( timeline, - manifest, periodId, positionUs, periodId.isAd() ? contentPositionUs : C.TIME_UNSET, @@ -202,17 +194,15 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; } /** - * Copies playback info with new timeline and manifest. + * Copies playback info with the new timeline. * * @param timeline New timeline. See {@link #timeline}. - * @param manifest New manifest. See {@link #manifest}. - * @return Copied playback info with new timeline and manifest. + * @return Copied playback info with the new timeline. */ @CheckResult - public PlaybackInfo copyWithTimeline(Timeline timeline, Object manifest) { + public PlaybackInfo copyWithTimeline(Timeline timeline) { return new PlaybackInfo( timeline, - manifest, periodId, startPositionUs, contentPositionUs, @@ -236,7 +226,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; public PlaybackInfo copyWithPlaybackState(int playbackState) { return new PlaybackInfo( timeline, - manifest, periodId, startPositionUs, contentPositionUs, @@ -260,7 +249,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; public PlaybackInfo copyWithIsLoading(boolean isLoading) { return new PlaybackInfo( timeline, - manifest, periodId, startPositionUs, contentPositionUs, @@ -286,7 +274,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; TrackGroupArray trackGroups, TrackSelectorResult trackSelectorResult) { return new PlaybackInfo( timeline, - manifest, periodId, startPositionUs, contentPositionUs, @@ -310,7 +297,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; public PlaybackInfo copyWithLoadingMediaPeriodId(MediaPeriodId loadingMediaPeriodId) { return new PlaybackInfo( timeline, - manifest, periodId, startPositionUs, contentPositionUs, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Player.java b/library/core/src/main/java/com/google/android/exoplayer2/Player.java index 0e19212afa..68a386d2de 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Player.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Player.java @@ -324,6 +324,29 @@ public interface Player { */ interface EventListener { + /** + * Called when the timeline has been refreshed. + * + *

Note that if the timeline has changed then a position discontinuity may also have + * occurred. For example, the current period index may have changed as a result of periods being + * added or removed from the timeline. This will not be reported via a separate call to + * {@link #onPositionDiscontinuity(int)}. + * + * @param timeline The latest timeline. Never null, but may be empty. + * @param reason The {@link TimelineChangeReason} responsible for this timeline change. + */ + @SuppressWarnings("deprecation") + default void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) { + Object manifest = null; + if (timeline.getWindowCount() == 1) { + // Legacy behavior was to report the manifest for single window timelines only. + Timeline.Window window = new Timeline.Window(); + manifest = timeline.getWindow(0, window).manifest; + } + // Call deprecated version. + onTimelineChanged(timeline, manifest, reason); + } + /** * Called when the timeline and/or manifest has been refreshed. * @@ -335,7 +358,11 @@ public interface Player { * @param timeline The latest timeline. Never null, but may be empty. * @param manifest The latest manifest. May be null. * @param reason The {@link TimelineChangeReason} responsible for this timeline change. + * @deprecated Use {@link #onTimelineChanged(Timeline, int)} instead. The manifest can be + * accessed by using {@link #getCurrentManifest()} or {@code timeline.getWindow(windowIndex, + * window).manifest} for a given window index. */ + @Deprecated default void onTimelineChanged( Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) {} @@ -396,8 +423,7 @@ public interface Player { * when the source introduces a discontinuity internally). * *

When a position discontinuity occurs as a result of a change to the timeline this method - * is not called. {@link #onTimelineChanged(Timeline, Object, int)} is called in this - * case. + * is not called. {@link #onTimelineChanged(Timeline, int)} is called in this case. * * @param reason The {@link DiscontinuityReason} responsible for the discontinuity. */ @@ -428,6 +454,19 @@ public interface Player { @Deprecated abstract class DefaultEventListener implements EventListener { + @Override + @SuppressWarnings("deprecation") + public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) { + Object manifest = null; + if (timeline.getWindowCount() == 1) { + // Legacy behavior was to report the manifest for single window timelines only. + Timeline.Window window = new Timeline.Window(); + manifest = timeline.getWindow(0, window).manifest; + } + // Call deprecated version. + onTimelineChanged(timeline, manifest, reason); + } + @Override @SuppressWarnings("deprecation") public void onTimelineChanged( @@ -436,7 +475,7 @@ public interface Player { onTimelineChanged(timeline, manifest); } - /** @deprecated Use {@link EventListener#onTimelineChanged(Timeline, Object, int)} instead. */ + /** @deprecated Use {@link EventListener#onTimelineChanged(Timeline, int)} instead. */ @Deprecated public void onTimelineChanged(Timeline timeline, @Nullable Object manifest) { // Do nothing. 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 b427991d6e..a782255cb8 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 @@ -1070,13 +1070,6 @@ public class SimpleExoPlayer extends BasePlayer return player.getCurrentTimeline(); } - @Override - @Nullable - public Object getCurrentManifest() { - verifyApplicationThread(); - return player.getCurrentManifest(); - } - @Override public int getCurrentPeriodIndex() { verifyApplicationThread(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java b/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java index 0c64810d58..32fa3a6e4b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java @@ -122,6 +122,9 @@ public abstract class Timeline { /** A tag for the window. Not necessarily unique. */ @Nullable public Object tag; + /** The manifest of the window. May be {@code null}. */ + @Nullable public Object manifest; + /** * The start time of the presentation to which this window belongs in milliseconds since the * epoch, or {@link C#TIME_UNSET} if unknown or not applicable. For informational purposes only. @@ -179,6 +182,7 @@ public abstract class Timeline { /** Sets the data held by this window. */ public Window set( @Nullable Object tag, + @Nullable Object manifest, long presentationStartTimeMs, long windowStartTimeMs, boolean isSeekable, @@ -189,6 +193,7 @@ public abstract class Timeline { int lastPeriodIndex, long positionInFirstPeriodUs) { this.tag = tag; + this.manifest = manifest; this.presentationStartTimeMs = presentationStartTimeMs; this.windowStartTimeMs = windowStartTimeMs; this.isSeekable = isSeekable; 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 deecfb15a8..de0f177342 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 @@ -437,8 +437,7 @@ public class AnalyticsCollector // having slightly different real times. @Override - public final void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) { + public final void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) { mediaPeriodQueueTracker.onTimelineChanged(timeline); EventTime eventTime = generatePlayingMediaPeriodEventTime(); for (AnalyticsListener listener : listeners) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadHelper.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadHelper.java index 4858eec6b7..17bc304db3 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadHelper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadHelper.java @@ -335,6 +335,7 @@ public final class DownloadHelper { private final RendererCapabilities[] rendererCapabilities; private final SparseIntArray scratchSet; private final Handler callbackHandler; + private final Timeline.Window window; private boolean isPreparedWithMedia; private @MonotonicNonNull Callback callback; @@ -374,6 +375,7 @@ public final class DownloadHelper { trackSelector.setParameters(trackSelectorParameters); trackSelector.init(/* listener= */ () -> {}, new DummyBandwidthMeter()); callbackHandler = new Handler(Util.getLooper()); + window = new Timeline.Window(); } /** @@ -409,7 +411,9 @@ public final class DownloadHelper { return null; } assertPreparedWithMedia(); - return mediaPreparer.manifest; + return mediaPreparer.timeline.getWindowCount() > 0 + ? mediaPreparer.timeline.getWindow(/* windowIndex= */ 0, window).manifest + : null; } /** @@ -814,7 +818,6 @@ public final class DownloadHelper { private final HandlerThread mediaSourceThread; private final Handler mediaSourceHandler; - @Nullable public Object manifest; public @MonotonicNonNull Timeline timeline; public MediaPeriod @MonotonicNonNull [] mediaPeriods; @@ -892,14 +895,12 @@ public final class DownloadHelper { // MediaSource.SourceInfoRefreshListener implementation. @Override - public void onSourceInfoRefreshed( - MediaSource source, Timeline timeline, @Nullable Object manifest) { + public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) { if (this.timeline != null) { // Ignore dynamic updates. return; } this.timeline = timeline; - this.manifest = manifest; mediaPeriods = new MediaPeriod[timeline.getPeriodCount()]; for (int i = 0; i < mediaPeriods.length; i++) { MediaPeriod mediaPeriod = diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java index f6ea3da089..124f70c64c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java @@ -27,8 +27,8 @@ import java.util.ArrayList; * Base {@link MediaSource} implementation to handle parallel reuse and to keep a list of {@link * MediaSourceEventListener}s. * - *

Whenever an implementing subclass needs to provide a new timeline and/or manifest, it must - * call {@link #refreshSourceInfo(Timeline, Object)} to notify all listeners. + *

Whenever an implementing subclass needs to provide a new timeline, it must call {@link + * #refreshSourceInfo(Timeline)} to notify all listeners. */ public abstract class BaseMediaSource implements MediaSource { @@ -37,7 +37,6 @@ public abstract class BaseMediaSource implements MediaSource { @Nullable private Looper looper; @Nullable private Timeline timeline; - @Nullable private Object manifest; public BaseMediaSource() { sourceInfoListeners = new ArrayList<>(/* initialCapacity= */ 1); @@ -65,13 +64,11 @@ public abstract class BaseMediaSource implements MediaSource { * Updates timeline and manifest and notifies all listeners of the update. * * @param timeline The new {@link Timeline}. - * @param manifest The new manifest. May be null. */ - protected final void refreshSourceInfo(Timeline timeline, @Nullable Object manifest) { + protected final void refreshSourceInfo(Timeline timeline) { this.timeline = timeline; - this.manifest = manifest; for (SourceInfoRefreshListener listener : sourceInfoListeners) { - listener.onSourceInfoRefreshed(/* source= */ this, timeline, manifest); + listener.onSourceInfoRefreshed(/* source= */ this, timeline); } } @@ -139,7 +136,7 @@ public abstract class BaseMediaSource implements MediaSource { this.looper = looper; prepareSourceInternal(mediaTransferListener); } else if (timeline != null) { - listener.onSourceInfoRefreshed(/* source= */ this, timeline, manifest); + listener.onSourceInfoRefreshed(/* source= */ this, timeline); } } @@ -149,7 +146,6 @@ public abstract class BaseMediaSource implements MediaSource { if (sourceInfoListeners.isEmpty()) { looper = null; timeline = null; - manifest = null; releaseSourceInternal(); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java index c942f9320e..81169354de 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java @@ -87,7 +87,6 @@ public final class ClippingMediaSource extends CompositeMediaSource { private final ArrayList mediaPeriods; private final Timeline.Window window; - @Nullable private Object manifest; @Nullable private ClippingTimeline clippingTimeline; @Nullable private IllegalClippingException clippingError; private long periodStartUs; @@ -235,12 +234,10 @@ public final class ClippingMediaSource extends CompositeMediaSource { } @Override - protected void onChildSourceInfoRefreshed( - Void id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest) { + protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) { if (clippingError != null) { return; } - this.manifest = manifest; refreshClippedTimeline(timeline); } @@ -280,7 +277,7 @@ public final class ClippingMediaSource extends CompositeMediaSource { clippingError = e; return; } - refreshSourceInfo(clippingTimeline, manifest); + refreshSourceInfo(clippingTimeline); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java index 1a9e1ff250..612ad33f9d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java @@ -73,17 +73,15 @@ public abstract class CompositeMediaSource extends BaseMediaSource { * @param id The unique id used to prepare the child source. * @param mediaSource The child source whose source info has been refreshed. * @param timeline The timeline of the child source. - * @param manifest The manifest of the child source. */ protected abstract void onChildSourceInfoRefreshed( - T id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest); + T id, MediaSource mediaSource, Timeline timeline); /** * Prepares a child source. * - *

{@link #onChildSourceInfoRefreshed(Object, MediaSource, Timeline, Object)} will be called - * when the child source updates its timeline and/or manifest with the same {@code id} passed to - * this method. + *

{@link #onChildSourceInfoRefreshed(Object, MediaSource, Timeline)} will be called when the + * child source updates its timeline with the same {@code id} passed to this method. * *

Any child sources that aren't explicitly released with {@link #releaseChildSource(Object)} * will be released in {@link #releaseSourceInternal()}. @@ -94,7 +92,12 @@ public abstract class CompositeMediaSource extends BaseMediaSource { protected final void prepareChildSource(final T id, MediaSource mediaSource) { Assertions.checkArgument(!childSources.containsKey(id)); SourceInfoRefreshListener sourceListener = - (source, timeline, manifest) -> onChildSourceInfoRefreshed(id, source, timeline, manifest); + new SourceInfoRefreshListener() { + @Override + public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) { + onChildSourceInfoRefreshed(id, source, timeline); + } + }; MediaSourceEventListener eventListener = new ForwardingEventListener(id); childSources.put(id, new MediaSourceAndListener(mediaSource, sourceListener, eventListener)); mediaSource.addEventListener(Assertions.checkNotNull(eventHandler), eventListener); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java index c72bed1b5b..18d5c49fb4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java @@ -474,10 +474,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource onCompletionActions = nextTimelineUpdateOnCompletionActions; nextTimelineUpdateOnCompletionActions = new HashSet<>(); - refreshSourceInfo( - new ConcatenatedTimeline(mediaSourceHolders, shuffleOrder, isAtomic), /* manifest= */ null); + refreshSourceInfo(new ConcatenatedTimeline(mediaSourceHolders, shuffleOrder, isAtomic)); getPlaybackThreadHandlerOnPlaybackThread() .obtainMessage(MSG_ON_COMPLETION, onCompletionActions) .sendToTarget(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java index f07ee63e79..2bcaad4fce 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java @@ -364,9 +364,8 @@ public final class ExtractorMediaSource extends BaseMediaSource } @Override - public void onSourceInfoRefreshed( - MediaSource source, Timeline timeline, @Nullable Object manifest) { - refreshSourceInfo(timeline, manifest); + public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) { + refreshSourceInfo(timeline); } @Deprecated diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/LoopingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/LoopingMediaSource.java index 7adb18dc94..ac23e2a831 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/LoopingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/LoopingMediaSource.java @@ -100,13 +100,12 @@ public final class LoopingMediaSource extends CompositeMediaSource { } @Override - protected void onChildSourceInfoRefreshed( - Void id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest) { + protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) { Timeline loopingTimeline = loopCount != Integer.MAX_VALUE ? new LoopingTimeline(timeline, loopCount) : new InfinitelyLoopingTimeline(timeline); - refreshSourceInfo(loopingTimeline, manifest); + refreshSourceInfo(loopingTimeline); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaSource.java index ad9ef194da..1fca824910 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaSource.java @@ -119,7 +119,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { @Override protected void onChildSourceInfoRefreshed( - Void id, MediaSource mediaSource, Timeline newTimeline, @Nullable Object manifest) { + Void id, MediaSource mediaSource, Timeline newTimeline) { if (isPrepared) { timeline = timeline.cloneWithUpdatedTimeline(newTimeline); } else if (newTimeline.isEmpty()) { @@ -162,7 +162,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { } } isPrepared = true; - refreshSourceInfo(this.timeline, manifest); + refreshSourceInfo(this.timeline); } @Nullable @@ -274,6 +274,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { int windowIndex, Window window, boolean setTag, long defaultPositionProjectionUs) { return window.set( tag, + /* manifest= */ null, /* presentationStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET, /* isSeekable= */ false, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java index b40bbb35d1..f86be8afc2 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java @@ -58,8 +58,8 @@ public interface MediaPeriod extends SequenceableLoader { * *

If preparation succeeds and results in a source timeline change (e.g. the period duration * becoming known), {@link - * MediaSource.SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline, Object)} - * will be called before {@code callback.onPrepared}. + * MediaSource.SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline)} will be + * called before {@code callback.onPrepared}. * * @param callback Callback to receive updates from this period, including being notified when * preparation completes. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java index 82359ffccd..10e29f3f44 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java @@ -49,16 +49,16 @@ public interface MediaSource { interface SourceInfoRefreshListener { /** - * Called when manifest and/or timeline has been refreshed. - *

- * Called on the playback thread. + * Called when the timeline has been refreshed. + * + *

Called on the playback thread. * * @param source The {@link MediaSource} whose info has been refreshed. * @param timeline The source's timeline. - * @param manifest The loaded manifest. May be null. */ - void onSourceInfoRefreshed(MediaSource source, Timeline timeline, @Nullable Object manifest); - + default void onSourceInfoRefreshed(MediaSource source, Timeline timeline) { + // Do nothing. + } } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java index f12ce92f54..dd7675f3d4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java @@ -71,7 +71,6 @@ public final class MergingMediaSource extends CompositeMediaSource { private final ArrayList pendingTimelineSources; private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; - @Nullable private Object primaryManifest; private int periodCount; @Nullable private IllegalMergeException mergeError; @@ -143,7 +142,6 @@ public final class MergingMediaSource extends CompositeMediaSource { protected void releaseSourceInternal() { super.releaseSourceInternal(); Arrays.fill(timelines, null); - primaryManifest = null; periodCount = PERIOD_COUNT_UNSET; mergeError = null; pendingTimelineSources.clear(); @@ -152,7 +150,7 @@ public final class MergingMediaSource extends CompositeMediaSource { @Override protected void onChildSourceInfoRefreshed( - Integer id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest) { + Integer id, MediaSource mediaSource, Timeline timeline) { if (mergeError == null) { mergeError = checkTimelineMerges(timeline); } @@ -161,11 +159,8 @@ public final class MergingMediaSource extends CompositeMediaSource { } pendingTimelineSources.remove(mediaSource); timelines[id] = timeline; - if (mediaSource == mediaSources[0]) { - primaryManifest = manifest; - } if (pendingTimelineSources.isEmpty()) { - refreshSourceInfo(timelines[0], primaryManifest); + refreshSourceInfo(timelines[0]); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaSource.java index ba69b46d7f..42ec237b3e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaSource.java @@ -287,7 +287,10 @@ public final class ProgressiveMediaSource extends BaseMediaSource // TODO: Make timeline dynamic until its duration is known. This is non-trivial. See b/69703223. refreshSourceInfo( new SinglePeriodTimeline( - timelineDurationUs, timelineIsSeekable, /* isDynamic= */ false, tag), - /* manifest= */ null); + timelineDurationUs, + timelineIsSeekable, + /* isDynamic= */ false, + /* manifest= */ null, + tag)); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java index fc99e8cb7b..a5b78ef3f7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java @@ -68,8 +68,7 @@ public final class SilenceMediaSource extends BaseMediaSource { @Override protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { refreshSourceInfo( - new SinglePeriodTimeline(durationUs, /* isSeekable= */ true, /* isDynamic= */ false), - /* manifest= */ null); + new SinglePeriodTimeline(durationUs, /* isSeekable= */ true, /* isDynamic= */ false)); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SinglePeriodTimeline.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SinglePeriodTimeline.java index 14648775f8..8790b09f07 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SinglePeriodTimeline.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SinglePeriodTimeline.java @@ -36,6 +36,7 @@ public final class SinglePeriodTimeline extends Timeline { private final boolean isSeekable; private final boolean isDynamic; @Nullable private final Object tag; + @Nullable private final Object manifest; /** * Creates a timeline containing a single period and a window that spans it. @@ -45,7 +46,7 @@ public final class SinglePeriodTimeline extends Timeline { * @param isDynamic Whether the window may change when the timeline is updated. */ public SinglePeriodTimeline(long durationUs, boolean isSeekable, boolean isDynamic) { - this(durationUs, isSeekable, isDynamic, /* tag= */ null); + this(durationUs, isSeekable, isDynamic, /* manifest= */ null, /* tag= */ null); } /** @@ -54,10 +55,15 @@ public final class SinglePeriodTimeline extends Timeline { * @param durationUs The duration of the period, in microseconds. * @param isSeekable Whether seeking is supported within the period. * @param isDynamic Whether the window may change when the timeline is updated. - * @param tag A tag used for {@link Timeline.Window#tag}. + * @param manifest The manifest. May be {@code null}. + * @param tag A tag used for {@link Window#tag}. */ public SinglePeriodTimeline( - long durationUs, boolean isSeekable, boolean isDynamic, @Nullable Object tag) { + long durationUs, + boolean isSeekable, + boolean isDynamic, + @Nullable Object manifest, + @Nullable Object tag) { this( durationUs, durationUs, @@ -65,6 +71,7 @@ public final class SinglePeriodTimeline extends Timeline { /* windowDefaultStartPositionUs= */ 0, isSeekable, isDynamic, + manifest, tag); } @@ -80,6 +87,7 @@ public final class SinglePeriodTimeline extends Timeline { * which to begin playback, in microseconds. * @param isSeekable Whether seeking is supported within the window. * @param isDynamic Whether the window may change when the timeline is updated. + * @param manifest The manifest. May be (@code null}. * @param tag A tag used for {@link Timeline.Window#tag}. */ public SinglePeriodTimeline( @@ -89,6 +97,7 @@ public final class SinglePeriodTimeline extends Timeline { long windowDefaultStartPositionUs, boolean isSeekable, boolean isDynamic, + @Nullable Object manifest, @Nullable Object tag) { this( /* presentationStartTimeMs= */ C.TIME_UNSET, @@ -99,6 +108,7 @@ public final class SinglePeriodTimeline extends Timeline { windowDefaultStartPositionUs, isSeekable, isDynamic, + manifest, tag); } @@ -117,6 +127,7 @@ public final class SinglePeriodTimeline extends Timeline { * which to begin playback, in microseconds. * @param isSeekable Whether seeking is supported within the window. * @param isDynamic Whether the window may change when the timeline is updated. + * @param manifest The manifest. May be {@code null}. * @param tag A tag used for {@link Timeline.Window#tag}. */ public SinglePeriodTimeline( @@ -128,6 +139,7 @@ public final class SinglePeriodTimeline extends Timeline { long windowDefaultStartPositionUs, boolean isSeekable, boolean isDynamic, + @Nullable Object manifest, @Nullable Object tag) { this.presentationStartTimeMs = presentationStartTimeMs; this.windowStartTimeMs = windowStartTimeMs; @@ -137,6 +149,7 @@ public final class SinglePeriodTimeline extends Timeline { this.windowDefaultStartPositionUs = windowDefaultStartPositionUs; this.isSeekable = isSeekable; this.isDynamic = isDynamic; + this.manifest = manifest; this.tag = tag; } @@ -165,6 +178,7 @@ public final class SinglePeriodTimeline extends Timeline { } return window.set( tag, + manifest, presentationStartTimeMs, windowStartTimeMs, isSeekable, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java index 6c1881a01a..04ee3a153c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java @@ -290,7 +290,8 @@ public final class SingleSampleMediaSource extends BaseMediaSource { this.tag = tag; dataSpec = new DataSpec(uri, DataSpec.FLAG_ALLOW_GZIP); timeline = - new SinglePeriodTimeline(durationUs, /* isSeekable= */ true, /* isDynamic= */ false, tag); + new SinglePeriodTimeline( + durationUs, /* isSeekable= */ true, /* isDynamic= */ false, /* manifest= */ null, tag); } // MediaSource implementation. @@ -304,7 +305,7 @@ public final class SingleSampleMediaSource extends BaseMediaSource { @Override protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { transferListener = mediaTransferListener; - refreshSourceInfo(timeline, /* manifest= */ null); + refreshSourceInfo(timeline); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java index a6c2cf2767..5e22de4320 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java @@ -134,7 +134,6 @@ public final class AdsMediaSource extends CompositeMediaSource { // Accessed on the player thread. @Nullable private ComponentListener componentListener; @Nullable private Timeline contentTimeline; - @Nullable private Object contentManifest; @Nullable private AdPlaybackState adPlaybackState; private @NullableType MediaSource[][] adGroupMediaSources; private @NullableType Timeline[][] adGroupTimelines; @@ -265,7 +264,6 @@ public final class AdsMediaSource extends CompositeMediaSource { componentListener = null; maskingMediaPeriodByAdMediaSource.clear(); contentTimeline = null; - contentManifest = null; adPlaybackState = null; adGroupMediaSources = new MediaSource[0][]; adGroupTimelines = new Timeline[0][]; @@ -274,16 +272,13 @@ public final class AdsMediaSource extends CompositeMediaSource { @Override protected void onChildSourceInfoRefreshed( - MediaPeriodId mediaPeriodId, - MediaSource mediaSource, - Timeline timeline, - @Nullable Object manifest) { + MediaPeriodId mediaPeriodId, MediaSource mediaSource, Timeline timeline) { if (mediaPeriodId.isAd()) { int adGroupIndex = mediaPeriodId.adGroupIndex; int adIndexInAdGroup = mediaPeriodId.adIndexInAdGroup; onAdSourceInfoRefreshed(mediaSource, adGroupIndex, adIndexInAdGroup, timeline); } else { - onContentSourceInfoRefreshed(timeline, manifest); + onContentSourceInfoRefreshed(timeline); } } @@ -308,10 +303,9 @@ public final class AdsMediaSource extends CompositeMediaSource { maybeUpdateSourceInfo(); } - private void onContentSourceInfoRefreshed(Timeline timeline, @Nullable Object manifest) { + private void onContentSourceInfoRefreshed(Timeline timeline) { Assertions.checkArgument(timeline.getPeriodCount() == 1); contentTimeline = timeline; - contentManifest = manifest; maybeUpdateSourceInfo(); } @@ -340,7 +334,7 @@ public final class AdsMediaSource extends CompositeMediaSource { adPlaybackState.adGroupCount == 0 ? contentTimeline : new SinglePeriodAdTimeline(contentTimeline, adPlaybackState); - refreshSourceInfo(timeline, contentManifest); + refreshSourceInfo(timeline); } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index 639e80348b..61b8418411 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -113,8 +113,8 @@ public final class ExoPlayerTest { /** Tests playback of a source that exposes a single period. */ @Test public void testPlaySinglePeriodTimeline() throws Exception { - Timeline timeline = new FakeTimeline(/* windowCount= */ 1); Object manifest = new Object(); + Timeline timeline = new FakeTimeline(/* windowCount= */ 1, manifest); FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT); ExoPlayerTestRunner testRunner = new Builder() @@ -126,7 +126,6 @@ public final class ExoPlayerTest { .blockUntilEnded(TIMEOUT_MS); testRunner.assertNoPositionDiscontinuities(); testRunner.assertTimelinesEqual(timeline); - testRunner.assertManifestsEqual(manifest); testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED); testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT))); assertThat(renderer.formatReadCount).isEqualTo(1); @@ -256,15 +255,16 @@ public final class ExoPlayerTest { @Test public void testRepreparationGivesFreshSourceInfo() throws Exception { - Timeline timeline = new FakeTimeline(/* windowCount= */ 1); FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT); Object firstSourceManifest = new Object(); - MediaSource firstSource = - new FakeMediaSource(timeline, firstSourceManifest, Builder.VIDEO_FORMAT); + Timeline firstTimeline = new FakeTimeline(/* windowCount= */ 1, firstSourceManifest); + MediaSource firstSource = new FakeMediaSource(firstTimeline, Builder.VIDEO_FORMAT); final CountDownLatch queuedSourceInfoCountDownLatch = new CountDownLatch(1); final CountDownLatch completePreparationCountDownLatch = new CountDownLatch(1); + + Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 1); MediaSource secondSource = - new FakeMediaSource(timeline, new Object(), Builder.VIDEO_FORMAT) { + new FakeMediaSource(secondTimeline, Builder.VIDEO_FORMAT) { @Override public synchronized void prepareSourceInternal( @Nullable TransferListener mediaTransferListener) { @@ -281,8 +281,8 @@ public final class ExoPlayerTest { } }; Object thirdSourceManifest = new Object(); - MediaSource thirdSource = - new FakeMediaSource(timeline, thirdSourceManifest, Builder.VIDEO_FORMAT); + Timeline thirdTimeline = new FakeTimeline(/* windowCount= */ 1, thirdSourceManifest); + MediaSource thirdSource = new FakeMediaSource(thirdTimeline, Builder.VIDEO_FORMAT); // Prepare the player with a source with the first manifest and a non-empty timeline. Prepare // the player again with a source and a new manifest, which will never be exposed. Allow the @@ -290,7 +290,7 @@ public final class ExoPlayerTest { // the test thread's call to prepare() has returned. ActionSchedule actionSchedule = new ActionSchedule.Builder("testRepreparation") - .waitForTimelineChanged(timeline) + .waitForTimelineChanged(firstTimeline) .prepareSource(secondSource) .executeRunnable( () -> { @@ -315,8 +315,7 @@ public final class ExoPlayerTest { // The first source's preparation completed with a non-empty timeline. When the player was // re-prepared with the second source, it immediately exposed an empty timeline, but the source // info refresh from the second source was suppressed as we re-prepared with the third source. - testRunner.assertTimelinesEqual(timeline, Timeline.EMPTY, timeline); - testRunner.assertManifestsEqual(firstSourceManifest, null, thirdSourceManifest); + testRunner.assertTimelinesEqual(firstTimeline, Timeline.EMPTY, thirdTimeline); testRunner.assertTimelineChangeReasonsEqual( Player.TIMELINE_CHANGE_REASON_PREPARED, Player.TIMELINE_CHANGE_REASON_RESET, @@ -376,9 +375,9 @@ public final class ExoPlayerTest { public void testShuffleModeEnabledChanges() throws Exception { Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1); MediaSource[] fakeMediaSources = { - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT) + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT) }; ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources); @@ -437,8 +436,7 @@ public final class ExoPlayerTest { /* isDynamic= */ false, /* durationUs= */ C.MICROS_PER_SECOND, errorAdPlaybackState)); - final FakeMediaSource fakeMediaSource = - new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT); + final FakeMediaSource fakeMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testAdGroupWithLoadErrorIsSkipped") .pause() @@ -585,7 +583,7 @@ public final class ExoPlayerTest { public void testSeekDiscontinuityWithAdjustment() throws Exception { FakeTimeline timeline = new FakeTimeline(1); FakeMediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -620,7 +618,7 @@ public final class ExoPlayerTest { public void testInternalDiscontinuityAtNewPosition() throws Exception { FakeTimeline timeline = new FakeTimeline(1); FakeMediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -646,7 +644,7 @@ public final class ExoPlayerTest { public void testInternalDiscontinuityAtInitialPosition() throws Exception { FakeTimeline timeline = new FakeTimeline(1); FakeMediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -673,7 +671,7 @@ public final class ExoPlayerTest { public void testAllActivatedTrackSelectionAreReleasedForSinglePeriod() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT); FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT); FakeTrackSelector trackSelector = new FakeTrackSelector(); @@ -702,7 +700,7 @@ public final class ExoPlayerTest { public void testAllActivatedTrackSelectionAreReleasedForMultiPeriods() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 2); MediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT); FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT); FakeTrackSelector trackSelector = new FakeTrackSelector(); @@ -732,7 +730,7 @@ public final class ExoPlayerTest { throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT); FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT); final FakeTrackSelector trackSelector = new FakeTrackSelector(); @@ -771,7 +769,7 @@ public final class ExoPlayerTest { throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = - new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT); FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT); final FakeTrackSelector trackSelector = new FakeTrackSelector(/* reuse track selection */ true); @@ -810,7 +808,7 @@ public final class ExoPlayerTest { public void testDynamicTimelineChangeReason() throws Exception { Timeline timeline1 = new FakeTimeline(new TimelineWindowDefinition(false, false, 100000)); final Timeline timeline2 = new FakeTimeline(new TimelineWindowDefinition(false, false, 20000)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, null, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testDynamicTimelineChangeReason") .pause() @@ -841,14 +839,14 @@ public final class ExoPlayerTest { new ConcatenatingMediaSource( /* isAtomic= */ false, new FakeShuffleOrder(/* length= */ 2), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); ConcatenatingMediaSource secondMediaSource = new ConcatenatingMediaSource( /* isAtomic= */ false, new FakeShuffleOrder(/* length= */ 2), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); ActionSchedule actionSchedule = new ActionSchedule.Builder("testRepreparationWithShuffle") // Wait for first preparation and enable shuffling. Plays period 0. @@ -877,7 +875,7 @@ public final class ExoPlayerTest { final CountDownLatch createPeriodCalledCountDownLatch = new CountDownLatch(1); final FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1]; MediaSource mediaSource = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -1017,8 +1015,7 @@ public final class ExoPlayerTest { @Test public void testStopWithoutResetReleasesMediaSource() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - final FakeMediaSource mediaSource = - new FakeMediaSource(timeline, /* manifest= */ null, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testStopReleasesMediaSource") .waitForPlaybackState(Player.STATE_READY) @@ -1038,8 +1035,7 @@ public final class ExoPlayerTest { @Test public void testStopWithResetReleasesMediaSource() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - final FakeMediaSource mediaSource = - new FakeMediaSource(timeline, /* manifest= */ null, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testStopReleasesMediaSource") .waitForPlaybackState(Player.STATE_READY) @@ -1059,7 +1055,7 @@ public final class ExoPlayerTest { @Test public void testRepreparationDoesNotResetAfterStopWithReset() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - MediaSource secondSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT); + MediaSource secondSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testRepreparationAfterStop") .waitForPlaybackState(Player.STATE_READY) @@ -1087,7 +1083,7 @@ public final class ExoPlayerTest { public void testSeekBeforeRepreparationPossibleAfterStopWithReset() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 2); - MediaSource secondSource = new FakeMediaSource(secondTimeline, null, Builder.VIDEO_FORMAT); + MediaSource secondSource = new FakeMediaSource(secondTimeline, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testSeekAfterStopWithReset") .waitForPlaybackState(Player.STATE_READY) @@ -1122,7 +1118,7 @@ public final class ExoPlayerTest { Timeline secondTimeline = new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ new Object())); - MediaSource secondSource = new FakeMediaSource(secondTimeline, /* manifest= */ null); + MediaSource secondSource = new FakeMediaSource(secondTimeline); AtomicLong positionAfterReprepare = new AtomicLong(); ActionSchedule actionSchedule = new ActionSchedule.Builder("testReprepareAndKeepPositionWithNewMediaSource") @@ -1211,9 +1207,7 @@ public final class ExoPlayerTest { .throwPlaybackException(ExoPlaybackException.createForSource(new IOException())) .waitForPlaybackState(Player.STATE_IDLE) .prepareSource( - new FakeMediaSource(timeline, /* manifest= */ null), - /* resetPosition= */ true, - /* resetState= */ false) + new FakeMediaSource(timeline), /* resetPosition= */ true, /* resetState= */ false) .waitForPlaybackState(Player.STATE_READY) .build(); ExoPlayerTestRunner testRunner = @@ -1252,9 +1246,7 @@ public final class ExoPlayerTest { } }) .prepareSource( - new FakeMediaSource(timeline, /* manifest= */ null), - /* resetPosition= */ false, - /* resetState= */ false) + new FakeMediaSource(timeline), /* resetPosition= */ false, /* resetState= */ false) .waitForPlaybackState(Player.STATE_READY) .executeRunnable( new PlayerRunnable() { @@ -1287,8 +1279,7 @@ public final class ExoPlayerTest { @Test public void testInvalidSeekPositionAfterSourceInfoRefreshStillUpdatesTimeline() throws Exception { final Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - final FakeMediaSource mediaSource = - new FakeMediaSource(/* timeline= */ null, /* manifest= */ null); + final FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null); ActionSchedule actionSchedule = new ActionSchedule.Builder("testInvalidSeekPositionSourceInfoRefreshStillUpdatesTimeline") .waitForPlaybackState(Player.STATE_BUFFERING) @@ -1312,8 +1303,7 @@ public final class ExoPlayerTest { public void testInvalidSeekPositionAfterSourceInfoRefreshWithShuffleModeEnabledUsesCorrectFirstPeriod() throws Exception { - FakeMediaSource mediaSource = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), /* manifest= */ null); + FakeMediaSource mediaSource = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1)); ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource( /* isAtomic= */ false, new FakeShuffleOrder(0), mediaSource, mediaSource); @@ -1347,7 +1337,7 @@ public final class ExoPlayerTest { public void testRestartAfterEmptyTimelineWithShuffleModeEnabledUsesCorrectFirstPeriod() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - FakeMediaSource mediaSource = new FakeMediaSource(timeline, /* manifest= */ null); + FakeMediaSource mediaSource = new FakeMediaSource(timeline); ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(/* isAtomic= */ false, new FakeShuffleOrder(0)); AtomicInteger windowIndexAfterAddingSources = new AtomicInteger(); @@ -1386,8 +1376,7 @@ public final class ExoPlayerTest { final Timeline timeline = new FakeTimeline(/* windowCount= */ 2); final long[] positionHolder = new long[3]; final int[] windowIndexHolder = new int[3]; - final FakeMediaSource secondMediaSource = - new FakeMediaSource(/* timeline= */ null, /* manifest= */ null); + final FakeMediaSource secondMediaSource = new FakeMediaSource(/* timeline= */ null); ActionSchedule actionSchedule = new ActionSchedule.Builder("testPlaybackErrorDoesNotResetPosition") .pause() @@ -1450,8 +1439,7 @@ public final class ExoPlayerTest { @Test public void testPlaybackErrorTwiceStillKeepsTimeline() throws Exception { final Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - final FakeMediaSource mediaSource2 = - new FakeMediaSource(/* timeline= */ null, /* manifest= */ null); + final FakeMediaSource mediaSource2 = new FakeMediaSource(/* timeline= */ null); ActionSchedule actionSchedule = new ActionSchedule.Builder("testPlaybackErrorDoesNotResetPosition") .pause() @@ -1609,9 +1597,7 @@ public final class ExoPlayerTest { // messages sent at end of playback are received before test ends. .waitForPlaybackState(Player.STATE_ENDED) .prepareSource( - new FakeMediaSource(timeline, null), - /* resetPosition= */ false, - /* resetState= */ true) + new FakeMediaSource(timeline), /* resetPosition= */ false, /* resetState= */ true) .waitForPlaybackState(Player.STATE_BUFFERING) .waitForPlaybackState(Player.STATE_ENDED) .build(); @@ -1774,7 +1760,7 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1), new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 0)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget(); ActionSchedule actionSchedule = new ActionSchedule.Builder("testSendMessages") @@ -1847,7 +1833,7 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1), new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 0)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget(); ActionSchedule actionSchedule = new ActionSchedule.Builder("testSendMessages") @@ -1873,9 +1859,9 @@ public final class ExoPlayerTest { public void testSendMessagesNonLinearPeriodOrder() throws Exception { Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1); MediaSource[] fakeMediaSources = { - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT) + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT) }; ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources); @@ -2022,8 +2008,7 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1), new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 3)); - final FakeMediaSource mediaSource = - new FakeMediaSource(timeline1, /* manifest= */ null, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("testTimelineUpdateDropsPeriods") .pause() @@ -2069,7 +2054,7 @@ public final class ExoPlayerTest { /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 10 * C.MICROS_PER_SECOND)); - FakeMediaSource mediaSource = new FakeMediaSource(timeline, /* manifest= */ null); + FakeMediaSource mediaSource = new FakeMediaSource(timeline); ActionSchedule actionSchedule = new ActionSchedule.Builder("testSeekToUnpreparedPeriod") .pause() @@ -2163,7 +2148,7 @@ public final class ExoPlayerTest { final EventListener eventListener = new EventListener() { @Override - public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) { + public void onTimelineChanged(Timeline timeline, int reason) { if (timeline.isEmpty()) { playerReference.get().setPlayWhenReady(/* playWhenReady= */ false); } @@ -2208,7 +2193,7 @@ public final class ExoPlayerTest { long expectedDurationUs = 700_000; MediaSource mediaSource = new ClippingMediaSource( - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), /* manifest= */ null), + new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1)), startPositionUs, startPositionUs + expectedDurationUs); Clock clock = new AutoAdvancingFakeClock(); @@ -2274,8 +2259,8 @@ public final class ExoPlayerTest { new TimelineWindowDefinition( /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ C.TIME_UNSET)); MediaSource[] fakeMediaSources = { - new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, null, Builder.AUDIO_FORMAT) + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, Builder.AUDIO_FORMAT) }; MediaSource mediaSource = new ConcatenatingMediaSource(fakeMediaSources); FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT); @@ -2326,10 +2311,9 @@ public final class ExoPlayerTest { /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 10 * C.MICROS_PER_SECOND)); - MediaSource workingMediaSource = - new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT); + MediaSource workingMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT); MediaSource failingMediaSource = - new FakeMediaSource(/* timeline= */ null, /* manifest= */ null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) { @Override public void maybeThrowSourceInfoRefreshError() throws IOException { throw new IOException(); @@ -2363,10 +2347,9 @@ public final class ExoPlayerTest { /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 10 * C.MICROS_PER_SECOND)); - MediaSource workingMediaSource = - new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT); + MediaSource workingMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT); MediaSource failingMediaSource = - new FakeMediaSource(/* timeline= */ null, /* manifest= */ null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) { @Override public void maybeThrowSourceInfoRefreshError() throws IOException { throw new IOException(); @@ -2408,7 +2391,7 @@ public final class ExoPlayerTest { /* durationUs= */ 10 * C.MICROS_PER_SECOND)); AtomicReference wasReadyOnce = new AtomicReference<>(false); MediaSource mediaSource = - new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT) { @Override public void maybeThrowSourceInfoRefreshError() throws IOException { if (wasReadyOnce.get()) { @@ -2446,7 +2429,7 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition( /* isSeekable= */ true, /* isDynamic= */ true, /* durationUs= */ 100_000)); - MediaSource mediaSource = new FakeMediaSource(timeline, /* manifest= */ null); + MediaSource mediaSource = new FakeMediaSource(timeline); ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(mediaSource); ActionSchedule actionSchedule = new ActionSchedule.Builder("removingLoopingLastPeriodFromPlaylistDoesNotThrow") @@ -2471,7 +2454,7 @@ public final class ExoPlayerTest { public void seekToUnpreparedWindowWithNonZeroOffsetInConcatenationStartsAtCorrectPosition() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null, /* manifest= */ null); + FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null); MediaSource clippedMediaSource = new ClippingMediaSource( mediaSource, @@ -2519,7 +2502,7 @@ public final class ExoPlayerTest { /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 2 * periodDurationMs * 1000)); - FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null, /* manifest= */ null); + FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null); MediaSource concatenatedMediaSource = new ConcatenatingMediaSource(mediaSource); AtomicInteger periodIndexWhenReady = new AtomicInteger(); AtomicLong positionWhenReady = new AtomicLong(); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java b/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java index 73f42c5fc9..def7f8552e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java @@ -353,7 +353,6 @@ public final class MediaPeriodQueueTest { playbackInfo = new PlaybackInfo( timeline, - /* manifest= */ null, mediaPeriodQueue.resolveMediaPeriodIdForAds(periodUid, initialPositionUs), /* startPositionUs= */ 0, /* contentPositionUs= */ 0, 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 index 22aa63b83a..a2546adfe4 100644 --- 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 @@ -125,7 +125,9 @@ public final class AnalyticsCollectorTest { public void testEmptyTimeline() throws Exception { FakeMediaSource mediaSource = new FakeMediaSource( - Timeline.EMPTY, /* manifest= */ null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + Timeline.EMPTY, + ExoPlayerTestRunner.Builder.VIDEO_FORMAT, + ExoPlayerTestRunner.Builder.AUDIO_FORMAT); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) @@ -140,7 +142,6 @@ public final class AnalyticsCollectorTest { FakeMediaSource mediaSource = new FakeMediaSource( SINGLE_PERIOD_TIMELINE, - /* manifest= */ null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); @@ -183,12 +184,10 @@ public final class AnalyticsCollectorTest { 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); @@ -242,9 +241,8 @@ public final class AnalyticsCollectorTest { 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)); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT), + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.AUDIO_FORMAT)); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); populateEventIds(listener.lastReportedTimeline); @@ -296,9 +294,8 @@ public final class AnalyticsCollectorTest { 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)); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT), + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.AUDIO_FORMAT)); ActionSchedule actionSchedule = new ActionSchedule.Builder("AnalyticsCollectorTest") .pause() @@ -361,12 +358,9 @@ public final class AnalyticsCollectorTest { public void testSeekBackAfterReadingAhead() throws Exception { MediaSource mediaSource = new ConcatenatingMediaSource( - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT), + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT), new FakeMediaSource( - SINGLE_PERIOD_TIMELINE, - /* manifest= */ null, - Builder.VIDEO_FORMAT, - Builder.AUDIO_FORMAT)); + SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT)); long periodDurationMs = SINGLE_PERIOD_TIMELINE.getWindow(/* windowIndex= */ 0, new Window()).getDurationMs(); ActionSchedule actionSchedule = @@ -443,10 +437,8 @@ public final class AnalyticsCollectorTest { @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); + MediaSource mediaSource1 = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT); + MediaSource mediaSource2 = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("AnalyticsCollectorTest") .pause() @@ -507,8 +499,7 @@ public final class AnalyticsCollectorTest { @Test public void testReprepareAfterError() throws Exception { - MediaSource mediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT); + MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder("AnalyticsCollectorTest") .waitForPlaybackState(Player.STATE_READY) @@ -570,7 +561,7 @@ public final class AnalyticsCollectorTest { @Test public void testDynamicTimelineChange() throws Exception { MediaSource childMediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT); final ConcatenatingMediaSource concatenatedMediaSource = new ConcatenatingMediaSource(childMediaSource, childMediaSource); long periodDurationMs = @@ -639,7 +630,7 @@ public final class AnalyticsCollectorTest { @Test public void testNotifyExternalEvents() throws Exception { - MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null); + MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE); ActionSchedule actionSchedule = new ActionSchedule.Builder("AnalyticsCollectorTest") .pause() diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadHelperTest.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadHelperTest.java index 3b78a2e3ae..479936b82f 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadHelperTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadHelperTest.java @@ -60,9 +60,11 @@ public class DownloadHelperTest { private static final String TEST_DOWNLOAD_TYPE = "downloadType"; private static final String TEST_CACHE_KEY = "cacheKey"; - private static final Timeline TEST_TIMELINE = - new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */ 2, /* id= */ new Object())); private static final Object TEST_MANIFEST = new Object(); + private static final Timeline TEST_TIMELINE = + new FakeTimeline( + new Object[] {TEST_MANIFEST}, + new TimelineWindowDefinition(/* periodCount= */ 2, /* id= */ new Object())); private static final Format VIDEO_FORMAT_LOW = createVideoFormat(/* bitrate= */ 200_000); private static final Format VIDEO_FORMAT_HIGH = createVideoFormat(/* bitrate= */ 800_000); @@ -491,7 +493,7 @@ public class DownloadHelperTest { private static final class TestMediaSource extends FakeMediaSource { public TestMediaSource() { - super(TEST_TIMELINE, TEST_MANIFEST); + super(TEST_TIMELINE); } @Override diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java index 846600f243..89acb3ec3e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java @@ -185,6 +185,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline clippedTimeline = getClippedTimeline(timeline, /* durationUs= */ TEST_CLIP_AMOUNT_US); @@ -206,6 +207,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline timeline2 = new SinglePeriodTimeline( @@ -215,6 +217,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline[] clippedTimelines = @@ -253,6 +256,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline timeline2 = new SinglePeriodTimeline( @@ -262,6 +266,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline[] clippedTimelines = @@ -300,6 +305,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline timeline2 = new SinglePeriodTimeline( @@ -309,6 +315,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline[] clippedTimelines = @@ -348,6 +355,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline timeline2 = new SinglePeriodTimeline( @@ -357,6 +365,7 @@ public final class ClippingMediaSourceTest { /* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US, /* isSeekable= */ true, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); Timeline[] clippedTimelines = @@ -473,7 +482,7 @@ public final class ClippingMediaSourceTest { new SinglePeriodTimeline( TEST_PERIOD_DURATION_US, /* isSeekable= */ true, /* isDynamic= */ false); FakeMediaSource fakeMediaSource = - new FakeMediaSource(timeline, /* manifest= */ null) { + new FakeMediaSource(timeline) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -530,7 +539,7 @@ public final class ClippingMediaSourceTest { */ private static Timeline getClippedTimeline(Timeline timeline, long startUs, long endUs) throws IOException { - FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, /* manifest= */ null); + FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline); ClippingMediaSource mediaSource = new ClippingMediaSource(fakeMediaSource, startUs, endUs); return getClippedTimelines(fakeMediaSource, mediaSource)[0]; } @@ -540,7 +549,7 @@ public final class ClippingMediaSourceTest { */ private static Timeline getClippedTimeline(Timeline timeline, long durationUs) throws IOException { - FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, /* manifest= */ null); + FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline); ClippingMediaSource mediaSource = new ClippingMediaSource(fakeMediaSource, durationUs); return getClippedTimelines(fakeMediaSource, mediaSource)[0]; } @@ -557,7 +566,7 @@ public final class ClippingMediaSourceTest { Timeline firstTimeline, Timeline... additionalTimelines) throws IOException { - FakeMediaSource fakeMediaSource = new FakeMediaSource(firstTimeline, /* manifest= */ null); + FakeMediaSource fakeMediaSource = new FakeMediaSource(firstTimeline); ClippingMediaSource mediaSource = new ClippingMediaSource( fakeMediaSource, diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java index 5187addec3..c587d85a85 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java @@ -226,7 +226,7 @@ public final class ConcatenatingMediaSourceTest { FakeMediaSource[] fastSources = createMediaSources(2); final FakeMediaSource[] lazySources = new FakeMediaSource[4]; for (int i = 0; i < 4; i++) { - lazySources[i] = new FakeMediaSource(null, null); + lazySources[i] = new FakeMediaSource(null); } // Add lazy sources and normal sources before preparation. Also remove one lazy source again @@ -307,16 +307,16 @@ public final class ConcatenatingMediaSourceTest { Timeline timeline = testRunner.prepareSource(); TimelineAsserts.assertEmpty(timeline); - mediaSource.addMediaSource(new FakeMediaSource(Timeline.EMPTY, null)); + mediaSource.addMediaSource(new FakeMediaSource(Timeline.EMPTY)); timeline = testRunner.assertTimelineChangeBlocking(); TimelineAsserts.assertEmpty(timeline); mediaSource.addMediaSources( Arrays.asList( new MediaSource[] { - new FakeMediaSource(Timeline.EMPTY, null), new FakeMediaSource(Timeline.EMPTY, null), - new FakeMediaSource(Timeline.EMPTY, null), new FakeMediaSource(Timeline.EMPTY, null), - new FakeMediaSource(Timeline.EMPTY, null), new FakeMediaSource(Timeline.EMPTY, null) + new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY), + new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY), + new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY) })); timeline = testRunner.assertTimelineChangeBlocking(); TimelineAsserts.assertEmpty(timeline); @@ -362,9 +362,9 @@ public final class ConcatenatingMediaSourceTest { public void testDynamicChangeOfEmptyTimelines() throws IOException { FakeMediaSource[] childSources = new FakeMediaSource[] { - new FakeMediaSource(Timeline.EMPTY, /* manifest= */ null), - new FakeMediaSource(Timeline.EMPTY, /* manifest= */ null), - new FakeMediaSource(Timeline.EMPTY, /* manifest= */ null), + new FakeMediaSource(Timeline.EMPTY), + new FakeMediaSource(Timeline.EMPTY), + new FakeMediaSource(Timeline.EMPTY), }; Timeline nonEmptyTimeline = new FakeTimeline(/* windowCount = */ 1); @@ -387,7 +387,7 @@ public final class ConcatenatingMediaSourceTest { @Test public void testIllegalArguments() { - MediaSource validSource = new FakeMediaSource(createFakeTimeline(1), null); + MediaSource validSource = new FakeMediaSource(createFakeTimeline(1)); // Null sources. try { @@ -660,8 +660,8 @@ public final class ConcatenatingMediaSourceTest { 10 * C.MICROS_PER_SECOND, FakeTimeline.createAdPlaybackState( /* adsPerAdGroup= */ 1, /* adGroupTimesUs= */ 0))); - FakeMediaSource mediaSourceContentOnly = new FakeMediaSource(timelineContentOnly, null); - FakeMediaSource mediaSourceWithAds = new FakeMediaSource(timelineWithAds, null); + FakeMediaSource mediaSourceContentOnly = new FakeMediaSource(timelineContentOnly); + FakeMediaSource mediaSourceWithAds = new FakeMediaSource(timelineWithAds); mediaSource.addMediaSource(mediaSourceContentOnly); mediaSource.addMediaSource(mediaSourceWithAds); @@ -807,7 +807,7 @@ public final class ConcatenatingMediaSourceTest { @Test public void testDuplicateMediaSources() throws IOException, InterruptedException { Timeline childTimeline = new FakeTimeline(/* windowCount= */ 2); - FakeMediaSource childSource = new FakeMediaSource(childTimeline, /* manifest= */ null); + FakeMediaSource childSource = new FakeMediaSource(childTimeline); mediaSource.addMediaSource(childSource); mediaSource.addMediaSource(childSource); @@ -840,7 +840,7 @@ public final class ConcatenatingMediaSourceTest { @Test public void testDuplicateNestedMediaSources() throws IOException, InterruptedException { Timeline childTimeline = new FakeTimeline(/* windowCount= */ 1); - FakeMediaSource childSource = new FakeMediaSource(childTimeline, /* manifest= */ null); + FakeMediaSource childSource = new FakeMediaSource(childTimeline); ConcatenatingMediaSource nestedConcatenation = new ConcatenatingMediaSource(); testRunner.prepareSource(); @@ -874,8 +874,7 @@ public final class ConcatenatingMediaSourceTest { public void testClear() throws IOException { DummyMainThread dummyMainThread = new DummyMainThread(); final FakeMediaSource preparedChildSource = createFakeMediaSource(); - final FakeMediaSource unpreparedChildSource = - new FakeMediaSource(/* timeline= */ null, /* manifest= */ null); + final FakeMediaSource unpreparedChildSource = new FakeMediaSource(/* timeline= */ null); dummyMainThread.runOnMainThread( () -> { mediaSource.addMediaSource(preparedChildSource); @@ -1092,13 +1091,13 @@ public final class ConcatenatingMediaSourceTest { private static FakeMediaSource[] createMediaSources(int count) { FakeMediaSource[] sources = new FakeMediaSource[count]; for (int i = 0; i < count; i++) { - sources[i] = new FakeMediaSource(createFakeTimeline(i), null); + sources[i] = new FakeMediaSource(createFakeTimeline(i)); } return sources; } private static FakeMediaSource createFakeMediaSource() { - return new FakeMediaSource(createFakeTimeline(/* index */ 0), null); + return new FakeMediaSource(createFakeTimeline(/* index */ 0)); } private static FakeTimeline createFakeTimeline(int index) { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java index df6506ed52..fa7c2f0614 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java @@ -135,7 +135,7 @@ public class LoopingMediaSourceTest { * Wraps the specified timeline in a {@link LoopingMediaSource} and returns the looping timeline. */ private static Timeline getLoopingTimeline(Timeline timeline, int loopCount) throws IOException { - FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, null); + FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline); LoopingMediaSource mediaSource = new LoopingMediaSource(fakeMediaSource, loopCount); MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null); try { @@ -153,7 +153,7 @@ public class LoopingMediaSourceTest { * the looping timeline can be created and prepared. */ private static void testMediaPeriodCreation(Timeline timeline, int loopCount) throws Exception { - FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, null); + FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline); LoopingMediaSource mediaSource = new LoopingMediaSource(fakeMediaSource, loopCount); MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null); try { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java index 5ea15ac2e8..1434d28500 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java @@ -68,8 +68,7 @@ public class MergingMediaSourceTest { public void testMergingMediaSourcePeriodCreation() throws Exception { FakeMediaSource[] mediaSources = new FakeMediaSource[2]; for (int i = 0; i < mediaSources.length; i++) { - mediaSources[i] = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 2), /* manifest= */ null); + mediaSources[i] = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 2)); } MergingMediaSource mediaSource = new MergingMediaSource(mediaSources); MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null); @@ -92,7 +91,7 @@ public class MergingMediaSourceTest { private static void testMergingMediaSourcePrepare(Timeline... timelines) throws IOException { FakeMediaSource[] mediaSources = new FakeMediaSource[timelines.length]; for (int i = 0; i < timelines.length; i++) { - mediaSources[i] = new FakeMediaSource(timelines[i], null); + mediaSources[i] = new FakeMediaSource(timelines[i]); } MergingMediaSource mergingMediaSource = new MergingMediaSource(mediaSources); MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mergingMediaSource, null); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java index bdd6820efa..701ec3521c 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java @@ -62,6 +62,7 @@ public final class SinglePeriodTimelineTest { /* windowDefaultStartPositionUs= */ 0, /* isSeekable= */ false, /* isDynamic= */ true, + /* manifest= */ null, /* tag= */ null); // Should return null with a positive position projection beyond window duration. Pair position = @@ -84,6 +85,7 @@ public final class SinglePeriodTimelineTest { /* durationUs= */ C.TIME_UNSET, /* isSeekable= */ false, /* isDynamic= */ false, + /* manifest= */ null, /* tag= */ null); assertThat(timeline.getWindow(/* windowIndex= */ 0, window, /* setTag= */ false).tag).isNull(); @@ -100,7 +102,11 @@ public final class SinglePeriodTimelineTest { Object tag = new Object(); SinglePeriodTimeline timeline = new SinglePeriodTimeline( - /* durationUs= */ C.TIME_UNSET, /* isSeekable= */ false, /* isDynamic= */ false, tag); + /* durationUs= */ C.TIME_UNSET, + /* isSeekable= */ false, + /* isDynamic= */ false, + /* manifest= */ null, + tag); assertThat(timeline.getWindow(/* windowIndex= */ 0, window, /* setTag= */ false).tag).isNull(); assertThat(timeline.getWindow(/* windowIndex= */ 0, window, /* setTag= */ true).tag) @@ -114,6 +120,7 @@ public final class SinglePeriodTimelineTest { /* durationUs= */ C.TIME_UNSET, /* isSeekable= */ false, /* isDynamic= */ false, + /* manifest= */ null, /* tag= */ null); Object uid = timeline.getPeriod(/* periodIndex= */ 0, period, /* setIds= */ true).uid; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index 551555502f..b9cb901041 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -994,7 +994,7 @@ public final class DashMediaSource extends BaseMediaSource { windowDefaultStartPositionUs, manifest, tag); - refreshSourceInfo(timeline, manifest); + refreshSourceInfo(timeline); if (!sideloadedManifest) { // Remove any pending simulated refresh. @@ -1193,6 +1193,7 @@ public final class DashMediaSource extends BaseMediaSource { && manifest.durationMs == C.TIME_UNSET; return window.set( tag, + manifest, presentationStartTimeMs, windowStartTimeMs, /* isSeekable= */ true, diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index f891670e78..12c6a8ee72 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -383,6 +383,7 @@ public final class HlsMediaSource extends BaseMediaSource ? windowStartTimeMs : C.TIME_UNSET; long windowDefaultStartPositionUs = playlist.startOffsetUs; + HlsManifest manifest = new HlsManifest(playlistTracker.getMasterPlaylist(), playlist); if (playlistTracker.isLive()) { long offsetFromInitialStartTimeUs = playlist.startTimeUs - playlistTracker.getInitialStartTimeUs(); @@ -403,6 +404,7 @@ public final class HlsMediaSource extends BaseMediaSource windowDefaultStartPositionUs, /* isSeekable= */ true, /* isDynamic= */ !playlist.hasEndTag, + manifest, tag); } else /* not live */ { if (windowDefaultStartPositionUs == C.TIME_UNSET) { @@ -418,9 +420,10 @@ public final class HlsMediaSource extends BaseMediaSource windowDefaultStartPositionUs, /* isSeekable= */ true, /* isDynamic= */ false, + manifest, tag); } - refreshSourceInfo(timeline, new HlsManifest(playlistTracker.getMasterPlaylist(), playlist)); + refreshSourceInfo(timeline); } } diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java index e31fbccae5..c053f255fc 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java @@ -669,6 +669,7 @@ public final class SsMediaSource extends BaseMediaSource /* windowDefaultStartPositionUs= */ 0, /* isSeekable= */ true, manifest.isLive, + manifest, tag); } else if (manifest.isLive) { if (manifest.dvrWindowLengthUs != C.TIME_UNSET && manifest.dvrWindowLengthUs > 0) { @@ -690,6 +691,7 @@ public final class SsMediaSource extends BaseMediaSource defaultStartPositionUs, /* isSeekable= */ true, /* isDynamic= */ true, + manifest, tag); } else { long durationUs = manifest.durationUs != C.TIME_UNSET ? manifest.durationUs @@ -702,9 +704,10 @@ public final class SsMediaSource extends BaseMediaSource /* windowDefaultStartPositionUs= */ 0, /* isSeekable= */ true, /* isDynamic= */ false, + manifest, tag); } - refreshSourceInfo(timeline, manifest); + refreshSourceInfo(timeline); } private void scheduleManifestRefresh() { diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerControlView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerControlView.java index bba422e488..e408035e98 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerControlView.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerControlView.java @@ -1212,8 +1212,7 @@ public class PlayerControlView extends FrameLayout { } @Override - public void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) { + public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) { updateNavigation(); updateTimeline(); } diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java index c800c7bd63..9ad951cb17 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java @@ -1286,7 +1286,7 @@ public class PlayerNotificationManager { } @Override - public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) { + public void onTimelineChanged(Timeline timeline, int reason) { startOrUpdateNotification(); } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java index 93e52bc23a..5d07f986d2 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java @@ -542,9 +542,7 @@ public abstract class Action { } } - /** - * Waits for {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)}. - */ + /** Waits for {@link Player.EventListener#onTimelineChanged(Timeline, int)}. */ public static final class WaitForTimelineChanged extends Action { @Nullable private final Timeline expectedTimeline; @@ -575,9 +573,7 @@ public abstract class Action { new Player.EventListener() { @Override public void onTimelineChanged( - Timeline timeline, - @Nullable Object manifest, - @Player.TimelineChangeReason int reason) { + Timeline timeline, @Player.TimelineChangeReason int reason) { if (expectedTimeline == null || timeline.equals(expectedTimeline)) { player.removeListener(this); nextAction.schedule(player, trackSelector, surface, handler); 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 cc4b3a60d7..f7c6694409 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 @@ -309,9 +309,9 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc } if (mediaSource == null) { if (timeline == null) { - timeline = new FakeTimeline(1); + timeline = new FakeTimeline(/* windowCount= */ 1, manifest); } - mediaSource = new FakeMediaSource(timeline, manifest, supportedFormats); + mediaSource = new FakeMediaSource(timeline, supportedFormats); } if (expectedPlayerEndedCount == null) { expectedPlayerEndedCount = 1; @@ -347,7 +347,6 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc private final CountDownLatch endedCountDownLatch; private final CountDownLatch actionScheduleFinishedCountDownLatch; private final ArrayList timelines; - private final ArrayList manifests; private final ArrayList timelineChangeReasons; private final ArrayList periodIndices; private final ArrayList discontinuityReasons; @@ -380,7 +379,6 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc this.eventListener = eventListener; this.analyticsListener = analyticsListener; this.timelines = new ArrayList<>(); - this.manifests = new ArrayList<>(); this.timelineChangeReasons = new ArrayList<>(); this.periodIndices = new ArrayList<>(); this.discontinuityReasons = new ArrayList<>(); @@ -469,9 +467,8 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc // Assertions called on the test thread after test finished. /** - * Asserts that the timelines reported by - * {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)} are equal to the provided - * timelines. + * Asserts that the timelines reported by {@link Player.EventListener#onTimelineChanged(Timeline, + * int)} are equal to the provided timelines. * * @param timelines A list of expected {@link Timeline}s. */ @@ -479,21 +476,10 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc assertThat(this.timelines).containsExactlyElementsIn(Arrays.asList(timelines)).inOrder(); } - /** - * Asserts that the manifests reported by - * {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)} are equal to the provided - * manifest. - * - * @param manifests A list of expected manifests. - */ - public void assertManifestsEqual(Object... manifests) { - assertThat(this.manifests).containsExactlyElementsIn(Arrays.asList(manifests)).inOrder(); - } - /** * Asserts that the timeline change reasons reported by {@link - * Player.EventListener#onTimelineChanged(Timeline, Object, int)} are equal to the provided - * timeline change reasons. + * Player.EventListener#onTimelineChanged(Timeline, int)} are equal to the provided timeline + * change reasons. */ public void assertTimelineChangeReasonsEqual(Integer... reasons) { assertThat(timelineChangeReasons).containsExactlyElementsIn(Arrays.asList(reasons)).inOrder(); @@ -573,10 +559,8 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc // Player.EventListener @Override - public void onTimelineChanged( - Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) { + public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) { timelines.add(timeline); - manifests.add(manifest); timelineChangeReasons.add(reason); if (reason == Player.TIMELINE_CHANGE_REASON_PREPARED) { periodIndices.add(player.getCurrentPeriodIndex()); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaSource.java index 5a158a3659..0d97b7a20f 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaSource.java @@ -34,10 +34,9 @@ public class FakeAdaptiveMediaSource extends FakeMediaSource { public FakeAdaptiveMediaSource( Timeline timeline, - Object manifest, TrackGroupArray trackGroupArray, FakeChunkSource.Factory chunkSourceFactory) { - super(timeline, manifest, trackGroupArray); + super(timeline, trackGroupArray); this.chunkSourceFactory = chunkSourceFactory; } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java index 80456169ff..8e5ba230ac 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java @@ -56,7 +56,6 @@ public class FakeMediaSource extends BaseMediaSource { private final ArrayList createdMediaPeriods; protected Timeline timeline; - private Object manifest; private boolean preparedSource; private boolean releasedSource; private Handler sourceInfoRefreshHandler; @@ -68,8 +67,8 @@ public class FakeMediaSource extends BaseMediaSource { * null to prevent an immediate source info refresh message when preparing the media source. It * can be manually set later using {@link #setNewSourceInfo(Timeline, Object)}. */ - public FakeMediaSource(@Nullable Timeline timeline, Object manifest, Format... formats) { - this(timeline, manifest, buildTrackGroupArray(formats)); + public FakeMediaSource(@Nullable Timeline timeline, Format... formats) { + this(timeline, buildTrackGroupArray(formats)); } /** @@ -78,10 +77,8 @@ public class FakeMediaSource extends BaseMediaSource { * immediate source info refresh message when preparing the media source. It can be manually set * later using {@link #setNewSourceInfo(Timeline, Object)}. */ - public FakeMediaSource(@Nullable Timeline timeline, Object manifest, - TrackGroupArray trackGroupArray) { + public FakeMediaSource(@Nullable Timeline timeline, TrackGroupArray trackGroupArray) { this.timeline = timeline; - this.manifest = manifest; this.activeMediaPeriods = new ArrayList<>(); this.createdMediaPeriods = new ArrayList<>(); this.trackGroupArray = trackGroupArray; @@ -158,12 +155,10 @@ public class FakeMediaSource extends BaseMediaSource { assertThat(releasedSource).isFalse(); assertThat(preparedSource).isTrue(); timeline = newTimeline; - manifest = newManifest; finishSourcePreparation(); }); } else { timeline = newTimeline; - manifest = newManifest; } } @@ -212,7 +207,7 @@ public class FakeMediaSource extends BaseMediaSource { } private void finishSourcePreparation() { - refreshSourceInfo(timeline, manifest); + refreshSourceInfo(timeline); if (!timeline.isEmpty()) { MediaLoadData mediaLoadData = new MediaLoadData( diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java index 56438a51ef..58ee32cdd9 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java @@ -112,6 +112,7 @@ public final class FakeTimeline extends Timeline { private static final long AD_DURATION_US = 10 * C.MICROS_PER_SECOND; private final TimelineWindowDefinition[] windowDefinitions; + private final Object[] manifests; private final int[] periodOffsets; /** @@ -140,9 +141,10 @@ public final class FakeTimeline extends Timeline { * with a duration of {@link TimelineWindowDefinition#DEFAULT_WINDOW_DURATION_US} each. * * @param windowCount The number of windows. + * @param manifests The manifests of the windows. */ - public FakeTimeline(int windowCount) { - this(createDefaultWindowDefinitions(windowCount)); + public FakeTimeline(int windowCount, Object... manifests) { + this(manifests, createDefaultWindowDefinitions(windowCount)); } /** @@ -151,6 +153,18 @@ public final class FakeTimeline extends Timeline { * @param windowDefinitions A list of {@link TimelineWindowDefinition}s. */ public FakeTimeline(TimelineWindowDefinition... windowDefinitions) { + this(new Object[0], windowDefinitions); + } + + /** + * Creates a fake timeline with the given window definitions. + * + * @param windowDefinitions A list of {@link TimelineWindowDefinition}s. + */ + public FakeTimeline(Object[] manifests, TimelineWindowDefinition... windowDefinitions) { + this.manifests = new Object[windowDefinitions.length]; + System.arraycopy( + manifests, 0, this.manifests, 0, Math.min(this.manifests.length, manifests.length)); this.windowDefinitions = windowDefinitions; periodOffsets = new int[windowDefinitions.length + 1]; periodOffsets[0] = 0; @@ -171,6 +185,7 @@ public final class FakeTimeline extends Timeline { Object tag = setTag ? windowDefinition.id : null; return window.set( tag, + manifests[windowIndex], /* presentationStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET, windowDefinition.isSeekable, diff --git a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java index 0873dbd145..6d626088fc 100644 --- a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java +++ b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java @@ -345,7 +345,7 @@ public class MediaSourceTestRunner { // SourceInfoRefreshListener methods. @Override - public void onSourceInfoRefreshed(MediaSource source, Timeline timeline, Object manifest) { + public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); timelines.addLast(timeline); } diff --git a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java index df96b634dd..eaebe5a12d 100644 --- a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java +++ b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java @@ -195,11 +195,6 @@ public abstract class StubExoPlayer extends BasePlayer implements ExoPlayer { throw new UnsupportedOperationException(); } - @Override - public Object getCurrentManifest() { - throw new UnsupportedOperationException(); - } - @Override public Timeline getCurrentTimeline() { throw new UnsupportedOperationException();