From ab64e6f92d7bb4fdcbe59935ea5571f8771125df Mon Sep 17 00:00:00 2001 From: rohks Date: Thu, 31 Aug 2023 06:29:23 -0700 Subject: [PATCH] Fix remaining `test_utils` module nullness issues #fixit PiperOrigin-RevId: 561636758 --- .../test/utils/AssetContentProvider.java | 31 +++++++++++----- .../test/utils/ExoPlayerTestRunner.java | 35 +++++++++++-------- .../test/utils/MediaSourceTestRunner.java | 23 +++++++----- 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/AssetContentProvider.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/AssetContentProvider.java index 8ce4060c0a..eab496509f 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/AssetContentProvider.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/AssetContentProvider.java @@ -15,6 +15,8 @@ */ package androidx.media3.test.utils; +import static androidx.media3.common.util.Assertions.checkNotNull; + import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; @@ -59,11 +61,16 @@ public final class AssetContentProvider extends ContentProvider @Override 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(); } @Override + @Nullable public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { if (uri.getPath() == null) { return null; @@ -74,14 +81,18 @@ public final class AssetContentProvider extends ContentProvider if (pipeMode) { ParcelFileDescriptor fileDescriptor = openPipeHelper( - uri, /* mimeType= */ null, /* opts= */ null, /* args= */ null, /* func= */ this); + uri, + /* mimeType= */ "application/octet-stream", + /* opts= */ null, + /* args= */ null, + /* func= */ this); return new AssetFileDescriptor( fileDescriptor, /* startOffset= */ 0, AssetFileDescriptor.UNKNOWN_LENGTH); } else { - return getContext().getAssets().openFd(fileName); + return checkNotNull(getContext()).getAssets().openFd(fileName); } } catch (IOException e) { - FileNotFoundException exception = new FileNotFoundException(e.getMessage()); + FileNotFoundException exception = new FileNotFoundException(checkNotNull(e.getMessage())); exception.initCause(e); throw exception; } @@ -98,12 +109,16 @@ public final class AssetContentProvider extends ContentProvider } @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { + public int delete(Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { throw new UnsupportedOperationException(); } @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(); } @@ -115,7 +130,7 @@ public final class AssetContentProvider extends ContentProvider @Nullable Bundle opts, @Nullable Object args) { 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); } catch (IOException e) { if (isBrokenPipe(e)) { @@ -129,7 +144,7 @@ public final class AssetContentProvider extends ContentProvider } private static String getFileName(Uri uri) { - return uri.getPath().replaceFirst("/", ""); + return checkNotNull(uri.getPath()).replaceFirst("/", ""); } private static boolean isBrokenPipe(IOException e) { diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/ExoPlayerTestRunner.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/ExoPlayerTestRunner.java index fd7844e210..0daf21bf59 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/ExoPlayerTestRunner.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/ExoPlayerTestRunner.java @@ -15,6 +15,7 @@ */ package androidx.media3.test.utils; +import static androidx.media3.common.util.Assertions.checkNotNull; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static junit.framework.TestCase.assertFalse; @@ -50,6 +51,7 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeoutException; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** Helper class to run an ExoPlayer test. */ @UnstableApi @@ -79,15 +81,15 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul */ public static final class Builder { private final TestExoPlayerBuilder testPlayerBuilder; - private Timeline timeline; + private @MonotonicNonNull Timeline timeline; private List mediaSources; private Format[] supportedFormats; - private Object manifest; - private ActionSchedule actionSchedule; - private Surface surface; - private Player.Listener playerListener; - private AnalyticsListener analyticsListener; - private Integer expectedPlayerEndedCount; + private @MonotonicNonNull Object manifest; + private @MonotonicNonNull ActionSchedule actionSchedule; + private @MonotonicNonNull Surface surface; + private Player.@MonotonicNonNull Listener playerListener; + private @MonotonicNonNull AnalyticsListener analyticsListener; + private @MonotonicNonNull Integer expectedPlayerEndedCount; private boolean pauseAtEndOfMediaItems; private int initialMediaItemIndex; private long initialPositionMs; @@ -355,7 +357,10 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul public ExoPlayerTestRunner build() { if (mediaSources.isEmpty() && !skipSettingMediaSources) { 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)); } @@ -401,8 +406,8 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul private final ArrayList playbackStates; private final boolean pauseAtEndOfMediaItems; - private ExoPlayer player; - private Exception exception; + private @MonotonicNonNull ExoPlayer player; + private @MonotonicNonNull Exception exception; private boolean playerWasPrepared; private ExoPlayerTestRunner( @@ -468,7 +473,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul handler.post( () -> { try { - player = playerBuilder.setLooper(Looper.myLooper()).build(); + player = playerBuilder.setLooper(checkNotNull(Looper.myLooper())).build(); if (surface != null) { player.setVideoSurface(surface); } @@ -651,7 +656,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) { timelineChangeReasons.add(reason); timelines.add(timeline); - int currentIndex = player.getCurrentPeriodIndex(); + int currentIndex = checkNotNull(player).getCurrentPeriodIndex(); if (periodIndices.isEmpty() || periodIndices.get(periodIndices.size() - 1) != currentIndex) { // Ignore timeline changes that do not change the period index. periodIndices.add(currentIndex); @@ -661,7 +666,9 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul @Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @Player.MediaItemTransitionReason int reason) { - mediaItems.add(mediaItem); + if (mediaItem != null) { + mediaItems.add(mediaItem); + } mediaItemTransitionReasons.add(reason); } @@ -686,7 +693,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul Player.PositionInfo newPosition, @Player.DiscontinuityReason int reason) { discontinuityReasons.add(reason); - int currentIndex = player.getCurrentPeriodIndex(); + int currentIndex = checkNotNull(player).getCurrentPeriodIndex(); if ((reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION && oldPosition.adGroupIndex != C.INDEX_UNSET && newPosition.adGroupIndex != C.INDEX_UNSET) diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/MediaSourceTestRunner.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/MediaSourceTestRunner.java index 7946e94345..34e7966b8b 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/MediaSourceTestRunner.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/MediaSourceTestRunner.java @@ -15,6 +15,7 @@ */ 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.assertWithMessage; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -27,6 +28,7 @@ import android.util.Pair; import androidx.annotation.Nullable; import androidx.media3.common.Timeline; import androidx.media3.common.util.Assertions; +import androidx.media3.common.util.NullableType; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.analytics.PlayerId; @@ -46,6 +48,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; +import org.checkerframework.dataflow.qual.SideEffectFree; /** A runner for {@link MediaSource} tests. */ @UnstableApi @@ -60,9 +63,9 @@ public class MediaSourceTestRunner { private final Allocator allocator; private final LinkedBlockingDeque timelines; - private final CopyOnWriteArrayList> completedLoads; + private final CopyOnWriteArrayList> completedLoads; - private Timeline timeline; + @Nullable private Timeline timeline; /** * @param mediaSource The source under test. @@ -214,6 +217,7 @@ public class MediaSourceTestRunner { * to {@link #assertTimelineChangeBlocking()} or {@link #assertTimelineChange()} (or since the * runner was created if neither method has been called). */ + @SideEffectFree public void assertNoTimelineChange() { assertThat(timelines).isEmpty(); } @@ -240,7 +244,7 @@ public class MediaSourceTestRunner { timeline = timelines.poll(TIMEOUT_MS, MILLISECONDS); assertThat(timeline).isNotNull(); // Null indicates the poll timed out. assertNoTimelineChange(); - return timeline; + return checkNotNull(timeline); } catch (InterruptedException e) { // Should never happen. throw new RuntimeException(e); @@ -255,13 +259,15 @@ public class MediaSourceTestRunner { */ public void assertPrepareAndReleaseAllPeriods() throws InterruptedException { Timeline.Period period = new Timeline.Period(); + Timeline timeline = checkNotNull(this.timeline); for (int i = 0; i < timeline.getPeriodCount(); i++) { 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 adIndex = 0; adIndex < period.getAdCountInAdGroup(adGroupIndex); adIndex++) { 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) { List expectedWindowIndices = new ArrayList<>(Arrays.asList(windowIndices)); - for (Pair windowIndexAndMediaPeriodId : completedLoads) { + for (Pair windowIndexAndMediaPeriodId : completedLoads) { if (windowIndexAndMediaPeriodId.second == null) { assertWithMessage("Missing expected load") .that(expectedWindowIndices) @@ -318,11 +324,12 @@ public class MediaSourceTestRunner { */ public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) { Timeline.Period period = new Timeline.Period(); + Timeline timeline = checkNotNull(this.timeline); HashSet expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds)); - for (Pair windowIndexAndMediaPeriodId : completedLoads) { + for (Pair windowIndexAndMediaPeriodId : completedLoads) { int windowIndex = windowIndexAndMediaPeriodId.first; MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second; - if (expectedLoads.remove(mediaPeriodId)) { + if (mediaPeriodId != null && expectedLoads.remove(mediaPeriodId)) { int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid); assertThat(windowIndex).isEqualTo(timeline.getPeriod(periodIndex, period).windowIndex); }