Start fixing nullness in testutil
PiperOrigin-RevId: 292340530
This commit is contained in:
parent
ff822ff9fd
commit
7c8a54c6d0
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.chunk;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
||||
@ -54,7 +55,7 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
|
||||
DataSpec dataSpec,
|
||||
Format trackFormat,
|
||||
int trackSelectionReason,
|
||||
Object trackSelectionData,
|
||||
@Nullable Object trackSelectionData,
|
||||
long startTimeUs,
|
||||
long endTimeUs,
|
||||
long chunkIndex,
|
||||
|
@ -821,7 +821,8 @@ public final class ExoPlayerTest {
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||
final FakeTrackSelector trackSelector = new FakeTrackSelector(/* reuse track selection */ true);
|
||||
final FakeTrackSelector trackSelector =
|
||||
new FakeTrackSelector(/* mayReuseTrackSelection= */ true);
|
||||
ActionSchedule disableTrackAction =
|
||||
new ActionSchedule.Builder("testReuseTrackSelection")
|
||||
.pause()
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import com.google.android.exoplayer2.util.HandlerWrapper;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* {@link FakeClock} extension which automatically advances time whenever an empty message is
|
||||
@ -25,7 +26,7 @@ import com.google.android.exoplayer2.util.HandlerWrapper;
|
||||
*/
|
||||
public final class AutoAdvancingFakeClock extends FakeClock {
|
||||
|
||||
private HandlerWrapper autoAdvancingHandler;
|
||||
private @MonotonicNonNull HandlerWrapper autoAdvancingHandler;
|
||||
|
||||
public AutoAdvancingFakeClock() {
|
||||
super(/* initialTimeMs= */ 0);
|
||||
|
@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.audio.AudioSink;
|
||||
import com.google.android.exoplayer2.audio.ForwardingAudioSink;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -122,7 +123,7 @@ public final class CapturingAudioSink extends ForwardingAudioSink implements Dum
|
||||
if (WRITE_DUMP) {
|
||||
File directory = context.getExternalFilesDir(null);
|
||||
File file = new File(directory, dumpFile);
|
||||
file.getParentFile().mkdirs();
|
||||
Assertions.checkStateNotNull(file.getParentFile()).mkdirs();
|
||||
PrintWriter out = new PrintWriter(file);
|
||||
out.print(actual);
|
||||
out.close();
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
@ -44,7 +45,7 @@ public final class Dumper {
|
||||
sb = new StringBuilder();
|
||||
}
|
||||
|
||||
public Dumper add(String field, Object value) {
|
||||
public Dumper add(String field, @Nullable Object value) {
|
||||
return addString(field + " = " + value + '\n');
|
||||
}
|
||||
|
||||
@ -53,8 +54,13 @@ public final class Dumper {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Dumper add(String field, byte[] value) {
|
||||
String string = String.format(Locale.US, "%s = length %d, hash %X\n", field, value.length,
|
||||
public Dumper add(String field, @Nullable byte[] value) {
|
||||
String string =
|
||||
String.format(
|
||||
Locale.US,
|
||||
"%s = length %d, hash %X\n",
|
||||
field,
|
||||
value == null ? 0 : value.length,
|
||||
Arrays.hashCode(value));
|
||||
return addString(string);
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ public final class ExtractorAsserts {
|
||||
}
|
||||
|
||||
// If the SeekMap is seekable, test seeking in the stream.
|
||||
SeekMap seekMap = extractorOutput.seekMap;
|
||||
SeekMap seekMap = Assertions.checkNotNull(extractorOutput.seekMap);
|
||||
if (seekMap.isSeekable()) {
|
||||
long durationUs = seekMap.getDurationUs();
|
||||
for (int j = 0; j < 4; j++) {
|
||||
@ -361,7 +361,7 @@ public final class ExtractorAsserts {
|
||||
int i = fileName.lastIndexOf('/');
|
||||
String path = i >= 0 ? fileName.substring(0, i) : "";
|
||||
String file = i >= 0 ? fileName.substring(i + 1) : fileName;
|
||||
return Arrays.asList(context.getResources().getAssets().list(path)).contains(file);
|
||||
String[] assets = context.getResources().getAssets().list(path);
|
||||
return assets != null && Arrays.asList(assets).contains(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer2.source.chunk.BaseMediaChunkIterator;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
@ -92,7 +93,7 @@ public final class FakeAdaptiveDataSet extends FakeDataSet {
|
||||
checkInBounds();
|
||||
String uri = dataSet.getUri(trackGroupIndex);
|
||||
int chunkIndex = (int) getCurrentIndex();
|
||||
Segment fakeDataChunk = dataSet.getData(uri).getSegments().get(chunkIndex);
|
||||
Segment fakeDataChunk = Util.castNonNull(dataSet.getData(uri)).getSegments().get(chunkIndex);
|
||||
return new DataSpec(
|
||||
Uri.parse(uri), fakeDataChunk.byteOffset, fakeDataChunk.length, /* key= */ null);
|
||||
}
|
||||
|
@ -28,9 +28,12 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting a
|
||||
@ -44,7 +47,7 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
@Nullable private final TransferListener transferListener;
|
||||
private final long durationUs;
|
||||
|
||||
private Callback callback;
|
||||
@MonotonicNonNull private Callback callback;
|
||||
private ChunkSampleStream<FakeChunkSource>[] sampleStreams;
|
||||
private SequenceableLoader sequenceableLoader;
|
||||
|
||||
@ -81,9 +84,9 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public long selectTracks(
|
||||
TrackSelection[] selections,
|
||||
@NullableType TrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
SampleStream[] streams,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
long positionUs) {
|
||||
long returnPositionUs = super.selectTracks(selections, mayRetainStreamFlags, streams,
|
||||
@ -94,7 +97,8 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
validStreams.add((ChunkSampleStream<FakeChunkSource>) stream);
|
||||
}
|
||||
}
|
||||
this.sampleStreams = validStreams.toArray(newSampleStreamArray(validStreams.size()));
|
||||
sampleStreams = newSampleStreamArray(validStreams.size());
|
||||
validStreams.toArray(sampleStreams);
|
||||
this.sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||
return returnPositionUs;
|
||||
}
|
||||
@ -162,7 +166,7 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
|
||||
@Override
|
||||
public void onContinueLoadingRequested(ChunkSampleStream<FakeChunkSource> source) {
|
||||
callback.onContinueLoadingRequested(this);
|
||||
Assertions.checkStateNotNull(callback).onContinueLoadingRequested(this);
|
||||
}
|
||||
|
||||
// We won't assign the array to a variable that erases the generic type, and then write into it.
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.testutil;
|
||||
import android.os.Handler.Callback;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
import com.google.android.exoplayer2.util.HandlerWrapper;
|
||||
import java.util.ArrayList;
|
||||
@ -90,7 +91,7 @@ public class FakeClock implements Clock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerWrapper createHandler(Looper looper, Callback callback) {
|
||||
public HandlerWrapper createHandler(Looper looper, @Nullable Callback callback) {
|
||||
return new ClockHandler(looper, callback);
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ public class FakeClock implements Clock {
|
||||
|
||||
private final long postTime;
|
||||
private final HandlerWrapper handler;
|
||||
private final Runnable runnable;
|
||||
@Nullable private final Runnable runnable;
|
||||
private final int message;
|
||||
|
||||
public HandlerMessageData(long postTime, HandlerWrapper handler, Runnable runnable) {
|
||||
@ -155,7 +156,7 @@ public class FakeClock implements Clock {
|
||||
|
||||
private final android.os.Handler handler;
|
||||
|
||||
public ClockHandler(Looper looper, Callback callback) {
|
||||
public ClockHandler(Looper looper, @Nullable Callback callback) {
|
||||
handler = new android.os.Handler(looper, callback);
|
||||
}
|
||||
|
||||
@ -170,7 +171,7 @@ public class FakeClock implements Clock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message obtainMessage(int what, Object obj) {
|
||||
public Message obtainMessage(int what, @Nullable Object obj) {
|
||||
return handler.obtainMessage(what, obj);
|
||||
}
|
||||
|
||||
@ -180,7 +181,7 @@ public class FakeClock implements Clock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message obtainMessage(int what, int arg1, int arg2, Object obj) {
|
||||
public Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
|
||||
return handler.obtainMessage(what, arg1, arg2, obj);
|
||||
}
|
||||
|
||||
@ -200,7 +201,7 @@ public class FakeClock implements Clock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallbacksAndMessages(Object token) {
|
||||
public void removeCallbacksAndMessages(@Nullable Object token) {
|
||||
handler.removeCallbacksAndMessages(token);
|
||||
}
|
||||
|
||||
|
@ -89,24 +89,28 @@ public class FakeDataSet {
|
||||
public boolean exceptionCleared;
|
||||
public int bytesRead;
|
||||
|
||||
private Segment(byte[] data, Segment previousSegment) {
|
||||
private Segment(byte[] data, @Nullable Segment previousSegment) {
|
||||
this(data, data.length, null, null, previousSegment);
|
||||
}
|
||||
|
||||
private Segment(int length, Segment previousSegment) {
|
||||
private Segment(int length, @Nullable Segment previousSegment) {
|
||||
this(null, length, null, null, previousSegment);
|
||||
}
|
||||
|
||||
private Segment(IOException exception, Segment previousSegment) {
|
||||
private Segment(IOException exception, @Nullable Segment previousSegment) {
|
||||
this(null, 0, exception, null, previousSegment);
|
||||
}
|
||||
|
||||
private Segment(Runnable action, Segment previousSegment) {
|
||||
private Segment(Runnable action, @Nullable Segment previousSegment) {
|
||||
this(null, 0, null, action, previousSegment);
|
||||
}
|
||||
|
||||
private Segment(@Nullable byte[] data, int length, @Nullable IOException exception,
|
||||
@Nullable Runnable action, Segment previousSegment) {
|
||||
private Segment(
|
||||
@Nullable byte[] data,
|
||||
int length,
|
||||
@Nullable IOException exception,
|
||||
@Nullable Runnable action,
|
||||
@Nullable Segment previousSegment) {
|
||||
this.exception = exception;
|
||||
this.action = action;
|
||||
this.data = data;
|
||||
@ -125,16 +129,17 @@ public class FakeDataSet {
|
||||
|
||||
}
|
||||
|
||||
/** Uri of the data or null if this is the default FakeData. */
|
||||
public final Uri uri;
|
||||
private final ArrayList<Segment> segments;
|
||||
private final FakeDataSet dataSet;
|
||||
/** Uri of the data or null if this is the default FakeData. */
|
||||
@Nullable public final Uri uri;
|
||||
|
||||
private final ArrayList<Segment> segments;
|
||||
private boolean simulateUnknownLength;
|
||||
|
||||
private FakeData(FakeDataSet dataSet, Uri uri) {
|
||||
private FakeData(FakeDataSet dataSet, @Nullable Uri uri) {
|
||||
this.dataSet = dataSet;
|
||||
this.uri = uri;
|
||||
this.segments = new ArrayList<>();
|
||||
this.dataSet = dataSet;
|
||||
}
|
||||
|
||||
/** Returns the {@link FakeDataSet} this FakeData belongs to. */
|
||||
@ -157,7 +162,7 @@ public class FakeDataSet {
|
||||
* Appends to the underlying data.
|
||||
*/
|
||||
public FakeData appendReadData(byte[] data) {
|
||||
Assertions.checkState(data != null && data.length > 0);
|
||||
Assertions.checkState(data.length > 0);
|
||||
segments.add(new Segment(data, getLastSegment()));
|
||||
return this;
|
||||
}
|
||||
@ -213,6 +218,7 @@ public class FakeDataSet {
|
||||
return simulateUnknownLength;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Segment getLastSegment() {
|
||||
int count = segments.size();
|
||||
return count > 0 ? segments.get(count - 1) : null;
|
||||
@ -221,7 +227,7 @@ public class FakeDataSet {
|
||||
}
|
||||
|
||||
private final HashMap<Uri, FakeData> dataMap;
|
||||
private FakeData defaultData;
|
||||
@Nullable private FakeData defaultData;
|
||||
|
||||
public FakeDataSet() {
|
||||
dataMap = new HashMap<>();
|
||||
@ -266,13 +272,15 @@ public class FakeDataSet {
|
||||
}
|
||||
|
||||
/** Returns the data for the given {@code uri}, or {@code defaultData} if no data is set. */
|
||||
@Nullable
|
||||
public FakeData getData(String uri) {
|
||||
return getData(Uri.parse(uri));
|
||||
}
|
||||
|
||||
/** Returns the data for the given {@code uri}, or {@code defaultData} if no data is set. */
|
||||
@Nullable
|
||||
public FakeData getData(Uri uri) {
|
||||
FakeData data = dataMap.get(uri);
|
||||
@Nullable FakeData data = dataMap.get(uri);
|
||||
return data != null ? data : defaultData;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment;
|
||||
@ -24,8 +25,10 @@ import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSourceException;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* A fake {@link DataSource} capable of simulating various scenarios. It uses a {@link FakeDataSet}
|
||||
@ -38,7 +41,7 @@ public class FakeDataSource extends BaseDataSource {
|
||||
*/
|
||||
public static class Factory implements DataSource.Factory {
|
||||
|
||||
protected FakeDataSet fakeDataSet;
|
||||
protected @MonotonicNonNull FakeDataSet fakeDataSet;
|
||||
protected boolean isNetwork;
|
||||
|
||||
public final Factory setFakeDataSet(FakeDataSet fakeDataSet) {
|
||||
@ -53,17 +56,17 @@ public class FakeDataSource extends BaseDataSource {
|
||||
|
||||
@Override
|
||||
public FakeDataSource createDataSource() {
|
||||
return new FakeDataSource(fakeDataSet, isNetwork);
|
||||
return new FakeDataSource(Assertions.checkStateNotNull(fakeDataSet), isNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
private final FakeDataSet fakeDataSet;
|
||||
private final ArrayList<DataSpec> openedDataSpecs;
|
||||
|
||||
private Uri uri;
|
||||
@Nullable private Uri uri;
|
||||
private boolean openCalled;
|
||||
private boolean sourceOpened;
|
||||
private FakeData fakeData;
|
||||
@Nullable private FakeData fakeData;
|
||||
private int currentSegmentIndex;
|
||||
private long bytesRemaining;
|
||||
|
||||
@ -96,10 +99,11 @@ public class FakeDataSource extends BaseDataSource {
|
||||
openedDataSpecs.add(dataSpec);
|
||||
|
||||
transferInitializing(dataSpec);
|
||||
fakeData = fakeDataSet.getData(uri.toString());
|
||||
FakeData fakeData = fakeDataSet.getData(dataSpec.uri.toString());
|
||||
if (fakeData == null) {
|
||||
throw new IOException("Data not found: " + dataSpec.uri);
|
||||
}
|
||||
this.fakeData = fakeData;
|
||||
|
||||
long totalLength = 0;
|
||||
for (Segment segment : fakeData.getSegments()) {
|
||||
@ -145,6 +149,7 @@ public class FakeDataSource extends BaseDataSource {
|
||||
public final int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||
Assertions.checkState(sourceOpened);
|
||||
while (true) {
|
||||
FakeData fakeData = Util.castNonNull(this.fakeData);
|
||||
if (currentSegmentIndex == fakeData.getSegments().size() || bytesRemaining == 0) {
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
}
|
||||
@ -152,13 +157,13 @@ public class FakeDataSource extends BaseDataSource {
|
||||
if (current.isErrorSegment()) {
|
||||
if (!current.exceptionCleared) {
|
||||
current.exceptionThrown = true;
|
||||
throw (IOException) current.exception.fillInStackTrace();
|
||||
throw (IOException) Util.castNonNull(current.exception).fillInStackTrace();
|
||||
} else {
|
||||
currentSegmentIndex++;
|
||||
}
|
||||
} else if (current.isActionSegment()) {
|
||||
currentSegmentIndex++;
|
||||
current.action.run();
|
||||
Util.castNonNull(current.action).run();
|
||||
} else {
|
||||
// Read at most bytesRemaining.
|
||||
readLength = (int) Math.min(readLength, bytesRemaining);
|
||||
@ -181,13 +186,14 @@ public class FakeDataSource extends BaseDataSource {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final Uri getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() throws IOException {
|
||||
public final void close() {
|
||||
Assertions.checkState(openCalled);
|
||||
openCalled = false;
|
||||
uri = null;
|
||||
|
@ -20,12 +20,15 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.SparseArray;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorOutput;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* A fake {@link ExtractorOutput}.
|
||||
@ -45,7 +48,7 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab
|
||||
|
||||
public int numberOfTracks;
|
||||
public boolean tracksEnded;
|
||||
public SeekMap seekMap;
|
||||
public @MonotonicNonNull SeekMap seekMap;
|
||||
|
||||
public FakeExtractorOutput() {
|
||||
trackOutputs = new SparseArray<>();
|
||||
@ -53,7 +56,7 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab
|
||||
|
||||
@Override
|
||||
public FakeTrackOutput track(int id, int type) {
|
||||
FakeTrackOutput output = trackOutputs.get(id);
|
||||
@Nullable FakeTrackOutput output = trackOutputs.get(id);
|
||||
if (output == null) {
|
||||
assertThat(tracksEnded).isFalse();
|
||||
numberOfTracks++;
|
||||
@ -99,10 +102,11 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab
|
||||
assertThat(seekMap).isNull();
|
||||
} else {
|
||||
// TODO: Bulk up this check if possible.
|
||||
assertThat(seekMap).isNotNull();
|
||||
assertThat(seekMap.getClass()).isEqualTo(expected.seekMap.getClass());
|
||||
assertThat(seekMap.isSeekable()).isEqualTo(expected.seekMap.isSeekable());
|
||||
assertThat(seekMap.getSeekPoints(0)).isEqualTo(expected.seekMap.getSeekPoints(0));
|
||||
SeekMap expectedSeekMap = Assertions.checkNotNull(expected.seekMap);
|
||||
SeekMap seekMap = Assertions.checkNotNull(this.seekMap);
|
||||
assertThat(seekMap.getClass()).isEqualTo(expectedSeekMap.getClass());
|
||||
assertThat(seekMap.isSeekable()).isEqualTo(expectedSeekMap.isSeekable());
|
||||
assertThat(seekMap.getSeekPoints(0)).isEqualTo(expectedSeekMap.getSeekPoints(0));
|
||||
}
|
||||
for (int i = 0; i < numberOfTracks; i++) {
|
||||
assertThat(trackOutputs.keyAt(i)).isEqualTo(expected.trackOutputs.keyAt(i));
|
||||
@ -125,7 +129,7 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab
|
||||
if (WRITE_DUMP) {
|
||||
File file = new File(System.getProperty("user.dir"), "src/test/assets");
|
||||
file = new File(file, dumpFile);
|
||||
file.getParentFile().mkdirs();
|
||||
Assertions.checkStateNotNull(file.getParentFile()).mkdirs();
|
||||
PrintWriter out = new PrintWriter(file);
|
||||
out.print(actual);
|
||||
out.close();
|
||||
|
@ -22,7 +22,6 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
|
||||
import java.io.IOException;
|
||||
|
||||
/** Fake {@link MediaChunk}. */
|
||||
public final class FakeMediaChunk extends MediaChunk {
|
||||
@ -51,7 +50,7 @@ public final class FakeMediaChunk extends MediaChunk {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() throws IOException, InterruptedException {
|
||||
public void load() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting
|
||||
@ -149,8 +150,12 @@ public class FakeMediaPeriod implements MediaPeriod {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
long positionUs) {
|
||||
assertThat(prepared).isTrue();
|
||||
sampleStreams.clear();
|
||||
int rendererCount = selections.length;
|
||||
|
@ -84,7 +84,7 @@ public class FakeRenderer extends BaseRenderer {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
formatReadCount++;
|
||||
assertThat(expectedFormats).contains(formatHolder.format);
|
||||
onFormatChanged(formatHolder.format);
|
||||
onFormatChanged(Assertions.checkNotNull(formatHolder.format));
|
||||
} else if (result == C.RESULT_BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
isEnded = true;
|
||||
|
@ -24,9 +24,7 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Fake {@link Timeline} which can be setup to return custom {@link TimelineWindowDefinition}s.
|
||||
*/
|
||||
/** Fake {@link Timeline} which can be setup to return custom {@link TimelineWindowDefinition}s. */
|
||||
public final class FakeTimeline extends Timeline {
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
@ -29,6 +30,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* A fake {@link TrackOutput}.
|
||||
@ -39,10 +42,10 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
private final ArrayList<Integer> sampleFlags;
|
||||
private final ArrayList<Integer> sampleStartOffsets;
|
||||
private final ArrayList<Integer> sampleEndOffsets;
|
||||
private final ArrayList<CryptoData> cryptoDatas;
|
||||
private final ArrayList<@NullableType CryptoData> cryptoDatas;
|
||||
|
||||
private byte[] sampleData;
|
||||
public Format format;
|
||||
public @MonotonicNonNull Format format;
|
||||
|
||||
public FakeTrackOutput() {
|
||||
sampleData = Util.EMPTY_BYTE_ARRAY;
|
||||
@ -64,6 +67,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
|
||||
@Override
|
||||
public void format(Format format) {
|
||||
// TODO: Capture and assert all formats (interleaved with the samples).
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@ -91,8 +95,12 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
|
||||
CryptoData cryptoData) {
|
||||
public void sampleMetadata(
|
||||
long timeUs,
|
||||
@C.BufferFlags int flags,
|
||||
int size,
|
||||
int offset,
|
||||
@Nullable CryptoData cryptoData) {
|
||||
if (format == null) {
|
||||
throw new IllegalStateException("TrackOutput must receive format before sampleMetadata");
|
||||
}
|
||||
@ -110,7 +118,8 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
assertThat(sampleTimesUs).hasSize(count);
|
||||
}
|
||||
|
||||
public void assertSample(int index, byte[] data, long timeUs, int flags, CryptoData cryptoData) {
|
||||
public void assertSample(
|
||||
int index, byte[] data, long timeUs, int flags, @Nullable CryptoData cryptoData) {
|
||||
byte[] actualData = getSampleData(index);
|
||||
assertThat(actualData).isEqualTo(data);
|
||||
assertThat(sampleTimesUs.get(index)).isEqualTo(timeUs);
|
||||
@ -131,6 +140,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
return sampleFlags.get(index);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CryptoData getSampleCryptoData(int index) {
|
||||
return cryptoDatas.get(index);
|
||||
}
|
||||
@ -162,6 +172,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
|
||||
@Override
|
||||
public void dump(Dumper dumper) {
|
||||
if (format != null) {
|
||||
dumper
|
||||
.startBlock("format")
|
||||
.add("bitrate", format.bitrate)
|
||||
@ -190,6 +201,7 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
|
||||
dumper.add("data", format.initializationData.get(i));
|
||||
}
|
||||
dumper.endBlock().endBlock();
|
||||
}
|
||||
|
||||
dumper.add("total output bytes", sampleData.length);
|
||||
dumper.add("sample count", sampleTimesUs.size());
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
@ -109,6 +110,7 @@ public final class FakeTrackSelection implements TrackSelection {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getSelectionData() {
|
||||
return null;
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport;
|
||||
import com.google.android.exoplayer2.RendererCapabilities.Capabilities;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
@ -23,6 +25,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/** A fake {@link MappingTrackSelector} that returns {@link FakeTrackSelection}s. */
|
||||
public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
@ -30,7 +33,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
private final FakeTrackSelectionFactory fakeTrackSelectionFactory;
|
||||
|
||||
public FakeTrackSelector() {
|
||||
this(false);
|
||||
this(/* mayReuseTrackSelection= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,13 +51,14 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TrackSelection.Definition[] selectAllTracks(
|
||||
protected TrackSelection.@NullableType Definition[] selectAllTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
int[][][] rendererFormatSupports,
|
||||
int[] rendererMixedMimeTypeAdaptationSupports,
|
||||
@Capabilities int[][][] rendererFormatSupports,
|
||||
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
|
||||
Parameters params) {
|
||||
int rendererCount = mappedTrackInfo.getRendererCount();
|
||||
TrackSelection.Definition[] definitions = new TrackSelection.Definition[rendererCount];
|
||||
TrackSelection.@NullableType Definition[] definitions =
|
||||
new TrackSelection.Definition[rendererCount];
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
|
||||
boolean hasTracks = trackGroupArray.length > 0;
|
||||
@ -80,7 +84,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
|
||||
@Override
|
||||
public TrackSelection[] createTrackSelections(
|
||||
TrackSelection.Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
@NullableType TrackSelection.Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
TrackSelection.Definition definition = definitions[i];
|
||||
|
@ -33,9 +33,7 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/**
|
||||
* A host activity for performing playback tests.
|
||||
*/
|
||||
/** A host activity for performing playback tests. */
|
||||
public final class HostActivity extends Activity implements SurfaceHolder.Callback {
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.BasePlayer;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
@ -250,7 +251,7 @@ public abstract class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||
public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -260,7 +261,7 @@ public abstract class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeekParameters(SeekParameters seekParameters) {
|
||||
public void setSeekParameters(@Nullable SeekParameters seekParameters) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -18,13 +18,16 @@ package com.google.android.exoplayer2.testutil;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.offline.Download;
|
||||
import com.google.android.exoplayer2.offline.Download.State;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/** A {@link DownloadManager.Listener} for testing. */
|
||||
public final class TestDownloadManagerListener implements DownloadManager.Listener {
|
||||
@ -39,7 +42,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
||||
private final CountDownLatch initializedCondition;
|
||||
private final int timeoutMs;
|
||||
|
||||
private CountDownLatch downloadFinishedCondition;
|
||||
private @MonotonicNonNull CountDownLatch downloadFinishedCondition;
|
||||
@Download.FailureReason private int failureReason;
|
||||
|
||||
public TestDownloadManagerListener(
|
||||
@ -57,6 +60,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
||||
downloadManager.addListener(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer pollStateChange(String taskId, long timeoutMs) throws InterruptedException {
|
||||
return getStateQueue(taskId).poll(timeoutMs, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
@ -112,7 +116,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
||||
dummyMainThread.runOnMainThread(
|
||||
() -> {
|
||||
if (downloadManager.isIdle()) {
|
||||
downloadFinishedCondition.countDown();
|
||||
Util.castNonNull(downloadFinishedCondition).countDown();
|
||||
}
|
||||
});
|
||||
assertThat(downloadFinishedCondition.await(timeoutMs, TimeUnit.MILLISECONDS)).isTrue();
|
||||
@ -120,10 +124,12 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
||||
|
||||
private ArrayBlockingQueue<Integer> getStateQueue(String taskId) {
|
||||
synchronized (downloadStates) {
|
||||
if (!downloadStates.containsKey(taskId)) {
|
||||
downloadStates.put(taskId, new ArrayBlockingQueue<>(10));
|
||||
@Nullable ArrayBlockingQueue<Integer> stateQueue = downloadStates.get(taskId);
|
||||
if (stateQueue == null) {
|
||||
stateQueue = new ArrayBlockingQueue<>(10);
|
||||
downloadStates.put(taskId, stateQueue);
|
||||
}
|
||||
return downloadStates.get(taskId);
|
||||
return stateQueue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,11 +143,11 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
||||
|
||||
private void assertStateInternal(String taskId, int expectedState, int timeoutMs) {
|
||||
while (true) {
|
||||
Integer state = null;
|
||||
@Nullable Integer state = null;
|
||||
try {
|
||||
state = pollStateChange(taskId, timeoutMs);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
fail("Interrupted: " + e.getMessage());
|
||||
}
|
||||
if (state != null) {
|
||||
if (expectedState == state) {
|
||||
|
@ -22,6 +22,8 @@ import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.Timeline.Period;
|
||||
import com.google.android.exoplayer2.Timeline.Window;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/** Unit test for {@link Timeline}. */
|
||||
public final class TimelineAsserts {
|
||||
@ -48,7 +50,8 @@ public final class TimelineAsserts {
|
||||
* @param expectedWindowTags A list of expected window tags. If a tag is unknown or not important
|
||||
* {@code null} can be passed to skip this window.
|
||||
*/
|
||||
public static void assertWindowTags(Timeline timeline, Object... expectedWindowTags) {
|
||||
public static void assertWindowTags(
|
||||
Timeline timeline, @NullableType Object... expectedWindowTags) {
|
||||
Window window = new Window();
|
||||
assertThat(timeline.getWindowCount()).isEqualTo(expectedWindowTags.length);
|
||||
for (int i = 0; i < timeline.getWindowCount(); i++) {
|
||||
@ -140,8 +143,9 @@ public final class TimelineAsserts {
|
||||
expectedWindowIndex++;
|
||||
}
|
||||
assertThat(period.windowIndex).isEqualTo(expectedWindowIndex);
|
||||
assertThat(timeline.getIndexOfPeriod(period.uid)).isEqualTo(i);
|
||||
assertThat(timeline.getUidOfPeriod(i)).isEqualTo(period.uid);
|
||||
Object periodUid = Assertions.checkNotNull(period.uid);
|
||||
assertThat(timeline.getIndexOfPeriod(periodUid)).isEqualTo(i);
|
||||
assertThat(timeline.getUidOfPeriod(i)).isEqualTo(periodUid);
|
||||
for (int repeatMode : REPEAT_MODES) {
|
||||
if (i < accumulatedPeriodCounts[expectedWindowIndex + 1] - 1) {
|
||||
assertThat(timeline.getNextPeriodIndex(i, period, window, repeatMode, false))
|
||||
|
Loading…
x
Reference in New Issue
Block a user