Use a helper function and Truth Correspondence instead of NoUidTimeline

NoUidTimeline still exists as a private detail of TestUtil, but it no
longer extends ForwardingTimeline because the interactions are quite
hard to reason about.

#minor-release

PiperOrigin-RevId: 457703593
This commit is contained in:
ibaker 2022-06-28 12:15:03 +00:00 committed by Marc Baechinger
parent b7b5f20e59
commit 2a2d9e360b
5 changed files with 69 additions and 67 deletions

View File

@ -53,6 +53,7 @@ import static androidx.media3.test.utils.FakeSampleStream.FakeSampleStreamItem.o
import static androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition.DEFAULT_WINDOW_DURATION_US;
import static androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
import static androidx.media3.test.utils.TestUtil.assertTimelinesSame;
import static androidx.media3.test.utils.TestUtil.timelinesAreSame;
import static androidx.media3.test.utils.robolectric.RobolectricUtil.runMainLooperUntil;
import static androidx.media3.test.utils.robolectric.TestPlayerRunHelper.playUntilPosition;
import static androidx.media3.test.utils.robolectric.TestPlayerRunHelper.playUntilStartOfMediaItem;
@ -156,7 +157,6 @@ import androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition;
import androidx.media3.test.utils.FakeTrackSelection;
import androidx.media3.test.utils.FakeTrackSelector;
import androidx.media3.test.utils.FakeVideoRenderer;
import androidx.media3.test.utils.NoUidTimeline;
import androidx.media3.test.utils.TestExoPlayerBuilder;
import androidx.media3.test.utils.robolectric.TestPlayerRunHelper;
import androidx.test.core.app.ApplicationProvider;
@ -12257,6 +12257,6 @@ public final class ExoPlayerTest {
* Returns an argument matcher for {@link Timeline} instances that ignores period and window uids.
*/
private static ArgumentMatcher<Timeline> noUid(Timeline timeline) {
return argument -> new NoUidTimeline(timeline).equals(new NoUidTimeline(argument));
return argument -> timelinesAreSame(argument, timeline);
}
}

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.test.utils;
import static androidx.media3.test.utils.TestUtil.timelinesAreSame;
import android.os.Looper;
import android.view.Surface;
import androidx.annotation.Nullable;
@ -765,7 +767,7 @@ public abstract class Action {
@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;
}
@ -797,7 +799,7 @@ public abstract class Action {
@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);
@ -805,8 +807,8 @@ public abstract class Action {
}
};
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);
}

View File

@ -43,6 +43,7 @@ import androidx.media3.exoplayer.analytics.AnalyticsListener;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.upstream.BandwidthMeter;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -536,11 +537,8 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
* @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));
}
/**

View File

@ -1,51 +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 androidx.media3.test.utils;
import androidx.media3.common.Timeline;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.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.
*/
@UnstableApi
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;
}
}

View File

@ -44,6 +44,7 @@ import androidx.media3.extractor.SeekMap;
import androidx.media3.extractor.metadata.MetadataInputBuffer;
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;
@ -207,11 +208,20 @@ public class TestUtil {
*/
public static void assertTimelinesSame(
List<Timeline> actualTimelines, List<Timeline> 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));
}
/**
@ -494,4 +504,47 @@ public class TestUtil {
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;
}
}
}