mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Fix remaining test_utils module nullness issues
#fixit PiperOrigin-RevId: 561636758
This commit is contained in:
parent
bbfba27cac
commit
ab64e6f92d
3 changed files with 59 additions and 30 deletions
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package androidx.media3.test.utils;
|
package androidx.media3.test.utils;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
|
@ -59,11 +61,16 @@ public final class AssetContentProvider extends ContentProvider
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor query(
|
public Cursor query(
|
||||||
Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
Uri uri,
|
||||||
|
@Nullable String[] projection,
|
||||||
|
@Nullable String selection,
|
||||||
|
@Nullable String[] selectionArgs,
|
||||||
|
@Nullable String sortOrder) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
|
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
|
||||||
if (uri.getPath() == null) {
|
if (uri.getPath() == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -74,14 +81,18 @@ public final class AssetContentProvider extends ContentProvider
|
||||||
if (pipeMode) {
|
if (pipeMode) {
|
||||||
ParcelFileDescriptor fileDescriptor =
|
ParcelFileDescriptor fileDescriptor =
|
||||||
openPipeHelper(
|
openPipeHelper(
|
||||||
uri, /* mimeType= */ null, /* opts= */ null, /* args= */ null, /* func= */ this);
|
uri,
|
||||||
|
/* mimeType= */ "application/octet-stream",
|
||||||
|
/* opts= */ null,
|
||||||
|
/* args= */ null,
|
||||||
|
/* func= */ this);
|
||||||
return new AssetFileDescriptor(
|
return new AssetFileDescriptor(
|
||||||
fileDescriptor, /* startOffset= */ 0, AssetFileDescriptor.UNKNOWN_LENGTH);
|
fileDescriptor, /* startOffset= */ 0, AssetFileDescriptor.UNKNOWN_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
return getContext().getAssets().openFd(fileName);
|
return checkNotNull(getContext()).getAssets().openFd(fileName);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
FileNotFoundException exception = new FileNotFoundException(e.getMessage());
|
FileNotFoundException exception = new FileNotFoundException(checkNotNull(e.getMessage()));
|
||||||
exception.initCause(e);
|
exception.initCause(e);
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
|
|
@ -98,12 +109,16 @@ public final class AssetContentProvider extends ContentProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
public int delete(Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
public int update(
|
||||||
|
Uri uri,
|
||||||
|
@Nullable ContentValues values,
|
||||||
|
@Nullable String selection,
|
||||||
|
@Nullable String[] selectionArgs) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +130,7 @@ public final class AssetContentProvider extends ContentProvider
|
||||||
@Nullable Bundle opts,
|
@Nullable Bundle opts,
|
||||||
@Nullable Object args) {
|
@Nullable Object args) {
|
||||||
try (FileOutputStream outputStream = new FileOutputStream(output.getFileDescriptor())) {
|
try (FileOutputStream outputStream = new FileOutputStream(output.getFileDescriptor())) {
|
||||||
byte[] data = TestUtil.getByteArray(getContext(), getFileName(uri));
|
byte[] data = TestUtil.getByteArray(checkNotNull(getContext()), getFileName(uri));
|
||||||
outputStream.write(data);
|
outputStream.write(data);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (isBrokenPipe(e)) {
|
if (isBrokenPipe(e)) {
|
||||||
|
|
@ -129,7 +144,7 @@ public final class AssetContentProvider extends ContentProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getFileName(Uri uri) {
|
private static String getFileName(Uri uri) {
|
||||||
return uri.getPath().replaceFirst("/", "");
|
return checkNotNull(uri.getPath()).replaceFirst("/", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isBrokenPipe(IOException e) {
|
private static boolean isBrokenPipe(IOException e) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package androidx.media3.test.utils;
|
package androidx.media3.test.utils;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static junit.framework.TestCase.assertFalse;
|
import static junit.framework.TestCase.assertFalse;
|
||||||
|
|
@ -50,6 +51,7 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/** Helper class to run an ExoPlayer test. */
|
/** Helper class to run an ExoPlayer test. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
|
|
@ -79,15 +81,15 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
*/
|
*/
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
private final TestExoPlayerBuilder testPlayerBuilder;
|
private final TestExoPlayerBuilder testPlayerBuilder;
|
||||||
private Timeline timeline;
|
private @MonotonicNonNull Timeline timeline;
|
||||||
private List<MediaSource> mediaSources;
|
private List<MediaSource> mediaSources;
|
||||||
private Format[] supportedFormats;
|
private Format[] supportedFormats;
|
||||||
private Object manifest;
|
private @MonotonicNonNull Object manifest;
|
||||||
private ActionSchedule actionSchedule;
|
private @MonotonicNonNull ActionSchedule actionSchedule;
|
||||||
private Surface surface;
|
private @MonotonicNonNull Surface surface;
|
||||||
private Player.Listener playerListener;
|
private Player.@MonotonicNonNull Listener playerListener;
|
||||||
private AnalyticsListener analyticsListener;
|
private @MonotonicNonNull AnalyticsListener analyticsListener;
|
||||||
private Integer expectedPlayerEndedCount;
|
private @MonotonicNonNull Integer expectedPlayerEndedCount;
|
||||||
private boolean pauseAtEndOfMediaItems;
|
private boolean pauseAtEndOfMediaItems;
|
||||||
private int initialMediaItemIndex;
|
private int initialMediaItemIndex;
|
||||||
private long initialPositionMs;
|
private long initialPositionMs;
|
||||||
|
|
@ -355,7 +357,10 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
public ExoPlayerTestRunner build() {
|
public ExoPlayerTestRunner build() {
|
||||||
if (mediaSources.isEmpty() && !skipSettingMediaSources) {
|
if (mediaSources.isEmpty() && !skipSettingMediaSources) {
|
||||||
if (timeline == null) {
|
if (timeline == null) {
|
||||||
timeline = new FakeTimeline(/* windowCount= */ 1, manifest);
|
timeline =
|
||||||
|
new FakeTimeline(
|
||||||
|
/* windowCount= */ 1,
|
||||||
|
manifest != null ? new Object[] {manifest} : new Object[] {});
|
||||||
}
|
}
|
||||||
mediaSources.add(new FakeMediaSource(timeline, supportedFormats));
|
mediaSources.add(new FakeMediaSource(timeline, supportedFormats));
|
||||||
}
|
}
|
||||||
|
|
@ -401,8 +406,8 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
private final ArrayList<Integer> playbackStates;
|
private final ArrayList<Integer> playbackStates;
|
||||||
private final boolean pauseAtEndOfMediaItems;
|
private final boolean pauseAtEndOfMediaItems;
|
||||||
|
|
||||||
private ExoPlayer player;
|
private @MonotonicNonNull ExoPlayer player;
|
||||||
private Exception exception;
|
private @MonotonicNonNull Exception exception;
|
||||||
private boolean playerWasPrepared;
|
private boolean playerWasPrepared;
|
||||||
|
|
||||||
private ExoPlayerTestRunner(
|
private ExoPlayerTestRunner(
|
||||||
|
|
@ -468,7 +473,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
handler.post(
|
handler.post(
|
||||||
() -> {
|
() -> {
|
||||||
try {
|
try {
|
||||||
player = playerBuilder.setLooper(Looper.myLooper()).build();
|
player = playerBuilder.setLooper(checkNotNull(Looper.myLooper())).build();
|
||||||
if (surface != null) {
|
if (surface != null) {
|
||||||
player.setVideoSurface(surface);
|
player.setVideoSurface(surface);
|
||||||
}
|
}
|
||||||
|
|
@ -651,7 +656,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||||
timelineChangeReasons.add(reason);
|
timelineChangeReasons.add(reason);
|
||||||
timelines.add(timeline);
|
timelines.add(timeline);
|
||||||
int currentIndex = player.getCurrentPeriodIndex();
|
int currentIndex = checkNotNull(player).getCurrentPeriodIndex();
|
||||||
if (periodIndices.isEmpty() || periodIndices.get(periodIndices.size() - 1) != currentIndex) {
|
if (periodIndices.isEmpty() || periodIndices.get(periodIndices.size() - 1) != currentIndex) {
|
||||||
// Ignore timeline changes that do not change the period index.
|
// Ignore timeline changes that do not change the period index.
|
||||||
periodIndices.add(currentIndex);
|
periodIndices.add(currentIndex);
|
||||||
|
|
@ -661,7 +666,9 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
@Override
|
@Override
|
||||||
public void onMediaItemTransition(
|
public void onMediaItemTransition(
|
||||||
@Nullable MediaItem mediaItem, @Player.MediaItemTransitionReason int reason) {
|
@Nullable MediaItem mediaItem, @Player.MediaItemTransitionReason int reason) {
|
||||||
mediaItems.add(mediaItem);
|
if (mediaItem != null) {
|
||||||
|
mediaItems.add(mediaItem);
|
||||||
|
}
|
||||||
mediaItemTransitionReasons.add(reason);
|
mediaItemTransitionReasons.add(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -686,7 +693,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||||
Player.PositionInfo newPosition,
|
Player.PositionInfo newPosition,
|
||||||
@Player.DiscontinuityReason int reason) {
|
@Player.DiscontinuityReason int reason) {
|
||||||
discontinuityReasons.add(reason);
|
discontinuityReasons.add(reason);
|
||||||
int currentIndex = player.getCurrentPeriodIndex();
|
int currentIndex = checkNotNull(player).getCurrentPeriodIndex();
|
||||||
if ((reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION
|
if ((reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION
|
||||||
&& oldPosition.adGroupIndex != C.INDEX_UNSET
|
&& oldPosition.adGroupIndex != C.INDEX_UNSET
|
||||||
&& newPosition.adGroupIndex != C.INDEX_UNSET)
|
&& newPosition.adGroupIndex != C.INDEX_UNSET)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package androidx.media3.test.utils;
|
package androidx.media3.test.utils;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth.assertWithMessage;
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
|
@ -27,6 +28,7 @@ import android.util.Pair;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.Timeline;
|
import androidx.media3.common.Timeline;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
|
import androidx.media3.common.util.NullableType;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||||
|
|
@ -46,6 +48,7 @@ import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import org.checkerframework.dataflow.qual.SideEffectFree;
|
||||||
|
|
||||||
/** A runner for {@link MediaSource} tests. */
|
/** A runner for {@link MediaSource} tests. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
|
|
@ -60,9 +63,9 @@ public class MediaSourceTestRunner {
|
||||||
private final Allocator allocator;
|
private final Allocator allocator;
|
||||||
|
|
||||||
private final LinkedBlockingDeque<Timeline> timelines;
|
private final LinkedBlockingDeque<Timeline> timelines;
|
||||||
private final CopyOnWriteArrayList<Pair<Integer, MediaPeriodId>> completedLoads;
|
private final CopyOnWriteArrayList<Pair<Integer, @NullableType MediaPeriodId>> completedLoads;
|
||||||
|
|
||||||
private Timeline timeline;
|
@Nullable private Timeline timeline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mediaSource The source under test.
|
* @param mediaSource The source under test.
|
||||||
|
|
@ -214,6 +217,7 @@ public class MediaSourceTestRunner {
|
||||||
* to {@link #assertTimelineChangeBlocking()} or {@link #assertTimelineChange()} (or since the
|
* to {@link #assertTimelineChangeBlocking()} or {@link #assertTimelineChange()} (or since the
|
||||||
* runner was created if neither method has been called).
|
* runner was created if neither method has been called).
|
||||||
*/
|
*/
|
||||||
|
@SideEffectFree
|
||||||
public void assertNoTimelineChange() {
|
public void assertNoTimelineChange() {
|
||||||
assertThat(timelines).isEmpty();
|
assertThat(timelines).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -240,7 +244,7 @@ public class MediaSourceTestRunner {
|
||||||
timeline = timelines.poll(TIMEOUT_MS, MILLISECONDS);
|
timeline = timelines.poll(TIMEOUT_MS, MILLISECONDS);
|
||||||
assertThat(timeline).isNotNull(); // Null indicates the poll timed out.
|
assertThat(timeline).isNotNull(); // Null indicates the poll timed out.
|
||||||
assertNoTimelineChange();
|
assertNoTimelineChange();
|
||||||
return timeline;
|
return checkNotNull(timeline);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Should never happen.
|
// Should never happen.
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
@ -255,13 +259,15 @@ public class MediaSourceTestRunner {
|
||||||
*/
|
*/
|
||||||
public void assertPrepareAndReleaseAllPeriods() throws InterruptedException {
|
public void assertPrepareAndReleaseAllPeriods() throws InterruptedException {
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
|
Timeline timeline = checkNotNull(this.timeline);
|
||||||
for (int i = 0; i < timeline.getPeriodCount(); i++) {
|
for (int i = 0; i < timeline.getPeriodCount(); i++) {
|
||||||
timeline.getPeriod(i, period, /* setIds= */ true);
|
timeline.getPeriod(i, period, /* setIds= */ true);
|
||||||
assertPrepareAndReleasePeriod(new MediaPeriodId(period.uid, period.windowIndex));
|
Object periodUid = checkNotNull(period.uid);
|
||||||
|
assertPrepareAndReleasePeriod(new MediaPeriodId(periodUid, period.windowIndex));
|
||||||
for (int adGroupIndex = 0; adGroupIndex < period.getAdGroupCount(); adGroupIndex++) {
|
for (int adGroupIndex = 0; adGroupIndex < period.getAdGroupCount(); adGroupIndex++) {
|
||||||
for (int adIndex = 0; adIndex < period.getAdCountInAdGroup(adGroupIndex); adIndex++) {
|
for (int adIndex = 0; adIndex < period.getAdCountInAdGroup(adGroupIndex); adIndex++) {
|
||||||
assertPrepareAndReleasePeriod(
|
assertPrepareAndReleasePeriod(
|
||||||
new MediaPeriodId(period.uid, adGroupIndex, adIndex, period.windowIndex));
|
new MediaPeriodId(periodUid, adGroupIndex, adIndex, period.windowIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -296,7 +302,7 @@ public class MediaSourceTestRunner {
|
||||||
*/
|
*/
|
||||||
public void assertCompletedManifestLoads(Integer... windowIndices) {
|
public void assertCompletedManifestLoads(Integer... windowIndices) {
|
||||||
List<Integer> expectedWindowIndices = new ArrayList<>(Arrays.asList(windowIndices));
|
List<Integer> expectedWindowIndices = new ArrayList<>(Arrays.asList(windowIndices));
|
||||||
for (Pair<Integer, MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) {
|
for (Pair<Integer, @NullableType MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) {
|
||||||
if (windowIndexAndMediaPeriodId.second == null) {
|
if (windowIndexAndMediaPeriodId.second == null) {
|
||||||
assertWithMessage("Missing expected load")
|
assertWithMessage("Missing expected load")
|
||||||
.that(expectedWindowIndices)
|
.that(expectedWindowIndices)
|
||||||
|
|
@ -318,11 +324,12 @@ public class MediaSourceTestRunner {
|
||||||
*/
|
*/
|
||||||
public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) {
|
public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) {
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
|
Timeline timeline = checkNotNull(this.timeline);
|
||||||
HashSet<MediaPeriodId> expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds));
|
HashSet<MediaPeriodId> expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds));
|
||||||
for (Pair<Integer, MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) {
|
for (Pair<Integer, @NullableType MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) {
|
||||||
int windowIndex = windowIndexAndMediaPeriodId.first;
|
int windowIndex = windowIndexAndMediaPeriodId.first;
|
||||||
MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second;
|
MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second;
|
||||||
if (expectedLoads.remove(mediaPeriodId)) {
|
if (mediaPeriodId != null && expectedLoads.remove(mediaPeriodId)) {
|
||||||
int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid);
|
int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid);
|
||||||
assertThat(windowIndex).isEqualTo(timeline.getPeriod(periodIndex, period).windowIndex);
|
assertThat(windowIndex).isEqualTo(timeline.getPeriod(periodIndex, period).windowIndex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue