diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index ca0ec0b6a0e..77ca6cf249e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -61,6 +61,7 @@ import static com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition.DEFAULT_WINDOW_DURATION_US; import static com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; import static com.google.android.exoplayer2.testutil.TestUtil.assertTimelinesSame; +import static com.google.android.exoplayer2.testutil.TestUtil.timelinesAreSame; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertThrows; @@ -140,7 +141,6 @@ import com.google.android.exoplayer2.testutil.FakeTrackSelection; import com.google.android.exoplayer2.testutil.FakeTrackSelector; import com.google.android.exoplayer2.testutil.FakeVideoRenderer; -import com.google.android.exoplayer2.testutil.NoUidTimeline; import com.google.android.exoplayer2.testutil.TestExoPlayerBuilder; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.upstream.Allocation; @@ -12247,6 +12247,6 @@ public Loader.LoadErrorAction onLoadError( * Returns an argument matcher for {@link Timeline} instances that ignores period and window uids. */ private static ArgumentMatcher noUid(Timeline timeline) { - return argument -> new NoUidTimeline(timeline).equals(new NoUidTimeline(argument)); + return argument -> timelinesAreSame(argument, timeline); } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java index 43a6f5120f0..fe81ebf4cbd 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.testutil; +import static com.google.android.exoplayer2.testutil.TestUtil.timelinesAreSame; + import android.os.Looper; import android.view.Surface; import androidx.annotation.Nullable; @@ -763,7 +765,7 @@ public WaitForTimelineChanged( @Nullable Timeline expectedTimeline, @Player.TimelineChangeReason int expectedReason) { super(tag, "WaitForTimelineChanged"); - this.expectedTimeline = expectedTimeline != null ? new NoUidTimeline(expectedTimeline) : null; + this.expectedTimeline = expectedTimeline; this.ignoreExpectedReason = false; this.expectedReason = expectedReason; } @@ -795,7 +797,7 @@ protected void doActionAndScheduleNextImpl( @Override public void onTimelineChanged( Timeline timeline, @Player.TimelineChangeReason int reason) { - if ((expectedTimeline == null || new NoUidTimeline(timeline).equals(expectedTimeline)) + if ((expectedTimeline == null || timelinesAreSame(timeline, expectedTimeline)) && (ignoreExpectedReason || expectedReason == reason)) { player.removeListener(this); nextAction.schedule(player, trackSelector, surface, handler); @@ -803,8 +805,8 @@ public void onTimelineChanged( } }; player.addListener(listener); - Timeline currentTimeline = new NoUidTimeline(player.getCurrentTimeline()); - if (currentTimeline.equals(expectedTimeline)) { + if (expectedTimeline != null + && timelinesAreSame(player.getCurrentTimeline(), expectedTimeline)) { player.removeListener(listener); nextAction.schedule(player, trackSelector, surface, handler); } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java index 1a305f0e353..5ff9bd3d596 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java @@ -42,6 +42,7 @@ import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.MimeTypes; +import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -534,11 +535,8 @@ public ExoPlayerTestRunner blockUntilActionScheduleFinished(long timeoutMs) * @param timelines A list of expected {@link Timeline}s. */ public void assertTimelinesSame(Timeline... timelines) { - assertThat(this.timelines).hasSize(timelines.length); - for (int i = 0; i < timelines.length; i++) { - assertThat(new NoUidTimeline(timelines[i])) - .isEqualTo(new NoUidTimeline(this.timelines.get(i))); - } + TestUtil.assertTimelinesSame( + ImmutableList.copyOf(this.timelines), ImmutableList.copyOf(timelines)); } /** diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/NoUidTimeline.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/NoUidTimeline.java deleted file mode 100644 index e9e5a7b1279..00000000000 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/NoUidTimeline.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2019 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 com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.source.ForwardingTimeline; - -/** - * A timeline which wraps another timeline and overrides all window and period uids to 0. This is - * useful for testing timeline equality without taking uids into account. - */ -public class NoUidTimeline extends ForwardingTimeline { - - /** - * Creates an instance. - * - * @param timeline The underlying timeline. - */ - public NoUidTimeline(Timeline timeline) { - super(timeline); - } - - @Override - public Window getWindow(int windowIndex, Window window, long defaultPositionProjectionUs) { - timeline.getWindow(windowIndex, window, defaultPositionProjectionUs); - window.uid = 0; - return window; - } - - @Override - public Period getPeriod(int periodIndex, Period period, boolean setIds) { - timeline.getPeriod(periodIndex, period, setIds); - period.uid = 0; - return period; - } -} diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java index 093a65dfccb..ea9b018da0e 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java @@ -43,6 +43,7 @@ import com.google.android.exoplayer2.util.Util; import com.google.common.collect.ImmutableList; import com.google.common.primitives.Bytes; +import com.google.common.truth.Correspondence; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -205,11 +206,20 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { */ public static void assertTimelinesSame( List actualTimelines, List expectedTimelines) { - assertThat(actualTimelines).hasSize(expectedTimelines.size()); - for (int i = 0; i < actualTimelines.size(); i++) { - assertThat(new NoUidTimeline(actualTimelines.get(i))) - .isEqualTo(new NoUidTimeline(expectedTimelines.get(i))); - } + assertThat(actualTimelines) + .comparingElementsUsing( + Correspondence.from( + TestUtil::timelinesAreSame, "is equal to (ignoring Window.uid and Period.uid)")) + .containsExactlyElementsIn(expectedTimelines) + .inOrder(); + } + + /** + * Returns true if {@code thisTimeline} is equal to {@code thatTimeline}, ignoring {@link + * Timeline.Window#uid} and {@link Timeline.Period#uid} values. + */ + public static boolean timelinesAreSame(Timeline thisTimeline, Timeline thatTimeline) { + return new NoUidTimeline(thisTimeline).equals(new NoUidTimeline(thatTimeline)); } /** @@ -492,4 +502,47 @@ public static List getPublicMethods(Class clazz) { return list; } + + private static final class NoUidTimeline extends Timeline { + + private final Timeline delegate; + + public NoUidTimeline(Timeline timeline) { + this.delegate = timeline; + } + + @Override + public int getWindowCount() { + return delegate.getWindowCount(); + } + + @Override + public Window getWindow(int windowIndex, Window window, long defaultPositionProjectionUs) { + delegate.getWindow(windowIndex, window, defaultPositionProjectionUs); + window.uid = 0; + return window; + } + + @Override + public int getPeriodCount() { + return delegate.getPeriodCount(); + } + + @Override + public Period getPeriod(int periodIndex, Period period, boolean setIds) { + delegate.getPeriod(periodIndex, period, setIds); + period.uid = 0; + return period; + } + + @Override + public int getIndexOfPeriod(Object uid) { + return delegate.getIndexOfPeriod(uid); + } + + @Override + public Object getUidOfPeriod(int periodIndex) { + return 0; + } + } }