add manifest to Timeline.Window

- Remove manifest argument from callbacks of Player.EventListener and
  SourceInfoRefreshListener. Instead make it accessible through
  Player.getCurrentManifest() and Timeline.Window.manifest.
- Fix all MediaSource implementation to include the manifest in the
  Timeline instead of passing it to the SourceInfoRefreshListener.
- Refactor ExoPlayerTestRunner, FakeTimeline, FakeMediaSource to
  reflect these changes and make tests pass.

PiperOrigin-RevId: 257359662
This commit is contained in:
bachinger 2019-07-10 09:52:53 +01:00 committed by Oliver Woodman
parent 877923ce5f
commit 49a2e5a5cb
53 changed files with 316 additions and 330 deletions

View file

@ -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 ###

View file

@ -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();
}

View file

@ -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)));
}
}

View file

@ -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,

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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();

View file

@ -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

View file

@ -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(

View file

@ -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;
}
}

View file

@ -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,

View file

@ -324,6 +324,29 @@ public interface Player {
*/
interface EventListener {
/**
* Called when the timeline has been refreshed.
*
* <p>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 <em>not</em> 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).
*
* <p>When a position discontinuity occurs as a result of a change to the timeline this method
* is <em>not</em> called. {@link #onTimelineChanged(Timeline, Object, int)} is called in this
* case.
* is <em>not</em> 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.

View file

@ -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();

View file

@ -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;

View file

@ -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) {

View file

@ -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 =

View file

@ -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.
*
* <p>Whenever an implementing subclass needs to provide a new timeline and/or manifest, it must
* call {@link #refreshSourceInfo(Timeline, Object)} to notify all listeners.
* <p>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();
}
}

View file

@ -87,7 +87,6 @@ public final class ClippingMediaSource extends CompositeMediaSource<Void> {
private final ArrayList<ClippingMediaPeriod> 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<Void> {
}
@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<Void> {
clippingError = e;
return;
}
refreshSourceInfo(clippingTimeline, manifest);
refreshSourceInfo(clippingTimeline);
}
@Override

View file

@ -73,17 +73,15 @@ public abstract class CompositeMediaSource<T> 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.
*
* <p>{@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.
* <p>{@link #onChildSourceInfoRefreshed(Object, MediaSource, Timeline)} will be called when the
* child source updates its timeline with the same {@code id} passed to this method.
*
* <p>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<T> 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);

View file

@ -474,10 +474,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
@Override
protected void onChildSourceInfoRefreshed(
MediaSourceHolder mediaSourceHolder,
MediaSource mediaSource,
Timeline timeline,
@Nullable Object manifest) {
MediaSourceHolder mediaSourceHolder, MediaSource mediaSource, Timeline timeline) {
updateMediaSourceInternal(mediaSourceHolder, timeline);
}
@ -679,8 +676,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
timelineUpdateScheduled = false;
Set<HandlerAndRunnable> 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();

View file

@ -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

View file

@ -100,13 +100,12 @@ public final class LoopingMediaSource extends CompositeMediaSource<Void> {
}
@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

View file

@ -119,7 +119,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
@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<Void> {
}
}
isPrepared = true;
refreshSourceInfo(this.timeline, manifest);
refreshSourceInfo(this.timeline);
}
@Nullable
@ -274,6 +274,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
int windowIndex, Window window, boolean setTag, long defaultPositionProjectionUs) {
return window.set(
tag,
/* manifest= */ null,
/* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET,
/* isSeekable= */ false,

View file

@ -58,8 +58,8 @@ public interface MediaPeriod extends SequenceableLoader {
*
* <p>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.

View file

@ -49,16 +49,16 @@ public interface MediaSource {
interface SourceInfoRefreshListener {
/**
* Called when manifest and/or timeline has been refreshed.
* <p>
* Called on the playback thread.
* Called when the timeline has been refreshed.
*
* <p>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.
}
}
/**

View file

@ -71,7 +71,6 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
private final ArrayList<MediaSource> 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<Integer> {
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<Integer> {
@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<Integer> {
}
pendingTimelineSources.remove(mediaSource);
timelines[id] = timeline;
if (mediaSource == mediaSources[0]) {
primaryManifest = manifest;
}
if (pendingTimelineSources.isEmpty()) {
refreshSourceInfo(timelines[0], primaryManifest);
refreshSourceInfo(timelines[0]);
}
}

View file

@ -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));
}
}

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -134,7 +134,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
// 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<MediaPeriodId> {
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<MediaPeriodId> {
@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<MediaPeriodId> {
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<MediaPeriodId> {
adPlaybackState.adGroupCount == 0
? contentTimeline
: new SinglePeriodAdTimeline(contentTimeline, adPlaybackState);
refreshSourceInfo(timeline, contentManifest);
refreshSourceInfo(timeline);
}
}

View file

@ -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<Boolean> 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();

View file

@ -353,7 +353,6 @@ public final class MediaPeriodQueueTest {
playbackInfo =
new PlaybackInfo(
timeline,
/* manifest= */ null,
mediaPeriodQueue.resolveMediaPeriodIdForAds(periodUid, initialPositionUs),
/* startPositionUs= */ 0,
/* contentPositionUs= */ 0,

View file

@ -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()

View file

@ -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

View file

@ -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,

View file

@ -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) {

View file

@ -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 {

View file

@ -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);

View file

@ -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<Object, Long> 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;

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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() {

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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<Timeline> timelines;
private final ArrayList<Object> manifests;
private final ArrayList<Integer> timelineChangeReasons;
private final ArrayList<Integer> periodIndices;
private final ArrayList<Integer> 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());

View file

@ -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;
}

View file

@ -56,7 +56,6 @@ public class FakeMediaSource extends BaseMediaSource {
private final ArrayList<MediaPeriodId> 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(

View file

@ -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,

View file

@ -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);
}

View file

@ -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();