Commit a9913e54 by bachinger

Add the media item to PositionInfo

PiperOrigin-RevId: 392914515
parent e5a39eca
......@@ -790,6 +790,7 @@ public final class CastPlayer extends BasePlayer {
new PositionInfo(
window.uid,
period.windowIndex,
window.mediaItem,
period.uid,
period.windowIndex,
/* positionMs= */ windowDurationMs,
......@@ -802,6 +803,7 @@ public final class CastPlayer extends BasePlayer {
new PositionInfo(
window.uid,
period.windowIndex,
window.mediaItem,
period.uid,
period.windowIndex,
/* positionMs= */ window.getDefaultPositionMs(),
......@@ -904,6 +906,7 @@ public final class CastPlayer extends BasePlayer {
new PositionInfo(
window.uid,
period.windowIndex,
window.mediaItem,
period.uid,
period.windowIndex,
getCurrentPosition(),
......@@ -1082,17 +1085,19 @@ public final class CastPlayer extends BasePlayer {
private PositionInfo getCurrentPositionInfo() {
Timeline currentTimeline = getCurrentTimeline();
@Nullable
Object newPeriodUid =
!currentTimeline.isEmpty()
? currentTimeline.getPeriod(getCurrentPeriodIndex(), period, /* setIds= */ true).uid
: null;
@Nullable
Object newWindowUid =
newPeriodUid != null ? currentTimeline.getWindow(period.windowIndex, window).uid : null;
@Nullable Object newPeriodUid = null;
@Nullable Object newWindowUid = null;
@Nullable MediaItem newMediaItem = null;
if (!currentTimeline.isEmpty()) {
newPeriodUid =
currentTimeline.getPeriod(getCurrentPeriodIndex(), period, /* setIds= */ true).uid;
newWindowUid = currentTimeline.getWindow(period.windowIndex, window).uid;
newMediaItem = window.mediaItem;
}
return new PositionInfo(
newWindowUid,
getCurrentWindowIndex(),
newMediaItem,
newPeriodUid,
getCurrentPeriodIndex(),
getCurrentPosition(),
......
......@@ -380,6 +380,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 2,
/* windowIndex= */ 1,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2,
/* periodIndex= */ 1,
/* positionMs= */ 2000,
......@@ -390,6 +391,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 3,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(3).build(),
/* periodUid= */ 3,
/* periodIndex= */ 0,
/* positionMs= */ 1000,
......@@ -660,6 +662,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 1234,
......@@ -670,6 +673,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ null,
/* windowIndex= */ 0,
/* mediaItem= */ null,
/* periodUid= */ null,
/* periodIndex= */ 0,
/* positionMs= */ 0,
......@@ -744,6 +748,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 1234,
......@@ -754,6 +759,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 2,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2,
/* periodIndex= */ 0,
/* positionMs= */ 0,
......@@ -825,6 +831,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 0, // position at which we receive the timeline change
......@@ -835,6 +842,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 2,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2,
/* periodIndex= */ 0,
/* positionMs= */ 0,
......@@ -937,6 +945,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 0,
......@@ -947,6 +956,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 2,
/* windowIndex= */ 1,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2,
/* periodIndex= */ 1,
/* positionMs= */ 1234,
......@@ -992,10 +1002,12 @@ public class CastPlayerTest {
updateTimeLine(mediaItems, mediaQueueItemIds, /* currentItemId= */ 1);
castPlayer.seekTo(/* windowIndex= */ 0, /* positionMs= */ 1234);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build();
Player.PositionInfo oldPosition =
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 0,
......@@ -1006,6 +1018,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 1234,
......@@ -1076,6 +1089,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 12500,
......@@ -1086,6 +1100,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 2,
/* windowIndex= */ 1,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2,
/* periodIndex= */ 1,
/* positionMs= */ 0,
......@@ -1120,10 +1135,12 @@ public class CastPlayerTest {
mediaItems, mediaQueueItemIds, currentItemId, streamTypes, durationsMs, positionMs);
castPlayer.seekBack();
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build();
Player.PositionInfo oldPosition =
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 2 * C.DEFAULT_SEEK_BACK_INCREMENT_MS,
......@@ -1134,6 +1151,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ C.DEFAULT_SEEK_BACK_INCREMENT_MS,
......@@ -1166,10 +1184,12 @@ public class CastPlayerTest {
mediaItems, mediaQueueItemIds, currentItemId, streamTypes, durationsMs, positionMs);
castPlayer.seekForward();
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build();
Player.PositionInfo oldPosition =
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ 0,
......@@ -1180,6 +1200,7 @@ public class CastPlayerTest {
new Player.PositionInfo(
/* windowUid= */ 1,
/* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1,
/* periodIndex= */ 0,
/* positionMs= */ C.DEFAULT_SEEK_FORWARD_INCREMENT_MS,
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.ext.ima;
import android.os.Looper;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.testutil.StubExoPlayer;
......@@ -32,6 +33,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
private final Timeline.Period period;
private final Object windowUid = new Object();
private final Object periodUid = new Object();
private final MediaItem mediaItem = MediaItem.fromUri("http://google.com/0");
private Timeline timeline;
@Player.State private int state;
......@@ -72,6 +74,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo(
windowUid,
/* windowIndex= */ 0,
mediaItem,
periodUid,
/* periodIndex= */ 0,
this.positionMs,
......@@ -89,6 +92,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo(
windowUid,
/* windowIndex= */ 0,
mediaItem,
periodUid,
/* periodIndex= */ 0,
positionMs,
......@@ -119,6 +123,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo(
windowUid,
/* windowIndex= */ 0,
mediaItem,
periodUid,
/* periodIndex= */ 0,
this.positionMs,
......@@ -136,6 +141,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo(
windowUid,
/* windowIndex= */ 0,
mediaItem,
periodUid,
/* periodIndex= */ 0,
positionMs,
......
......@@ -56,6 +56,7 @@ import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer;
import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
......@@ -281,6 +282,7 @@ public final class ImaAdsLoaderTest {
new Player.PositionInfo(
/* windowUid= */ new Object(),
/* windowIndex= */ 0,
/* mediaItem= */ MediaItem.fromUri("http://google.com/0"),
/* periodUid= */ new Object(),
/* periodIndex= */ 0,
/* positionMs= */ 10_000,
......@@ -290,6 +292,7 @@ public final class ImaAdsLoaderTest {
new Player.PositionInfo(
/* windowUid= */ new Object(),
/* windowIndex= */ 1,
/* mediaItem= */ MediaItem.fromUri("http://google.com/1"),
/* periodUid= */ new Object(),
/* periodIndex= */ 0,
/* positionMs= */ 20_000,
......
......@@ -32,6 +32,7 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.util.BundleableUtils;
import com.google.android.exoplayer2.util.FlagSet;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoSize;
......@@ -468,13 +469,15 @@ public interface Player {
final class PositionInfo implements Bundleable {
/**
* The UID of the window, or {@code null}, if the timeline is {@link Timeline#isEmpty() empty}.
* The UID of the window, or {@code null} if the timeline is {@link Timeline#isEmpty() empty}.
*/
@Nullable public final Object windowUid;
/** The window index. */
public final int windowIndex;
/** The media item, or {@code null} if the timeline is {@link Timeline#isEmpty() empty}. */
@Nullable public final MediaItem mediaItem;
/**
* The UID of the period, or {@code null}, if the timeline is {@link Timeline#isEmpty() empty}.
* The UID of the period, or {@code null} if the timeline is {@link Timeline#isEmpty() empty}.
*/
@Nullable public final Object periodUid;
/** The period index. */
......@@ -498,10 +501,37 @@ public interface Player {
*/
public final int adIndexInAdGroup;
/**
* @deprecated Use {@link #PositionInfo(Object, int, MediaItem, Object, int, long, long, int,
* int)} instead.
*/
@Deprecated
public PositionInfo(
@Nullable Object windowUid,
int windowIndex,
@Nullable Object periodUid,
int periodIndex,
long positionMs,
long contentPositionMs,
int adGroupIndex,
int adIndexInAdGroup) {
this(
windowUid,
windowIndex,
MediaItem.EMPTY,
periodUid,
periodIndex,
positionMs,
contentPositionMs,
adGroupIndex,
adIndexInAdGroup);
}
/** Creates an instance. */
public PositionInfo(
@Nullable Object windowUid,
int windowIndex,
@Nullable MediaItem mediaItem,
@Nullable Object periodUid,
int periodIndex,
long positionMs,
......@@ -510,6 +540,7 @@ public interface Player {
int adIndexInAdGroup) {
this.windowUid = windowUid;
this.windowIndex = windowIndex;
this.mediaItem = mediaItem;
this.periodUid = periodUid;
this.periodIndex = periodIndex;
this.positionMs = positionMs;
......@@ -534,7 +565,8 @@ public interface Player {
&& adGroupIndex == that.adGroupIndex
&& adIndexInAdGroup == that.adIndexInAdGroup
&& Objects.equal(windowUid, that.windowUid)
&& Objects.equal(periodUid, that.periodUid);
&& Objects.equal(periodUid, that.periodUid)
&& Objects.equal(mediaItem, that.mediaItem);
}
@Override
......@@ -542,6 +574,7 @@ public interface Player {
return Objects.hashCode(
windowUid,
windowIndex,
mediaItem,
periodUid,
periodIndex,
windowIndex,
......@@ -556,6 +589,7 @@ public interface Player {
@Retention(RetentionPolicy.SOURCE)
@IntDef({
FIELD_WINDOW_INDEX,
FIELD_MEDIA_ITEM,
FIELD_PERIOD_INDEX,
FIELD_POSITION_MS,
FIELD_CONTENT_POSITION_MS,
......@@ -565,11 +599,12 @@ public interface Player {
private @interface FieldNumber {}
private static final int FIELD_WINDOW_INDEX = 0;
private static final int FIELD_PERIOD_INDEX = 1;
private static final int FIELD_POSITION_MS = 2;
private static final int FIELD_CONTENT_POSITION_MS = 3;
private static final int FIELD_AD_GROUP_INDEX = 4;
private static final int FIELD_AD_INDEX_IN_AD_GROUP = 5;
private static final int FIELD_MEDIA_ITEM = 1;
private static final int FIELD_PERIOD_INDEX = 2;
private static final int FIELD_POSITION_MS = 3;
private static final int FIELD_CONTENT_POSITION_MS = 4;
private static final int FIELD_AD_GROUP_INDEX = 5;
private static final int FIELD_AD_INDEX_IN_AD_GROUP = 6;
/**
* {@inheritDoc}
......@@ -581,6 +616,7 @@ public interface Player {
public Bundle toBundle() {
Bundle bundle = new Bundle();
bundle.putInt(keyForField(FIELD_WINDOW_INDEX), windowIndex);
bundle.putBundle(keyForField(FIELD_MEDIA_ITEM), BundleableUtils.toNullableBundle(mediaItem));
bundle.putInt(keyForField(FIELD_PERIOD_INDEX), periodIndex);
bundle.putLong(keyForField(FIELD_POSITION_MS), positionMs);
bundle.putLong(keyForField(FIELD_CONTENT_POSITION_MS), contentPositionMs);
......@@ -595,6 +631,10 @@ public interface Player {
private static PositionInfo fromBundle(Bundle bundle) {
int windowIndex =
bundle.getInt(keyForField(FIELD_WINDOW_INDEX), /* defaultValue= */ C.INDEX_UNSET);
@Nullable
MediaItem mediaItem =
BundleableUtils.fromNullableBundle(
MediaItem.CREATOR, bundle.getBundle(keyForField(FIELD_MEDIA_ITEM)));
int periodIndex =
bundle.getInt(keyForField(FIELD_PERIOD_INDEX), /* defaultValue= */ C.INDEX_UNSET);
long positionMs =
......@@ -608,6 +648,7 @@ public interface Player {
return new PositionInfo(
/* windowUid= */ null,
windowIndex,
mediaItem,
/* periodUid= */ null,
periodIndex,
positionMs,
......
......@@ -32,6 +32,7 @@ public class PositionInfoTest {
new PositionInfo(
/* windowUid= */ null,
/* windowIndex= */ 23,
new MediaItem.Builder().setMediaId("1234").build(),
/* periodUid= */ null,
/* periodIndex= */ 11,
/* positionMs= */ 8787L,
......@@ -48,6 +49,7 @@ public class PositionInfoTest {
new PositionInfo(
/* windowUid= */ new Object(),
/* windowIndex= */ 23,
MediaItem.fromUri("https://exoplayer.dev"),
/* periodUid= */ null,
/* periodIndex= */ 11,
/* positionMs= */ 8787L,
......@@ -65,6 +67,7 @@ public class PositionInfoTest {
new PositionInfo(
/* windowUid= */ null,
/* windowIndex= */ 23,
MediaItem.fromUri("https://exoplayer.dev"),
/* periodUid= */ new Object(),
/* periodIndex= */ 11,
/* positionMs= */ 8787L,
......
......@@ -1360,6 +1360,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Nullable Object oldPeriodUid = null;
int oldWindowIndex = oldMaskingWindowIndex;
int oldPeriodIndex = C.INDEX_UNSET;
@Nullable MediaItem oldMediaItem = null;
Timeline.Period oldPeriod = new Timeline.Period();
if (!oldPlaybackInfo.timeline.isEmpty()) {
oldPeriodUid = oldPlaybackInfo.periodId.periodUid;
......@@ -1367,6 +1368,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
oldWindowIndex = oldPeriod.windowIndex;
oldPeriodIndex = oldPlaybackInfo.timeline.getIndexOfPeriod(oldPeriodUid);
oldWindowUid = oldPlaybackInfo.timeline.getWindow(oldWindowIndex, window).uid;
oldMediaItem = window.mediaItem;
}
long oldPositionUs;
long oldContentPositionUs;
......@@ -1397,6 +1399,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
return new PositionInfo(
oldWindowUid,
oldWindowIndex,
oldMediaItem,
oldPeriodUid,
oldPeriodIndex,
C.usToMs(oldPositionUs),
......@@ -1410,16 +1413,19 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Nullable Object newPeriodUid = null;
int newWindowIndex = getCurrentWindowIndex();
int newPeriodIndex = C.INDEX_UNSET;
@Nullable MediaItem newMediaItem = null;
if (!playbackInfo.timeline.isEmpty()) {
newPeriodUid = playbackInfo.periodId.periodUid;
playbackInfo.timeline.getPeriodByUid(newPeriodUid, period);
newPeriodIndex = playbackInfo.timeline.getIndexOfPeriod(newPeriodUid);
newWindowUid = playbackInfo.timeline.getWindow(newWindowIndex, window).uid;
newMediaItem = window.mediaItem;
}
long positionMs = C.usToMs(discontinuityWindowStartPositionUs);
return new PositionInfo(
newWindowUid,
newWindowIndex,
newMediaItem,
newPeriodUid,
newPeriodIndex,
positionMs,
......
......@@ -85,6 +85,8 @@ import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Player.DiscontinuityReason;
import com.google.android.exoplayer2.Player.Listener;
import com.google.android.exoplayer2.Player.PositionInfo;
import com.google.android.exoplayer2.Timeline.Window;
import com.google.android.exoplayer2.analytics.AnalyticsListener;
import com.google.android.exoplayer2.audio.AudioAttributes;
......@@ -120,6 +122,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.testutil.FakeMediaClockRenderer;
import com.google.android.exoplayer2.testutil.FakeMediaPeriod;
import com.google.android.exoplayer2.testutil.FakeMediaSource;
import com.google.android.exoplayer2.testutil.FakeMediaSourceFactory;
import com.google.android.exoplayer2.testutil.FakeRenderer;
import com.google.android.exoplayer2.testutil.FakeSampleStream;
import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem;
......@@ -142,7 +145,6 @@ import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import java.io.IOException;
import java.util.ArrayList;
......@@ -9580,6 +9582,7 @@ public final class ExoPlayerTest {
assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid);
assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex);
assertThat(oldPositionInfo.windowIndex).isEqualTo(newPositionInfo.windowIndex);
assertThat(oldPositionInfo.mediaItem.playbackProperties.tag).isEqualTo(1);
assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(10_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000);
......@@ -9601,6 +9604,7 @@ public final class ExoPlayerTest {
assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid);
assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex);
assertThat(oldPositionInfo.windowIndex).isEqualTo(newPositionInfo.windowIndex);
assertThat(oldPositionInfo.mediaItem.playbackProperties.tag).isEqualTo(1);
assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(10_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000);
......@@ -9620,6 +9624,7 @@ public final class ExoPlayerTest {
oldPositionInfo = oldPosition.getValue();
newPositionInfo = newPosition.getValue();
assertThat(oldPositionInfo.windowIndex).isEqualTo(1);
assertThat(oldPositionInfo.mediaItem.playbackProperties.tag).isEqualTo(2);
assertThat(oldPositionInfo.windowUid).isNotEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(20_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(20_000);
......@@ -9881,7 +9886,7 @@ public final class ExoPlayerTest {
TimelineWindowDefinition postRollWindow =
new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ 0,
/* id= */ "id-2",
/* isSeekable= */ true,
/* isDynamic= */ false,
/* isLive= */ false,
......@@ -9895,7 +9900,7 @@ public final class ExoPlayerTest {
TimelineWindowDefinition preRollWindow =
new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ 0,
/* id= */ "id-3",
/* isSeekable= */ true,
/* isDynamic= */ false,
/* isLive= */ false,
......@@ -9905,11 +9910,13 @@ public final class ExoPlayerTest {
/* windowOffsetInFirstPeriodUs= */ 0,
preRollAdPlaybackState);
player.setMediaSources(
Lists.newArrayList(
new FakeMediaSource(),
ImmutableList.of(
createFakeMediaSource(/* id= */ "id-0"),
new FakeMediaSource(
new FakeTimeline(
new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ "id-1",
/* isSeekable= */ true,
/* isDynamic= */ false,
/* durationUs= */ 15 * C.MICROS_PER_SECOND))),
......@@ -9939,6 +9946,7 @@ public final class ExoPlayerTest {
assertThat(oldPosition.getValue().windowUid)
.isEqualTo(player.getCurrentTimeline().getWindow(0, window).uid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(0);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-0");
assertThat(oldPosition.getValue().positionMs).isEqualTo(10_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(10_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
......@@ -9946,6 +9954,7 @@ public final class ExoPlayerTest {
assertThat(newPosition.getValue().windowUid)
.isEqualTo(player.getCurrentTimeline().getWindow(1, window).uid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(1);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-1");
assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
......@@ -9965,11 +9974,13 @@ public final class ExoPlayerTest {
assertThat(newPosition.getValue().windowUid)
.isEqualTo(player.getCurrentTimeline().getWindow(2, window).uid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(1);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-1");
assertThat(oldPosition.getValue().positionMs).isEqualTo(15_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(15_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1);
assertThat(newPosition.getValue().windowIndex).isEqualTo(2);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
......@@ -9983,12 +9994,14 @@ public final class ExoPlayerTest {
newPosition.capture(),
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(oldPosition.getValue().windowIndex).isEqualTo(2);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().positionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1);
assertThat(newPosition.getValue().windowIndex).isEqualTo(2);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(0);
......@@ -10003,12 +10016,14 @@ public final class ExoPlayerTest {
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(2);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(oldPosition.getValue().positionMs).isEqualTo(5_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(0);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(0);
assertThat(newPosition.getValue().windowUid).isEqualTo(oldPosition.getValue().windowUid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(2);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(newPosition.getValue().positionMs).isEqualTo(19_999);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(19_999);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
......@@ -10026,12 +10041,14 @@ public final class ExoPlayerTest {
.onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_AUTO));
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(2);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(oldPosition.getValue().positionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1);
assertThat(newPosition.getValue().windowUid).isNotEqualTo(oldPosition.getValue().windowUid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(3);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-3");
assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(0);
......@@ -10046,12 +10063,14 @@ public final class ExoPlayerTest {
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(3);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-3");
assertThat(oldPosition.getValue().positionMs).isEqualTo(5_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(0);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(0);
assertThat(newPosition.getValue().windowUid).isEqualTo(oldPosition.getValue().windowUid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(3);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-3");
assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
......@@ -10093,7 +10112,7 @@ public final class ExoPlayerTest {
player.prepare();
TestPlayerRunHelper.playUntilPosition(
player, /* windowIndex= */ 0, /* positionMs= */ 5 * C.MILLIS_PER_SECOND);
player.setMediaSources(Lists.newArrayList(secondMediaSource, secondMediaSource));
player.setMediaSources(ImmutableList.of(secondMediaSource, secondMediaSource));
player.play();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
......@@ -10121,13 +10140,80 @@ public final class ExoPlayerTest {
}
@Test
public void onPositionDiscontinuity_recursiveStateChange_mediaItemMaskingCorrect()
throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
MediaItem[] currentMediaItems = new MediaItem[2];
int[] mediaItemCount = new int[2];
player.addListener(
new Listener() {
@Override
public void onPositionDiscontinuity(
PositionInfo oldPosition, PositionInfo newPosition, int reason) {
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
mediaItemCount[0] = player.getMediaItemCount();
currentMediaItems[0] = player.getCurrentMediaItem();
// This is called before the second listener is called.
player.removeMediaItem(/* index= */ 1);
}
}
});
player.addListener(
new Listener() {
@Override
public void onPositionDiscontinuity(
PositionInfo oldPosition, PositionInfo newPosition, int reason) {
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
mediaItemCount[1] = player.getMediaItemCount();
currentMediaItems[1] = player.getCurrentMediaItem();
}
}
});
player.addListener(listener);
player.setMediaSources(
ImmutableList.of(
createFakeMediaSource(/* id= */ "id-0"), createFakeMediaSource(/* id= */ "id-1")));
player.prepare();
player.play();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor =
ArgumentCaptor.forClass(PositionInfo.class);
InOrder inOrder = inOrder(listener);
inOrder
.verify(listener)
.onPositionDiscontinuity(
any(),
newPositionArgumentCaptor.capture(),
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
inOrder
.verify(listener)
.onPositionDiscontinuity(
any(), newPositionArgumentCaptor.capture(), eq(Player.DISCONTINUITY_REASON_REMOVE));
// The state at auto-transition event time.
assertThat(mediaItemCount[0]).isEqualTo(2);
assertThat(currentMediaItems[0].playbackProperties.tag).isEqualTo("id-1");
// The masked state after id-1 has been removed.
assertThat(mediaItemCount[1]).isEqualTo(1);
assertThat(currentMediaItems[1].playbackProperties.tag).isEqualTo("id-0");
// PositionInfo reports the media item at event time.
assertThat(newPositionArgumentCaptor.getAllValues().get(0).mediaItem.playbackProperties.tag)
.isEqualTo("id-1");
assertThat(newPositionArgumentCaptor.getAllValues().get(1).mediaItem.playbackProperties.tag)
.isEqualTo("id-0");
player.release();
}
@Test
public void removeMediaItems_removesPlayingPeriod_callsOnPositionDiscontinuity()
throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
player.setMediaSources(
Lists.newArrayList(
ImmutableList.of(
new FakeMediaSource(
new FakeTimeline(
new TimelineWindowDefinition(
......@@ -10355,11 +10441,75 @@ public final class ExoPlayerTest {
}
@Test
public void setMediaItems_callsListenersWithSameInstanceOfMediaItem() throws Exception {
ArgumentCaptor<Timeline> timeline = ArgumentCaptor.forClass(Timeline.class);
ArgumentCaptor<Player.PositionInfo> oldPosition =
ArgumentCaptor.forClass(Player.PositionInfo.class);
ArgumentCaptor<Player.PositionInfo> newPosition =
ArgumentCaptor.forClass(Player.PositionInfo.class);
ArgumentCaptor<MediaItem> currentMediaItem = ArgumentCaptor.forClass(MediaItem.class);
Window window = new Timeline.Window();
ExoPlayer player =
new TestExoPlayerBuilder(context)
.setMediaSourceFactory(new FakeMediaSourceFactory())
.build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
List<MediaItem> playlist =
ImmutableList.of(
MediaItem.fromUri("http://item-0.com/"), MediaItem.fromUri("http://item-1.com/"));
player.setMediaItems(playlist);
player.prepare();
player.seekTo(/* positionMs= */ 2000);
player.play();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
InOrder inOrder = inOrder(listener);
inOrder
.verify(listener)
.onTimelineChanged(timeline.capture(), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder
.verify(listener)
.onMediaItemTransition(
currentMediaItem.capture(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED));
inOrder
.verify(listener)
.onPositionDiscontinuity(
oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_SEEK));
inOrder
.verify(listener)
.onPositionDiscontinuity(
oldPosition.capture(),
newPosition.capture(),
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
inOrder
.verify(listener)
.onMediaItemTransition(
currentMediaItem.capture(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_AUTO));
inOrder.verify(listener, never()).onPositionDiscontinuity(any(), any(), anyInt());
inOrder.verify(listener, never()).onMediaItemTransition(any(), anyInt());
assertThat(timeline.getValue().getWindow(0, window).mediaItem)
.isSameInstanceAs(playlist.get(0));
assertThat(timeline.getValue().getWindow(1, window).mediaItem)
.isSameInstanceAs(playlist.get(1));
assertThat(oldPosition.getAllValues().get(0).mediaItem).isSameInstanceAs(playlist.get(0));
assertThat(newPosition.getAllValues().get(0).mediaItem).isSameInstanceAs(playlist.get(0));
assertThat(oldPosition.getAllValues().get(1).mediaItem).isSameInstanceAs(playlist.get(0));
assertThat(newPosition.getAllValues().get(1).mediaItem).isSameInstanceAs(playlist.get(1));
assertThat(currentMediaItem.getAllValues().get(0)).isSameInstanceAs(playlist.get(0));
assertThat(currentMediaItem.getAllValues().get(1)).isSameInstanceAs(playlist.get(1));
player.release();
}
@Test
public void seekTo_callsOnPositionDiscontinuity() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
player.setMediaSources(Lists.newArrayList(new FakeMediaSource(), new FakeMediaSource()));
player.setMediaSources(
ImmutableList.of(
createFakeMediaSource(/* id= */ "id-0"), createFakeMediaSource(/* id= */ "id-1")));
player.prepare();
TestPlayerRunHelper.playUntilPosition(
......@@ -10382,16 +10532,20 @@ public final class ExoPlayerTest {
List<Player.PositionInfo> newPositions = newPosition.getAllValues();
assertThat(oldPositions.get(0).windowUid).isEqualTo(newPositions.get(0).windowUid);
assertThat(newPositions.get(0).windowIndex).isEqualTo(0);
assertThat(newPositions.get(0).mediaItem.playbackProperties.tag).isEqualTo("id-0");
assertThat(oldPositions.get(0).positionMs).isIn(Range.closed(4980L, 5000L));
assertThat(oldPositions.get(0).contentPositionMs).isIn(Range.closed(4980L, 5000L));
assertThat(oldPositions.get(0).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(0).mediaItem.playbackProperties.tag).isEqualTo("id-0");
assertThat(newPositions.get(0).positionMs).isEqualTo(7_000);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(7_000);
assertThat(oldPositions.get(1).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(1).windowUid).isNotEqualTo(newPositions.get(1).windowUid);
assertThat(oldPositions.get(1).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(1).mediaItem.playbackProperties.tag).isEqualTo("id-0");
assertThat(oldPositions.get(1).positionMs).isEqualTo(7_000);
assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(7_000);
assertThat(newPositions.get(1).windowIndex).isEqualTo(1);
assertThat(newPositions.get(1).mediaItem.playbackProperties.tag).isEqualTo("id-1");
assertThat(newPositions.get(1).positionMs).isEqualTo(1_000);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(1_000);
player.release();
......@@ -10421,6 +10575,7 @@ public final class ExoPlayerTest {
// a seek from initial state to masked seek position
assertThat(oldPositions.get(0).windowUid).isNull();
assertThat(oldPositions.get(0).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(0).mediaItem).isNull();
assertThat(oldPositions.get(0).positionMs).isEqualTo(0);
assertThat(oldPositions.get(0).contentPositionMs).isEqualTo(0);
assertThat(newPositions.get(0).windowIndex).isEqualTo(0);
......@@ -10430,6 +10585,7 @@ public final class ExoPlayerTest {
// a seek from masked seek position to another masked position across windows
assertThat(oldPositions.get(1).windowUid).isNull();
assertThat(oldPositions.get(1).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(1).mediaItem).isNull();
assertThat(oldPositions.get(1).positionMs).isEqualTo(7_000);
assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(7_000);
assertThat(newPositions.get(1).windowUid).isNull();
......@@ -10439,6 +10595,7 @@ public final class ExoPlayerTest {
// a seek from masked seek position to another masked position within window
assertThat(oldPositions.get(2).windowUid).isNull();
assertThat(oldPositions.get(2).windowIndex).isEqualTo(1);
assertThat(oldPositions.get(2).mediaItem).isNull();
assertThat(oldPositions.get(2).positionMs).isEqualTo(1_000);
assertThat(oldPositions.get(2).contentPositionMs).isEqualTo(1_000);
assertThat(newPositions.get(2).windowUid).isNull();
......@@ -10671,7 +10828,7 @@ public final class ExoPlayerTest {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
player.setMediaSource(new FakeMediaSource());
player.setMediaSource(createFakeMediaSource(/* id= */ 123));
player.prepare();
TestPlayerRunHelper.playUntilPosition(
......@@ -10690,10 +10847,12 @@ public final class ExoPlayerTest {
List<Player.PositionInfo> oldPositions = oldPosition.getAllValues();
List<Player.PositionInfo> newPositions = newPosition.getAllValues();
assertThat(oldPositions.get(0).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(0).mediaItem.playbackProperties.tag).isEqualTo(123);
assertThat(oldPositions.get(0).positionMs).isIn(Range.closed(4980L, 5000L));
assertThat(oldPositions.get(0).contentPositionMs).isIn(Range.closed(4980L, 5000L));
assertThat(newPositions.get(0).windowUid).isNull();
assertThat(newPositions.get(0).windowIndex).isEqualTo(0);
assertThat(newPositions.get(0).mediaItem).isNull();
assertThat(newPositions.get(0).positionMs).isEqualTo(0);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(0);
player.release();
......@@ -10851,6 +11010,11 @@ public final class ExoPlayerTest {
});
}
private static FakeMediaSource createFakeMediaSource(Object id) {
return new FakeMediaSource(
new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */ 1, id)));
}
private static void deliverBroadcast(Intent intent) {
ApplicationProvider.getApplicationContext().sendBroadcast(intent);
shadowOf(Looper.getMainLooper()).idle();
......
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.testutil;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManagerProvider;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
/** Fake {@link MediaSourceFactory} that creates a {@link FakeMediaSource}. */
public class FakeMediaSourceFactory implements MediaSourceFactory {
/** The window UID used by media sources that are created by the factory. */
public static final Object DEFAULT_WINDOW_UID = new Object();
@Override
public MediaSourceFactory setDrmSessionManagerProvider(
@Nullable DrmSessionManagerProvider drmSessionManagerProvider) {
throw new UnsupportedOperationException();
}
@Deprecated
@Override
public MediaSourceFactory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager) {
throw new UnsupportedOperationException();
}
@Deprecated
@Override
public MediaSourceFactory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
throw new UnsupportedOperationException();
}
@Deprecated
@Override
public MediaSourceFactory setDrmUserAgent(@Nullable String userAgent) {
throw new UnsupportedOperationException();
}
@Override
public MediaSourceFactory setLoadErrorHandlingPolicy(
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
throw new UnsupportedOperationException();
}
@Override
public int[] getSupportedTypes() {
return new int[] {C.TYPE_OTHER};
}
@Override
public MediaSource createMediaSource(MediaItem mediaItem) {
TimelineWindowDefinition timelineWindowDefinition =
new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ DEFAULT_WINDOW_UID,
/* isSeekable= */ true,
/* isDynamic= */ false,
/* isLive= */ false,
/* isPlaceholder= */ false,
/* durationUs= */ 1000 * C.MICROS_PER_SECOND,
/* defaultPositionUs= */ 2 * C.MICROS_PER_SECOND,
/* windowOffsetInFirstPeriodUs= */ C.msToUs(123456789),
AdPlaybackState.NONE,
mediaItem);
return new FakeMediaSource(new FakeTimeline(timelineWindowDefinition));
}
}
......@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
......@@ -45,6 +46,7 @@ public class TestExoPlayerBuilder {
private BandwidthMeter bandwidthMeter;
@Nullable private Renderer[] renderers;
@Nullable private RenderersFactory renderersFactory;
@Nullable private MediaSourceFactory mediaSourceFactory;
private boolean useLazyPreparation;
private @MonotonicNonNull Looper looper;
private long seekBackIncrementMs;
......@@ -220,6 +222,26 @@ public class TestExoPlayerBuilder {
}
/**
* Returns the {@link MediaSourceFactory} that will be used by the player, or null if no {@link
* MediaSourceFactory} has been set yet and no default is available.
*/
@Nullable
public MediaSourceFactory getMediaSourceFactory() {
return mediaSourceFactory;
}
/**
* Sets the {@link MediaSourceFactory} to be used by the player.
*
* @param mediaSourceFactory The {@link MediaSourceFactory} to be used by the player.
* @return This builder.
*/
public TestExoPlayerBuilder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
return this;
}
/**
* Sets the seek back increment to be used by the player.
*
* @param seekBackIncrementMs The seek back increment to be used by the player.
......@@ -277,7 +299,8 @@ public class TestExoPlayerBuilder {
};
}
return new ExoPlayer.Builder(context, playerRenderersFactory)
ExoPlayer.Builder builder =
new ExoPlayer.Builder(context, playerRenderersFactory)
.setTrackSelector(trackSelector)
.setLoadControl(loadControl)
.setBandwidthMeter(bandwidthMeter)
......@@ -286,7 +309,10 @@ public class TestExoPlayerBuilder {
.setUseLazyPreparation(useLazyPreparation)
.setLooper(looper)
.setSeekBackIncrementMs(seekBackIncrementMs)
.setSeekForwardIncrementMs(seekForwardIncrementMs)
.build();
.setSeekForwardIncrementMs(seekForwardIncrementMs);
if (mediaSourceFactory != null) {
builder.setMediaSourceFactory(mediaSourceFactory);
}
return builder.build();
}
}
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.testutil;
import static com.google.common.truth.Truth.assertThat;
import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline.Window;
import com.google.android.exoplayer2.source.MediaSource;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link FakeMediaSourceFactory}. */
@RunWith(AndroidJUnit4.class)
public class FakeMediaSourceFactoryTest {
@Test
public void createMediaSource_mediaItemIsSameInstance() {
FakeMediaSourceFactory fakeMediaSourceFactory = new FakeMediaSourceFactory();
MediaItem mediaItem = MediaItem.fromUri("http://google.com/0");
@Nullable AtomicReference<MediaItem> reportedMediaItem = new AtomicReference<>();
MediaSource mediaSource = fakeMediaSourceFactory.createMediaSource(mediaItem);
mediaSource.prepareSource(
(source, timeline) -> {
int firstWindowIndex = timeline.getFirstWindowIndex(/* shuffleModeEnabled= */ false);
reportedMediaItem.set(timeline.getWindow(firstWindowIndex, new Window()).mediaItem);
},
/* mediaTransferListener= */ null);
assertThat(reportedMediaItem.get()).isSameInstanceAs(mediaItem);
assertThat(mediaSource.getMediaItem()).isSameInstanceAs(mediaItem);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment