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 { ...@@ -790,6 +790,7 @@ public final class CastPlayer extends BasePlayer {
new PositionInfo( new PositionInfo(
window.uid, window.uid,
period.windowIndex, period.windowIndex,
window.mediaItem,
period.uid, period.uid,
period.windowIndex, period.windowIndex,
/* positionMs= */ windowDurationMs, /* positionMs= */ windowDurationMs,
...@@ -802,6 +803,7 @@ public final class CastPlayer extends BasePlayer { ...@@ -802,6 +803,7 @@ public final class CastPlayer extends BasePlayer {
new PositionInfo( new PositionInfo(
window.uid, window.uid,
period.windowIndex, period.windowIndex,
window.mediaItem,
period.uid, period.uid,
period.windowIndex, period.windowIndex,
/* positionMs= */ window.getDefaultPositionMs(), /* positionMs= */ window.getDefaultPositionMs(),
...@@ -904,6 +906,7 @@ public final class CastPlayer extends BasePlayer { ...@@ -904,6 +906,7 @@ public final class CastPlayer extends BasePlayer {
new PositionInfo( new PositionInfo(
window.uid, window.uid,
period.windowIndex, period.windowIndex,
window.mediaItem,
period.uid, period.uid,
period.windowIndex, period.windowIndex,
getCurrentPosition(), getCurrentPosition(),
...@@ -1082,17 +1085,19 @@ public final class CastPlayer extends BasePlayer { ...@@ -1082,17 +1085,19 @@ public final class CastPlayer extends BasePlayer {
private PositionInfo getCurrentPositionInfo() { private PositionInfo getCurrentPositionInfo() {
Timeline currentTimeline = getCurrentTimeline(); Timeline currentTimeline = getCurrentTimeline();
@Nullable @Nullable Object newPeriodUid = null;
Object newPeriodUid = @Nullable Object newWindowUid = null;
!currentTimeline.isEmpty() @Nullable MediaItem newMediaItem = null;
? currentTimeline.getPeriod(getCurrentPeriodIndex(), period, /* setIds= */ true).uid if (!currentTimeline.isEmpty()) {
: null; newPeriodUid =
@Nullable currentTimeline.getPeriod(getCurrentPeriodIndex(), period, /* setIds= */ true).uid;
Object newWindowUid = newWindowUid = currentTimeline.getWindow(period.windowIndex, window).uid;
newPeriodUid != null ? currentTimeline.getWindow(period.windowIndex, window).uid : null; newMediaItem = window.mediaItem;
}
return new PositionInfo( return new PositionInfo(
newWindowUid, newWindowUid,
getCurrentWindowIndex(), getCurrentWindowIndex(),
newMediaItem,
newPeriodUid, newPeriodUid,
getCurrentPeriodIndex(), getCurrentPeriodIndex(),
getCurrentPosition(), getCurrentPosition(),
......
...@@ -380,6 +380,7 @@ public class CastPlayerTest { ...@@ -380,6 +380,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 2, /* windowUid= */ 2,
/* windowIndex= */ 1, /* windowIndex= */ 1,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2, /* periodUid= */ 2,
/* periodIndex= */ 1, /* periodIndex= */ 1,
/* positionMs= */ 2000, /* positionMs= */ 2000,
...@@ -390,6 +391,7 @@ public class CastPlayerTest { ...@@ -390,6 +391,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 3, /* windowUid= */ 3,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(3).build(),
/* periodUid= */ 3, /* periodUid= */ 3,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 1000, /* positionMs= */ 1000,
...@@ -660,6 +662,7 @@ public class CastPlayerTest { ...@@ -660,6 +662,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 1234, /* positionMs= */ 1234,
...@@ -670,6 +673,7 @@ public class CastPlayerTest { ...@@ -670,6 +673,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ null, /* windowUid= */ null,
/* windowIndex= */ 0, /* windowIndex= */ 0,
/* mediaItem= */ null,
/* periodUid= */ null, /* periodUid= */ null,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -744,6 +748,7 @@ public class CastPlayerTest { ...@@ -744,6 +748,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 1234, /* positionMs= */ 1234,
...@@ -754,6 +759,7 @@ public class CastPlayerTest { ...@@ -754,6 +759,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 2, /* windowUid= */ 2,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2, /* periodUid= */ 2,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -825,6 +831,7 @@ public class CastPlayerTest { ...@@ -825,6 +831,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, // position at which we receive the timeline change /* positionMs= */ 0, // position at which we receive the timeline change
...@@ -835,6 +842,7 @@ public class CastPlayerTest { ...@@ -835,6 +842,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 2, /* windowUid= */ 2,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2, /* periodUid= */ 2,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -937,6 +945,7 @@ public class CastPlayerTest { ...@@ -937,6 +945,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -947,6 +956,7 @@ public class CastPlayerTest { ...@@ -947,6 +956,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 2, /* windowUid= */ 2,
/* windowIndex= */ 1, /* windowIndex= */ 1,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2, /* periodUid= */ 2,
/* periodIndex= */ 1, /* periodIndex= */ 1,
/* positionMs= */ 1234, /* positionMs= */ 1234,
...@@ -992,10 +1002,12 @@ public class CastPlayerTest { ...@@ -992,10 +1002,12 @@ public class CastPlayerTest {
updateTimeLine(mediaItems, mediaQueueItemIds, /* currentItemId= */ 1); updateTimeLine(mediaItems, mediaQueueItemIds, /* currentItemId= */ 1);
castPlayer.seekTo(/* windowIndex= */ 0, /* positionMs= */ 1234); castPlayer.seekTo(/* windowIndex= */ 0, /* positionMs= */ 1234);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build();
Player.PositionInfo oldPosition = Player.PositionInfo oldPosition =
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -1006,6 +1018,7 @@ public class CastPlayerTest { ...@@ -1006,6 +1018,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 1234, /* positionMs= */ 1234,
...@@ -1076,6 +1089,7 @@ public class CastPlayerTest { ...@@ -1076,6 +1089,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build(),
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 12500, /* positionMs= */ 12500,
...@@ -1086,6 +1100,7 @@ public class CastPlayerTest { ...@@ -1086,6 +1100,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 2, /* windowUid= */ 2,
/* windowIndex= */ 1, /* windowIndex= */ 1,
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(2).build(),
/* periodUid= */ 2, /* periodUid= */ 2,
/* periodIndex= */ 1, /* periodIndex= */ 1,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -1120,10 +1135,12 @@ public class CastPlayerTest { ...@@ -1120,10 +1135,12 @@ public class CastPlayerTest {
mediaItems, mediaQueueItemIds, currentItemId, streamTypes, durationsMs, positionMs); mediaItems, mediaQueueItemIds, currentItemId, streamTypes, durationsMs, positionMs);
castPlayer.seekBack(); castPlayer.seekBack();
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build();
Player.PositionInfo oldPosition = Player.PositionInfo oldPosition =
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 2 * C.DEFAULT_SEEK_BACK_INCREMENT_MS, /* positionMs= */ 2 * C.DEFAULT_SEEK_BACK_INCREMENT_MS,
...@@ -1134,6 +1151,7 @@ public class CastPlayerTest { ...@@ -1134,6 +1151,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ C.DEFAULT_SEEK_BACK_INCREMENT_MS, /* positionMs= */ C.DEFAULT_SEEK_BACK_INCREMENT_MS,
...@@ -1166,10 +1184,12 @@ public class CastPlayerTest { ...@@ -1166,10 +1184,12 @@ public class CastPlayerTest {
mediaItems, mediaQueueItemIds, currentItemId, streamTypes, durationsMs, positionMs); mediaItems, mediaQueueItemIds, currentItemId, streamTypes, durationsMs, positionMs);
castPlayer.seekForward(); castPlayer.seekForward();
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.EMPTY).setTag(1).build();
Player.PositionInfo oldPosition = Player.PositionInfo oldPosition =
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 0, /* positionMs= */ 0,
...@@ -1180,6 +1200,7 @@ public class CastPlayerTest { ...@@ -1180,6 +1200,7 @@ public class CastPlayerTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ 1, /* windowUid= */ 1,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
/* periodUid= */ 1, /* periodUid= */ 1,
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ C.DEFAULT_SEEK_FORWARD_INCREMENT_MS, /* positionMs= */ C.DEFAULT_SEEK_FORWARD_INCREMENT_MS,
......
...@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.ext.ima; ...@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.ext.ima;
import android.os.Looper; import android.os.Looper;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.testutil.StubExoPlayer; import com.google.android.exoplayer2.testutil.StubExoPlayer;
...@@ -32,6 +33,7 @@ import com.google.android.exoplayer2.util.ListenerSet; ...@@ -32,6 +33,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
private final Timeline.Period period; private final Timeline.Period period;
private final Object windowUid = new Object(); private final Object windowUid = new Object();
private final Object periodUid = new Object(); private final Object periodUid = new Object();
private final MediaItem mediaItem = MediaItem.fromUri("http://google.com/0");
private Timeline timeline; private Timeline timeline;
@Player.State private int state; @Player.State private int state;
...@@ -72,6 +74,7 @@ import com.google.android.exoplayer2.util.ListenerSet; ...@@ -72,6 +74,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo( new PositionInfo(
windowUid, windowUid,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
periodUid, periodUid,
/* periodIndex= */ 0, /* periodIndex= */ 0,
this.positionMs, this.positionMs,
...@@ -89,6 +92,7 @@ import com.google.android.exoplayer2.util.ListenerSet; ...@@ -89,6 +92,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo( new PositionInfo(
windowUid, windowUid,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
periodUid, periodUid,
/* periodIndex= */ 0, /* periodIndex= */ 0,
positionMs, positionMs,
...@@ -119,6 +123,7 @@ import com.google.android.exoplayer2.util.ListenerSet; ...@@ -119,6 +123,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo( new PositionInfo(
windowUid, windowUid,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
periodUid, periodUid,
/* periodIndex= */ 0, /* periodIndex= */ 0,
this.positionMs, this.positionMs,
...@@ -136,6 +141,7 @@ import com.google.android.exoplayer2.util.ListenerSet; ...@@ -136,6 +141,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
new PositionInfo( new PositionInfo(
windowUid, windowUid,
/* windowIndex= */ 0, /* windowIndex= */ 0,
mediaItem,
periodUid, periodUid,
/* periodIndex= */ 0, /* periodIndex= */ 0,
positionMs, positionMs,
......
...@@ -56,6 +56,7 @@ import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer; ...@@ -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.ads.interactivemedia.v3.api.player.VideoProgressUpdate;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
...@@ -281,6 +282,7 @@ public final class ImaAdsLoaderTest { ...@@ -281,6 +282,7 @@ public final class ImaAdsLoaderTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ new Object(), /* windowUid= */ new Object(),
/* windowIndex= */ 0, /* windowIndex= */ 0,
/* mediaItem= */ MediaItem.fromUri("http://google.com/0"),
/* periodUid= */ new Object(), /* periodUid= */ new Object(),
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 10_000, /* positionMs= */ 10_000,
...@@ -290,6 +292,7 @@ public final class ImaAdsLoaderTest { ...@@ -290,6 +292,7 @@ public final class ImaAdsLoaderTest {
new Player.PositionInfo( new Player.PositionInfo(
/* windowUid= */ new Object(), /* windowUid= */ new Object(),
/* windowIndex= */ 1, /* windowIndex= */ 1,
/* mediaItem= */ MediaItem.fromUri("http://google.com/1"),
/* periodUid= */ new Object(), /* periodUid= */ new Object(),
/* periodIndex= */ 0, /* periodIndex= */ 0,
/* positionMs= */ 20_000, /* positionMs= */ 20_000,
......
...@@ -32,6 +32,7 @@ import com.google.android.exoplayer2.text.Cue; ...@@ -32,6 +32,7 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; 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.FlagSet;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoSize; import com.google.android.exoplayer2.video.VideoSize;
...@@ -468,13 +469,15 @@ public interface Player { ...@@ -468,13 +469,15 @@ public interface Player {
final class PositionInfo implements Bundleable { 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; @Nullable public final Object windowUid;
/** The window index. */ /** The window index. */
public final int windowIndex; 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; @Nullable public final Object periodUid;
/** The period index. */ /** The period index. */
...@@ -498,10 +501,37 @@ public interface Player { ...@@ -498,10 +501,37 @@ public interface Player {
*/ */
public final int adIndexInAdGroup; 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. */ /** Creates an instance. */
public PositionInfo( public PositionInfo(
@Nullable Object windowUid, @Nullable Object windowUid,
int windowIndex, int windowIndex,
@Nullable MediaItem mediaItem,
@Nullable Object periodUid, @Nullable Object periodUid,
int periodIndex, int periodIndex,
long positionMs, long positionMs,
...@@ -510,6 +540,7 @@ public interface Player { ...@@ -510,6 +540,7 @@ public interface Player {
int adIndexInAdGroup) { int adIndexInAdGroup) {
this.windowUid = windowUid; this.windowUid = windowUid;
this.windowIndex = windowIndex; this.windowIndex = windowIndex;
this.mediaItem = mediaItem;
this.periodUid = periodUid; this.periodUid = periodUid;
this.periodIndex = periodIndex; this.periodIndex = periodIndex;
this.positionMs = positionMs; this.positionMs = positionMs;
...@@ -534,7 +565,8 @@ public interface Player { ...@@ -534,7 +565,8 @@ public interface Player {
&& adGroupIndex == that.adGroupIndex && adGroupIndex == that.adGroupIndex
&& adIndexInAdGroup == that.adIndexInAdGroup && adIndexInAdGroup == that.adIndexInAdGroup
&& Objects.equal(windowUid, that.windowUid) && Objects.equal(windowUid, that.windowUid)
&& Objects.equal(periodUid, that.periodUid); && Objects.equal(periodUid, that.periodUid)
&& Objects.equal(mediaItem, that.mediaItem);
} }
@Override @Override
...@@ -542,6 +574,7 @@ public interface Player { ...@@ -542,6 +574,7 @@ public interface Player {
return Objects.hashCode( return Objects.hashCode(
windowUid, windowUid,
windowIndex, windowIndex,
mediaItem,
periodUid, periodUid,
periodIndex, periodIndex,
windowIndex, windowIndex,
...@@ -556,6 +589,7 @@ public interface Player { ...@@ -556,6 +589,7 @@ public interface Player {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({ @IntDef({
FIELD_WINDOW_INDEX, FIELD_WINDOW_INDEX,
FIELD_MEDIA_ITEM,
FIELD_PERIOD_INDEX, FIELD_PERIOD_INDEX,
FIELD_POSITION_MS, FIELD_POSITION_MS,
FIELD_CONTENT_POSITION_MS, FIELD_CONTENT_POSITION_MS,
...@@ -565,11 +599,12 @@ public interface Player { ...@@ -565,11 +599,12 @@ public interface Player {
private @interface FieldNumber {} private @interface FieldNumber {}
private static final int FIELD_WINDOW_INDEX = 0; private static final int FIELD_WINDOW_INDEX = 0;
private static final int FIELD_PERIOD_INDEX = 1; private static final int FIELD_MEDIA_ITEM = 1;
private static final int FIELD_POSITION_MS = 2; private static final int FIELD_PERIOD_INDEX = 2;
private static final int FIELD_CONTENT_POSITION_MS = 3; private static final int FIELD_POSITION_MS = 3;
private static final int FIELD_AD_GROUP_INDEX = 4; private static final int FIELD_CONTENT_POSITION_MS = 4;
private static final int FIELD_AD_INDEX_IN_AD_GROUP = 5; private static final int FIELD_AD_GROUP_INDEX = 5;
private static final int FIELD_AD_INDEX_IN_AD_GROUP = 6;
/** /**
* {@inheritDoc} * {@inheritDoc}
...@@ -581,6 +616,7 @@ public interface Player { ...@@ -581,6 +616,7 @@ public interface Player {
public Bundle toBundle() { public Bundle toBundle() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt(keyForField(FIELD_WINDOW_INDEX), windowIndex); bundle.putInt(keyForField(FIELD_WINDOW_INDEX), windowIndex);
bundle.putBundle(keyForField(FIELD_MEDIA_ITEM), BundleableUtils.toNullableBundle(mediaItem));
bundle.putInt(keyForField(FIELD_PERIOD_INDEX), periodIndex); bundle.putInt(keyForField(FIELD_PERIOD_INDEX), periodIndex);
bundle.putLong(keyForField(FIELD_POSITION_MS), positionMs); bundle.putLong(keyForField(FIELD_POSITION_MS), positionMs);
bundle.putLong(keyForField(FIELD_CONTENT_POSITION_MS), contentPositionMs); bundle.putLong(keyForField(FIELD_CONTENT_POSITION_MS), contentPositionMs);
...@@ -595,6 +631,10 @@ public interface Player { ...@@ -595,6 +631,10 @@ public interface Player {
private static PositionInfo fromBundle(Bundle bundle) { private static PositionInfo fromBundle(Bundle bundle) {
int windowIndex = int windowIndex =
bundle.getInt(keyForField(FIELD_WINDOW_INDEX), /* defaultValue= */ C.INDEX_UNSET); 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 = int periodIndex =
bundle.getInt(keyForField(FIELD_PERIOD_INDEX), /* defaultValue= */ C.INDEX_UNSET); bundle.getInt(keyForField(FIELD_PERIOD_INDEX), /* defaultValue= */ C.INDEX_UNSET);
long positionMs = long positionMs =
...@@ -608,6 +648,7 @@ public interface Player { ...@@ -608,6 +648,7 @@ public interface Player {
return new PositionInfo( return new PositionInfo(
/* windowUid= */ null, /* windowUid= */ null,
windowIndex, windowIndex,
mediaItem,
/* periodUid= */ null, /* periodUid= */ null,
periodIndex, periodIndex,
positionMs, positionMs,
......
...@@ -32,6 +32,7 @@ public class PositionInfoTest { ...@@ -32,6 +32,7 @@ public class PositionInfoTest {
new PositionInfo( new PositionInfo(
/* windowUid= */ null, /* windowUid= */ null,
/* windowIndex= */ 23, /* windowIndex= */ 23,
new MediaItem.Builder().setMediaId("1234").build(),
/* periodUid= */ null, /* periodUid= */ null,
/* periodIndex= */ 11, /* periodIndex= */ 11,
/* positionMs= */ 8787L, /* positionMs= */ 8787L,
...@@ -48,6 +49,7 @@ public class PositionInfoTest { ...@@ -48,6 +49,7 @@ public class PositionInfoTest {
new PositionInfo( new PositionInfo(
/* windowUid= */ new Object(), /* windowUid= */ new Object(),
/* windowIndex= */ 23, /* windowIndex= */ 23,
MediaItem.fromUri("https://exoplayer.dev"),
/* periodUid= */ null, /* periodUid= */ null,
/* periodIndex= */ 11, /* periodIndex= */ 11,
/* positionMs= */ 8787L, /* positionMs= */ 8787L,
...@@ -65,6 +67,7 @@ public class PositionInfoTest { ...@@ -65,6 +67,7 @@ public class PositionInfoTest {
new PositionInfo( new PositionInfo(
/* windowUid= */ null, /* windowUid= */ null,
/* windowIndex= */ 23, /* windowIndex= */ 23,
MediaItem.fromUri("https://exoplayer.dev"),
/* periodUid= */ new Object(), /* periodUid= */ new Object(),
/* periodIndex= */ 11, /* periodIndex= */ 11,
/* positionMs= */ 8787L, /* positionMs= */ 8787L,
......
...@@ -1360,6 +1360,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -1360,6 +1360,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Nullable Object oldPeriodUid = null; @Nullable Object oldPeriodUid = null;
int oldWindowIndex = oldMaskingWindowIndex; int oldWindowIndex = oldMaskingWindowIndex;
int oldPeriodIndex = C.INDEX_UNSET; int oldPeriodIndex = C.INDEX_UNSET;
@Nullable MediaItem oldMediaItem = null;
Timeline.Period oldPeriod = new Timeline.Period(); Timeline.Period oldPeriod = new Timeline.Period();
if (!oldPlaybackInfo.timeline.isEmpty()) { if (!oldPlaybackInfo.timeline.isEmpty()) {
oldPeriodUid = oldPlaybackInfo.periodId.periodUid; oldPeriodUid = oldPlaybackInfo.periodId.periodUid;
...@@ -1367,6 +1368,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -1367,6 +1368,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
oldWindowIndex = oldPeriod.windowIndex; oldWindowIndex = oldPeriod.windowIndex;
oldPeriodIndex = oldPlaybackInfo.timeline.getIndexOfPeriod(oldPeriodUid); oldPeriodIndex = oldPlaybackInfo.timeline.getIndexOfPeriod(oldPeriodUid);
oldWindowUid = oldPlaybackInfo.timeline.getWindow(oldWindowIndex, window).uid; oldWindowUid = oldPlaybackInfo.timeline.getWindow(oldWindowIndex, window).uid;
oldMediaItem = window.mediaItem;
} }
long oldPositionUs; long oldPositionUs;
long oldContentPositionUs; long oldContentPositionUs;
...@@ -1397,6 +1399,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -1397,6 +1399,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
return new PositionInfo( return new PositionInfo(
oldWindowUid, oldWindowUid,
oldWindowIndex, oldWindowIndex,
oldMediaItem,
oldPeriodUid, oldPeriodUid,
oldPeriodIndex, oldPeriodIndex,
C.usToMs(oldPositionUs), C.usToMs(oldPositionUs),
...@@ -1410,16 +1413,19 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -1410,16 +1413,19 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Nullable Object newPeriodUid = null; @Nullable Object newPeriodUid = null;
int newWindowIndex = getCurrentWindowIndex(); int newWindowIndex = getCurrentWindowIndex();
int newPeriodIndex = C.INDEX_UNSET; int newPeriodIndex = C.INDEX_UNSET;
@Nullable MediaItem newMediaItem = null;
if (!playbackInfo.timeline.isEmpty()) { if (!playbackInfo.timeline.isEmpty()) {
newPeriodUid = playbackInfo.periodId.periodUid; newPeriodUid = playbackInfo.periodId.periodUid;
playbackInfo.timeline.getPeriodByUid(newPeriodUid, period); playbackInfo.timeline.getPeriodByUid(newPeriodUid, period);
newPeriodIndex = playbackInfo.timeline.getIndexOfPeriod(newPeriodUid); newPeriodIndex = playbackInfo.timeline.getIndexOfPeriod(newPeriodUid);
newWindowUid = playbackInfo.timeline.getWindow(newWindowIndex, window).uid; newWindowUid = playbackInfo.timeline.getWindow(newWindowIndex, window).uid;
newMediaItem = window.mediaItem;
} }
long positionMs = C.usToMs(discontinuityWindowStartPositionUs); long positionMs = C.usToMs(discontinuityWindowStartPositionUs);
return new PositionInfo( return new PositionInfo(
newWindowUid, newWindowUid,
newWindowIndex, newWindowIndex,
newMediaItem,
newPeriodUid, newPeriodUid,
newPeriodIndex, newPeriodIndex,
positionMs, positionMs,
......
...@@ -85,6 +85,8 @@ import androidx.annotation.Nullable; ...@@ -85,6 +85,8 @@ import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Player.DiscontinuityReason; 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.Timeline.Window;
import com.google.android.exoplayer2.analytics.AnalyticsListener; import com.google.android.exoplayer2.analytics.AnalyticsListener;
import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioAttributes;
...@@ -120,6 +122,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource; ...@@ -120,6 +122,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.testutil.FakeMediaClockRenderer; import com.google.android.exoplayer2.testutil.FakeMediaClockRenderer;
import com.google.android.exoplayer2.testutil.FakeMediaPeriod; import com.google.android.exoplayer2.testutil.FakeMediaPeriod;
import com.google.android.exoplayer2.testutil.FakeMediaSource; 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.FakeRenderer;
import com.google.android.exoplayer2.testutil.FakeSampleStream; import com.google.android.exoplayer2.testutil.FakeSampleStream;
import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem; import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem;
...@@ -142,7 +145,6 @@ import com.google.android.exoplayer2.util.Clock; ...@@ -142,7 +145,6 @@ import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -9580,6 +9582,7 @@ public final class ExoPlayerTest { ...@@ -9580,6 +9582,7 @@ public final class ExoPlayerTest {
assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid); assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid);
assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex); assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex);
assertThat(oldPositionInfo.windowIndex).isEqualTo(newPositionInfo.windowIndex); assertThat(oldPositionInfo.windowIndex).isEqualTo(newPositionInfo.windowIndex);
assertThat(oldPositionInfo.mediaItem.playbackProperties.tag).isEqualTo(1);
assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid); assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(10_000); assertThat(oldPositionInfo.positionMs).isEqualTo(10_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000); assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000);
...@@ -9601,6 +9604,7 @@ public final class ExoPlayerTest { ...@@ -9601,6 +9604,7 @@ public final class ExoPlayerTest {
assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid); assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid);
assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex); assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex);
assertThat(oldPositionInfo.windowIndex).isEqualTo(newPositionInfo.windowIndex); assertThat(oldPositionInfo.windowIndex).isEqualTo(newPositionInfo.windowIndex);
assertThat(oldPositionInfo.mediaItem.playbackProperties.tag).isEqualTo(1);
assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid); assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(10_000); assertThat(oldPositionInfo.positionMs).isEqualTo(10_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000); assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000);
...@@ -9620,6 +9624,7 @@ public final class ExoPlayerTest { ...@@ -9620,6 +9624,7 @@ public final class ExoPlayerTest {
oldPositionInfo = oldPosition.getValue(); oldPositionInfo = oldPosition.getValue();
newPositionInfo = newPosition.getValue(); newPositionInfo = newPosition.getValue();
assertThat(oldPositionInfo.windowIndex).isEqualTo(1); assertThat(oldPositionInfo.windowIndex).isEqualTo(1);
assertThat(oldPositionInfo.mediaItem.playbackProperties.tag).isEqualTo(2);
assertThat(oldPositionInfo.windowUid).isNotEqualTo(newPositionInfo.windowUid); assertThat(oldPositionInfo.windowUid).isNotEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(20_000); assertThat(oldPositionInfo.positionMs).isEqualTo(20_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(20_000); assertThat(oldPositionInfo.contentPositionMs).isEqualTo(20_000);
...@@ -9881,7 +9886,7 @@ public final class ExoPlayerTest { ...@@ -9881,7 +9886,7 @@ public final class ExoPlayerTest {
TimelineWindowDefinition postRollWindow = TimelineWindowDefinition postRollWindow =
new TimelineWindowDefinition( new TimelineWindowDefinition(
/* periodCount= */ 1, /* periodCount= */ 1,
/* id= */ 0, /* id= */ "id-2",
/* isSeekable= */ true, /* isSeekable= */ true,
/* isDynamic= */ false, /* isDynamic= */ false,
/* isLive= */ false, /* isLive= */ false,
...@@ -9895,7 +9900,7 @@ public final class ExoPlayerTest { ...@@ -9895,7 +9900,7 @@ public final class ExoPlayerTest {
TimelineWindowDefinition preRollWindow = TimelineWindowDefinition preRollWindow =
new TimelineWindowDefinition( new TimelineWindowDefinition(
/* periodCount= */ 1, /* periodCount= */ 1,
/* id= */ 0, /* id= */ "id-3",
/* isSeekable= */ true, /* isSeekable= */ true,
/* isDynamic= */ false, /* isDynamic= */ false,
/* isLive= */ false, /* isLive= */ false,
...@@ -9905,11 +9910,13 @@ public final class ExoPlayerTest { ...@@ -9905,11 +9910,13 @@ public final class ExoPlayerTest {
/* windowOffsetInFirstPeriodUs= */ 0, /* windowOffsetInFirstPeriodUs= */ 0,
preRollAdPlaybackState); preRollAdPlaybackState);
player.setMediaSources( player.setMediaSources(
Lists.newArrayList( ImmutableList.of(
new FakeMediaSource(), createFakeMediaSource(/* id= */ "id-0"),
new FakeMediaSource( new FakeMediaSource(
new FakeTimeline( new FakeTimeline(
new TimelineWindowDefinition( new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ "id-1",
/* isSeekable= */ true, /* isSeekable= */ true,
/* isDynamic= */ false, /* isDynamic= */ false,
/* durationUs= */ 15 * C.MICROS_PER_SECOND))), /* durationUs= */ 15 * C.MICROS_PER_SECOND))),
...@@ -9939,6 +9946,7 @@ public final class ExoPlayerTest { ...@@ -9939,6 +9946,7 @@ public final class ExoPlayerTest {
assertThat(oldPosition.getValue().windowUid) assertThat(oldPosition.getValue().windowUid)
.isEqualTo(player.getCurrentTimeline().getWindow(0, window).uid); .isEqualTo(player.getCurrentTimeline().getWindow(0, window).uid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(0); 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().positionMs).isEqualTo(10_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(10_000); assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(10_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
...@@ -9946,6 +9954,7 @@ public final class ExoPlayerTest { ...@@ -9946,6 +9954,7 @@ public final class ExoPlayerTest {
assertThat(newPosition.getValue().windowUid) assertThat(newPosition.getValue().windowUid)
.isEqualTo(player.getCurrentTimeline().getWindow(1, window).uid); .isEqualTo(player.getCurrentTimeline().getWindow(1, window).uid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(1); assertThat(newPosition.getValue().windowIndex).isEqualTo(1);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-1");
assertThat(newPosition.getValue().positionMs).isEqualTo(0); assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0); assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
...@@ -9965,11 +9974,13 @@ public final class ExoPlayerTest { ...@@ -9965,11 +9974,13 @@ public final class ExoPlayerTest {
assertThat(newPosition.getValue().windowUid) assertThat(newPosition.getValue().windowUid)
.isEqualTo(player.getCurrentTimeline().getWindow(2, window).uid); .isEqualTo(player.getCurrentTimeline().getWindow(2, window).uid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(1); 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().positionMs).isEqualTo(15_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(15_000); assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(15_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1); assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1);
assertThat(newPosition.getValue().windowIndex).isEqualTo(2); assertThat(newPosition.getValue().windowIndex).isEqualTo(2);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(newPosition.getValue().positionMs).isEqualTo(0); assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0); assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
...@@ -9983,12 +9994,14 @@ public final class ExoPlayerTest { ...@@ -9983,12 +9994,14 @@ public final class ExoPlayerTest {
newPosition.capture(), newPosition.capture(),
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION)); eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(oldPosition.getValue().windowIndex).isEqualTo(2); assertThat(oldPosition.getValue().windowIndex).isEqualTo(2);
assertThat(oldPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid); assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().positionMs).isEqualTo(20_000); assertThat(oldPosition.getValue().positionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000); assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1); assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1);
assertThat(newPosition.getValue().windowIndex).isEqualTo(2); assertThat(newPosition.getValue().windowIndex).isEqualTo(2);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-2");
assertThat(newPosition.getValue().positionMs).isEqualTo(0); assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(20_000); assertThat(newPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(0); assertThat(newPosition.getValue().adGroupIndex).isEqualTo(0);
...@@ -10003,12 +10016,14 @@ public final class ExoPlayerTest { ...@@ -10003,12 +10016,14 @@ public final class ExoPlayerTest {
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION)); eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid); assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(2); 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().positionMs).isEqualTo(5_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000); assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(0); assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(0);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(0); assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(0);
assertThat(newPosition.getValue().windowUid).isEqualTo(oldPosition.getValue().windowUid); assertThat(newPosition.getValue().windowUid).isEqualTo(oldPosition.getValue().windowUid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(2); 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().positionMs).isEqualTo(19_999);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(19_999); assertThat(newPosition.getValue().contentPositionMs).isEqualTo(19_999);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
...@@ -10026,12 +10041,14 @@ public final class ExoPlayerTest { ...@@ -10026,12 +10041,14 @@ public final class ExoPlayerTest {
.onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_AUTO)); .onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_AUTO));
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid); assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(2); 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().positionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000); assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(20_000);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(-1);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1); assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(-1);
assertThat(newPosition.getValue().windowUid).isNotEqualTo(oldPosition.getValue().windowUid); assertThat(newPosition.getValue().windowUid).isNotEqualTo(oldPosition.getValue().windowUid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(3); assertThat(newPosition.getValue().windowIndex).isEqualTo(3);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-3");
assertThat(newPosition.getValue().positionMs).isEqualTo(0); assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0); assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(0); assertThat(newPosition.getValue().adGroupIndex).isEqualTo(0);
...@@ -10046,12 +10063,14 @@ public final class ExoPlayerTest { ...@@ -10046,12 +10063,14 @@ public final class ExoPlayerTest {
eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION)); eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid); assertThat(oldPosition.getValue().windowUid).isEqualTo(lastNewWindowUid);
assertThat(oldPosition.getValue().windowIndex).isEqualTo(3); 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().positionMs).isEqualTo(5_000);
assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(0); assertThat(oldPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(0); assertThat(oldPosition.getValue().adGroupIndex).isEqualTo(0);
assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(0); assertThat(oldPosition.getValue().adIndexInAdGroup).isEqualTo(0);
assertThat(newPosition.getValue().windowUid).isEqualTo(oldPosition.getValue().windowUid); assertThat(newPosition.getValue().windowUid).isEqualTo(oldPosition.getValue().windowUid);
assertThat(newPosition.getValue().windowIndex).isEqualTo(3); assertThat(newPosition.getValue().windowIndex).isEqualTo(3);
assertThat(newPosition.getValue().mediaItem.playbackProperties.tag).isEqualTo("id-3");
assertThat(newPosition.getValue().positionMs).isEqualTo(0); assertThat(newPosition.getValue().positionMs).isEqualTo(0);
assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0); assertThat(newPosition.getValue().contentPositionMs).isEqualTo(0);
assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1); assertThat(newPosition.getValue().adGroupIndex).isEqualTo(-1);
...@@ -10093,7 +10112,7 @@ public final class ExoPlayerTest { ...@@ -10093,7 +10112,7 @@ public final class ExoPlayerTest {
player.prepare(); player.prepare();
TestPlayerRunHelper.playUntilPosition( TestPlayerRunHelper.playUntilPosition(
player, /* windowIndex= */ 0, /* positionMs= */ 5 * C.MILLIS_PER_SECOND); player, /* windowIndex= */ 0, /* positionMs= */ 5 * C.MILLIS_PER_SECOND);
player.setMediaSources(Lists.newArrayList(secondMediaSource, secondMediaSource)); player.setMediaSources(ImmutableList.of(secondMediaSource, secondMediaSource));
player.play(); player.play();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED); TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
...@@ -10121,13 +10140,80 @@ public final class ExoPlayerTest { ...@@ -10121,13 +10140,80 @@ public final class ExoPlayerTest {
} }
@Test @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() public void removeMediaItems_removesPlayingPeriod_callsOnPositionDiscontinuity()
throws Exception { throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build(); ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class); Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener); player.addListener(listener);
player.setMediaSources( player.setMediaSources(
Lists.newArrayList( ImmutableList.of(
new FakeMediaSource( new FakeMediaSource(
new FakeTimeline( new FakeTimeline(
new TimelineWindowDefinition( new TimelineWindowDefinition(
...@@ -10355,11 +10441,75 @@ public final class ExoPlayerTest { ...@@ -10355,11 +10441,75 @@ public final class ExoPlayerTest {
} }
@Test @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 { public void seekTo_callsOnPositionDiscontinuity() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build(); ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class); Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener); 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(); player.prepare();
TestPlayerRunHelper.playUntilPosition( TestPlayerRunHelper.playUntilPosition(
...@@ -10382,16 +10532,20 @@ public final class ExoPlayerTest { ...@@ -10382,16 +10532,20 @@ public final class ExoPlayerTest {
List<Player.PositionInfo> newPositions = newPosition.getAllValues(); List<Player.PositionInfo> newPositions = newPosition.getAllValues();
assertThat(oldPositions.get(0).windowUid).isEqualTo(newPositions.get(0).windowUid); assertThat(oldPositions.get(0).windowUid).isEqualTo(newPositions.get(0).windowUid);
assertThat(newPositions.get(0).windowIndex).isEqualTo(0); 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).positionMs).isIn(Range.closed(4980L, 5000L));
assertThat(oldPositions.get(0).contentPositionMs).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).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).positionMs).isEqualTo(7_000);
assertThat(newPositions.get(0).contentPositionMs).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).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).positionMs).isEqualTo(7_000);
assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(7_000); assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(7_000);
assertThat(newPositions.get(1).windowIndex).isEqualTo(1); 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).positionMs).isEqualTo(1_000);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(1_000); assertThat(newPositions.get(1).contentPositionMs).isEqualTo(1_000);
player.release(); player.release();
...@@ -10421,6 +10575,7 @@ public final class ExoPlayerTest { ...@@ -10421,6 +10575,7 @@ public final class ExoPlayerTest {
// a seek from initial state to masked seek position // a seek from initial state to masked seek position
assertThat(oldPositions.get(0).windowUid).isNull(); assertThat(oldPositions.get(0).windowUid).isNull();
assertThat(oldPositions.get(0).windowIndex).isEqualTo(0); assertThat(oldPositions.get(0).windowIndex).isEqualTo(0);
assertThat(oldPositions.get(0).mediaItem).isNull();
assertThat(oldPositions.get(0).positionMs).isEqualTo(0); assertThat(oldPositions.get(0).positionMs).isEqualTo(0);
assertThat(oldPositions.get(0).contentPositionMs).isEqualTo(0); assertThat(oldPositions.get(0).contentPositionMs).isEqualTo(0);
assertThat(newPositions.get(0).windowIndex).isEqualTo(0); assertThat(newPositions.get(0).windowIndex).isEqualTo(0);
...@@ -10430,6 +10585,7 @@ public final class ExoPlayerTest { ...@@ -10430,6 +10585,7 @@ public final class ExoPlayerTest {
// a seek from masked seek position to another masked position across windows // a seek from masked seek position to another masked position across windows
assertThat(oldPositions.get(1).windowUid).isNull(); assertThat(oldPositions.get(1).windowUid).isNull();
assertThat(oldPositions.get(1).windowIndex).isEqualTo(0); 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).positionMs).isEqualTo(7_000);
assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(7_000); assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(7_000);
assertThat(newPositions.get(1).windowUid).isNull(); assertThat(newPositions.get(1).windowUid).isNull();
...@@ -10439,6 +10595,7 @@ public final class ExoPlayerTest { ...@@ -10439,6 +10595,7 @@ public final class ExoPlayerTest {
// a seek from masked seek position to another masked position within window // a seek from masked seek position to another masked position within window
assertThat(oldPositions.get(2).windowUid).isNull(); assertThat(oldPositions.get(2).windowUid).isNull();
assertThat(oldPositions.get(2).windowIndex).isEqualTo(1); 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).positionMs).isEqualTo(1_000);
assertThat(oldPositions.get(2).contentPositionMs).isEqualTo(1_000); assertThat(oldPositions.get(2).contentPositionMs).isEqualTo(1_000);
assertThat(newPositions.get(2).windowUid).isNull(); assertThat(newPositions.get(2).windowUid).isNull();
...@@ -10671,7 +10828,7 @@ public final class ExoPlayerTest { ...@@ -10671,7 +10828,7 @@ public final class ExoPlayerTest {
ExoPlayer player = new TestExoPlayerBuilder(context).build(); ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class); Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener); player.addListener(listener);
player.setMediaSource(new FakeMediaSource()); player.setMediaSource(createFakeMediaSource(/* id= */ 123));
player.prepare(); player.prepare();
TestPlayerRunHelper.playUntilPosition( TestPlayerRunHelper.playUntilPosition(
...@@ -10690,10 +10847,12 @@ public final class ExoPlayerTest { ...@@ -10690,10 +10847,12 @@ public final class ExoPlayerTest {
List<Player.PositionInfo> oldPositions = oldPosition.getAllValues(); List<Player.PositionInfo> oldPositions = oldPosition.getAllValues();
List<Player.PositionInfo> newPositions = newPosition.getAllValues(); List<Player.PositionInfo> newPositions = newPosition.getAllValues();
assertThat(oldPositions.get(0).windowIndex).isEqualTo(0); 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).positionMs).isIn(Range.closed(4980L, 5000L));
assertThat(oldPositions.get(0).contentPositionMs).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).windowUid).isNull();
assertThat(newPositions.get(0).windowIndex).isEqualTo(0); assertThat(newPositions.get(0).windowIndex).isEqualTo(0);
assertThat(newPositions.get(0).mediaItem).isNull();
assertThat(newPositions.get(0).positionMs).isEqualTo(0); assertThat(newPositions.get(0).positionMs).isEqualTo(0);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(0); assertThat(newPositions.get(0).contentPositionMs).isEqualTo(0);
player.release(); player.release();
...@@ -10851,6 +11010,11 @@ public final class ExoPlayerTest { ...@@ -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) { private static void deliverBroadcast(Intent intent) {
ApplicationProvider.getApplicationContext().sendBroadcast(intent); ApplicationProvider.getApplicationContext().sendBroadcast(intent);
shadowOf(Looper.getMainLooper()).idle(); 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; ...@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.analytics.AnalyticsCollector; 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.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
...@@ -45,6 +46,7 @@ public class TestExoPlayerBuilder { ...@@ -45,6 +46,7 @@ public class TestExoPlayerBuilder {
private BandwidthMeter bandwidthMeter; private BandwidthMeter bandwidthMeter;
@Nullable private Renderer[] renderers; @Nullable private Renderer[] renderers;
@Nullable private RenderersFactory renderersFactory; @Nullable private RenderersFactory renderersFactory;
@Nullable private MediaSourceFactory mediaSourceFactory;
private boolean useLazyPreparation; private boolean useLazyPreparation;
private @MonotonicNonNull Looper looper; private @MonotonicNonNull Looper looper;
private long seekBackIncrementMs; private long seekBackIncrementMs;
...@@ -220,6 +222,26 @@ public class TestExoPlayerBuilder { ...@@ -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. * Sets the seek back increment to be used by the player.
* *
* @param seekBackIncrementMs The seek back increment to be used by the player. * @param seekBackIncrementMs The seek back increment to be used by the player.
...@@ -277,16 +299,20 @@ public class TestExoPlayerBuilder { ...@@ -277,16 +299,20 @@ public class TestExoPlayerBuilder {
}; };
} }
return new ExoPlayer.Builder(context, playerRenderersFactory) ExoPlayer.Builder builder =
.setTrackSelector(trackSelector) new ExoPlayer.Builder(context, playerRenderersFactory)
.setLoadControl(loadControl) .setTrackSelector(trackSelector)
.setBandwidthMeter(bandwidthMeter) .setLoadControl(loadControl)
.setAnalyticsCollector(new AnalyticsCollector(clock)) .setBandwidthMeter(bandwidthMeter)
.setClock(clock) .setAnalyticsCollector(new AnalyticsCollector(clock))
.setUseLazyPreparation(useLazyPreparation) .setClock(clock)
.setLooper(looper) .setUseLazyPreparation(useLazyPreparation)
.setSeekBackIncrementMs(seekBackIncrementMs) .setLooper(looper)
.setSeekForwardIncrementMs(seekForwardIncrementMs) .setSeekBackIncrementMs(seekBackIncrementMs)
.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