From fb73a9dfc8c60177e360c31b0a77e697d5b9bb53 Mon Sep 17 00:00:00 2001 From: bachinger Date: Wed, 3 Jun 2020 15:37:44 +0100 Subject: [PATCH] Make media item of Timeline.Window non-null This change makes the media item of Timeline.Window non-null by providing a fallback media item in window.set(...). After having migrated all media sources this should not be needed anymore, but a fallback makes it more safe than just making the mediaItem argument of window.set(...) non-null (which is done in a following CL in this chain of CLs). PiperOrigin-RevId: 314527983 --- .../google/android/exoplayer2/Timeline.java | 24 ++++++++++++------- .../android/exoplayer2/TimelineTest.java | 16 ++++++++----- .../source/SinglePeriodTimelineTest.java | 5 ++-- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java b/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java index c3d9cab7ab..7e22671f00 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Timeline.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2; +import android.net.Uri; import android.os.SystemClock; import android.util.Pair; import androidx.annotation.Nullable; @@ -123,6 +124,12 @@ public abstract class Timeline { */ public static final Object SINGLE_WINDOW_UID = new Object(); + private static final MediaItem DUMMY_MEDIA_ITEM = + new MediaItem.Builder() + .setMediaId("com.google.android.exoplayer2.Timeline") + .setUri(Uri.EMPTY) + .build(); + /** * A unique identifier for the window. Single-window {@link Timeline Timelines} must use {@link * #SINGLE_WINDOW_UID}. @@ -133,7 +140,7 @@ public abstract class Timeline { @Deprecated @Nullable public Object tag; /** The {@link MediaItem} associated to the window. Not necessarily unique. */ - @Nullable public MediaItem mediaItem; + public MediaItem mediaItem; /** The manifest of the window. May be {@code null}. */ @Nullable public Object manifest; @@ -215,13 +222,13 @@ public abstract class Timeline { /** Creates window. */ public Window() { uid = SINGLE_WINDOW_UID; + mediaItem = DUMMY_MEDIA_ITEM; } /** * @deprecated Use {@link #set(Object, MediaItem, Object, long, long, long, boolean, boolean, * boolean, long, long, int, int, long)} instead. */ - @SuppressWarnings("deprecation") @Deprecated public Window set( Object uid, @@ -240,7 +247,7 @@ public abstract class Timeline { long positionInFirstPeriodUs) { set( uid, - /* mediaItem= */ null, + DUMMY_MEDIA_ITEM.buildUpon().setTag(tag).build(), manifest, presentationStartTimeMs, windowStartTimeMs, @@ -253,7 +260,6 @@ public abstract class Timeline { firstPeriodIndex, lastPeriodIndex, positionInFirstPeriodUs); - this.tag = tag; return this; } @@ -275,7 +281,7 @@ public abstract class Timeline { int lastPeriodIndex, long positionInFirstPeriodUs) { this.uid = uid; - this.mediaItem = mediaItem; + this.mediaItem = mediaItem != null ? mediaItem : DUMMY_MEDIA_ITEM; this.tag = mediaItem != null && mediaItem.playbackProperties != null ? mediaItem.playbackProperties.tag @@ -356,6 +362,7 @@ public abstract class Timeline { return Util.getNowUnixTimeMs(elapsedRealtimeEpochOffsetMs); } + // Provide backward compatibility for tag. @Override public boolean equals(@Nullable Object obj) { if (this == obj) { @@ -366,7 +373,6 @@ public abstract class Timeline { } Window that = (Window) obj; return Util.areEqual(uid, that.uid) - && Util.areEqual(tag, that.tag) && Util.areEqual(mediaItem, that.mediaItem) && Util.areEqual(manifest, that.manifest) && presentationStartTimeMs == that.presentationStartTimeMs @@ -383,12 +389,12 @@ public abstract class Timeline { && positionInFirstPeriodUs == that.positionInFirstPeriodUs; } + // Provide backward compatibility for tag. @Override public int hashCode() { int result = 7; result = 31 * result + uid.hashCode(); - result = 31 * result + (tag == null ? 0 : tag.hashCode()); - result = 31 * result + (mediaItem == null ? 0 : mediaItem.hashCode()); + result = 31 * result + mediaItem.hashCode(); result = 31 * result + (manifest == null ? 0 : manifest.hashCode()); result = 31 * result + (int) (presentationStartTimeMs ^ (presentationStartTimeMs >>> 32)); result = 31 * result + (int) (windowStartTimeMs ^ (windowStartTimeMs >>> 32)); @@ -688,7 +694,7 @@ public abstract class Timeline { result = 31 * result + windowIndex; result = 31 * result + (int) (durationUs ^ (durationUs >>> 32)); result = 31 * result + (int) (positionInWindowUs ^ (positionInWindowUs >>> 32)); - result = 31 * result + (adPlaybackState == null ? 0 : adPlaybackState.hashCode()); + result = 31 * result + adPlaybackState.hashCode(); return result; } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/TimelineTest.java b/library/core/src/test/java/com/google/android/exoplayer2/TimelineTest.java index a151507db4..06fb452444 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/TimelineTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/TimelineTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2; import static com.google.common.truth.Truth.assertThat; +import android.net.Uri; import androidx.annotation.Nullable; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.testutil.FakeTimeline; @@ -62,7 +63,6 @@ public class TimelineTest { TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 0); } - @SuppressWarnings("deprecation") // Tests the deprecated window.tag property. @Test public void windowEquals() { MediaItem mediaItem = new MediaItem.Builder().setUri("uri").setTag(new Object()).build(); @@ -73,10 +73,6 @@ public class TimelineTest { otherWindow.mediaItem = mediaItem; assertThat(window).isNotEqualTo(otherWindow); - otherWindow = new Timeline.Window(); - otherWindow.tag = mediaItem.playbackProperties.tag; - assertThat(window).isNotEqualTo(otherWindow); - otherWindow = new Timeline.Window(); otherWindow.manifest = new Object(); assertThat(window).isNotEqualTo(otherWindow); @@ -148,7 +144,15 @@ public class TimelineTest { @SuppressWarnings("deprecation") @Test public void windowSet_withTag() { - Timeline.Window window = populateWindow(/* mediaItem= */ null, new Object()); + Object tag = new Object(); + Timeline.Window window = + populateWindow( + new MediaItem.Builder() + .setMediaId("com.google.android.exoplayer2.Timeline") + .setUri(Uri.EMPTY) + .setTag(tag) + .build(), + tag); Timeline.Window otherWindow = new Timeline.Window(); otherWindow = otherWindow.set( diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java index bc3713379c..ea0b9f1538 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/SinglePeriodTimelineTest.java @@ -108,7 +108,7 @@ public final class SinglePeriodTimelineTest { } @Test - public void setNullMediaItem_returnsNullMediaItem_butUsesDefaultUid() { + public void setNullMediaItem_returnsFallbackMediaItem_butUsesDefaultUid() { SinglePeriodTimeline timeline = new SinglePeriodTimeline( /* durationUs= */ C.TIME_UNSET, @@ -118,7 +118,8 @@ public final class SinglePeriodTimelineTest { /* manifest= */ null, /* mediaItem= */ null); - assertThat(timeline.getWindow(/* windowIndex= */ 0, window).mediaItem).isNull(); + assertThat(timeline.getWindow(/* windowIndex= */ 0, window).mediaItem.mediaId) + .isEqualTo("com.google.android.exoplayer2.Timeline"); assertThat(timeline.getPeriod(/* periodIndex= */ 0, period, /* setIds= */ false).id).isNull(); assertThat(timeline.getPeriod(/* periodIndex= */ 0, period, /* setIds= */ true).id).isNull(); assertThat(timeline.getPeriod(/* periodIndex= */ 0, period, /* setIds= */ false).uid).isNull();