diff --git a/demos/shortform/src/main/java/androidx/media3/demo/shortform/MediaSourceManager.kt b/demos/shortform/src/main/java/androidx/media3/demo/shortform/MediaSourceManager.kt index ba96d1df8b..ae12b627be 100644 --- a/demos/shortform/src/main/java/androidx/media3/demo/shortform/MediaSourceManager.kt +++ b/demos/shortform/src/main/java/androidx/media3/demo/shortform/MediaSourceManager.kt @@ -26,7 +26,6 @@ import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.Util import androidx.media3.exoplayer.RendererCapabilities import androidx.media3.exoplayer.RenderersFactory -import androidx.media3.exoplayer.analytics.PlayerId import androidx.media3.exoplayer.audio.AudioRendererEventListener import androidx.media3.exoplayer.source.MediaSource import androidx.media3.exoplayer.source.preload.PreloadMediaSource @@ -61,7 +60,7 @@ class MediaSourceManager( bandwidthMeter, getRendererCapabilities(renderersFactory = renderersFactory), allocator, - preloadLooper + preloadLooper, ) } @@ -104,7 +103,7 @@ class MediaSourceManager( Util.createHandlerForCurrentOrMainLooper(), object : VideoRendererEventListener {}, object : AudioRendererEventListener {}, - { _: CueGroup? -> } + { _: CueGroup? -> }, ) { _: Metadata -> } val capabilities = ArrayList() @@ -131,9 +130,14 @@ class MediaSourceManager( override fun onContinueLoadingRequested( mediaSource: PreloadMediaSource, - bufferedPositionUs: Long + bufferedPositionUs: Long, ): Boolean { return bufferedPositionUs < targetPreloadPositionUs } + + override fun onUsedByPlayer(mediaSource: PreloadMediaSource) { + // Implementation is no-op until the whole class is removed with the adoption of + // DefaultPreloadManager. + } } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManager.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManager.java index 19b6532a49..42a719ca2b 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManager.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManager.java @@ -171,10 +171,6 @@ public final class DefaultPreloadManager extends BasePreloadManager { protected void preloadSourceInternal(MediaSource mediaSource, long startPositionsUs) { checkArgument(mediaSource instanceof PreloadMediaSource); PreloadMediaSource preloadMediaSource = (PreloadMediaSource) mediaSource; - if (preloadMediaSource.isUsedByPlayer()) { - onPreloadCompleted(preloadMediaSource); - return; - } preloadMediaSource.preload(startPositionsUs); } @@ -227,6 +223,11 @@ public final class DefaultPreloadManager extends BasePreloadManager { && status.getValue() > Util.usToMs(bufferedPositionUs))); } + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onPreloadCompleted(mediaSource); + } + private boolean continueOrCompletePreloading( MediaSource mediaSource, Predicate continueLoadingPredicate) { @Nullable diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java index 8db4160cf9..6b2fd13d8d 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java @@ -86,6 +86,13 @@ public final class PreloadMediaSource extends WrappingMediaSource { * data is buffered, or {@link C#TIME_END_OF_SOURCE} if the track is fully buffered. */ boolean onContinueLoadingRequested(PreloadMediaSource mediaSource, long bufferedPositionUs); + + /** + * Called from {@link PreloadMediaSource} when the player starts using this source. + * + * @param mediaSource The {@link PreloadMediaSource} that the player starts using. + */ + void onUsedByPlayer(PreloadMediaSource mediaSource); } /** Factory for {@link PreloadMediaSource}. */ @@ -197,6 +204,7 @@ public final class PreloadMediaSource extends WrappingMediaSource { @Nullable private Timeline timeline; @Nullable private Pair preloadingMediaPeriodAndKey; @Nullable private Pair playingPreloadedMediaPeriodAndId; + private boolean onUsedByPlayerNotified; private PreloadMediaSource( MediaSource mediaSource, @@ -230,7 +238,9 @@ public final class PreloadMediaSource extends WrappingMediaSource { () -> { preloadCalled = true; this.startPositionUs = startPositionUs; - if (!isUsedByPlayer()) { + if (isUsedByPlayer()) { + notifyOnUsedByPlayer(); + } else { setPlayerId(PlayerId.UNSET); // Set to PlayerId.UNSET as there is no ongoing playback. prepareSourceInternal(bandwidthMeter.getTransferListener()); } @@ -239,6 +249,9 @@ public final class PreloadMediaSource extends WrappingMediaSource { @Override protected void prepareSourceInternal() { + if (isUsedByPlayer() && !onUsedByPlayerNotified) { + notifyOnUsedByPlayer(); + } if (timeline != null) { onChildSourceInfoRefreshed(timeline); } else if (!prepareChildSourceCalled) { @@ -318,10 +331,13 @@ public final class PreloadMediaSource extends WrappingMediaSource { @Override protected void releaseSourceInternal() { - if (!preloadCalled && !isUsedByPlayer()) { - timeline = null; - prepareChildSourceCalled = false; - super.releaseSourceInternal(); + if (!isUsedByPlayer()) { + onUsedByPlayerNotified = false; + if (!preloadCalled) { + timeline = null; + prepareChildSourceCalled = false; + super.releaseSourceInternal(); + } } } @@ -355,6 +371,9 @@ public final class PreloadMediaSource extends WrappingMediaSource { @Override public void onPrepared(MediaPeriod mediaPeriod) { + if (isUsedByPlayer()) { + return; + } prepared = true; PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod; TrackGroupArray trackGroups = preloadMediaPeriod.getTrackGroups(); @@ -379,6 +398,9 @@ public final class PreloadMediaSource extends WrappingMediaSource { @Override public void onContinueLoadingRequested(MediaPeriod mediaPeriod) { + if (isUsedByPlayer()) { + return; + } PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod; if (!prepared || preloadControl.onContinueLoadingRequested( @@ -389,10 +411,15 @@ public final class PreloadMediaSource extends WrappingMediaSource { } } - /* package */ boolean isUsedByPlayer() { + private boolean isUsedByPlayer() { return prepareSourceCalled(); } + private void notifyOnUsedByPlayer() { + preloadControl.onUsedByPlayer(this); + onUsedByPlayerNotified = true; + } + private static boolean mediaPeriodIdEqualsWithoutWindowSequenceNumber( MediaPeriodId firstPeriodId, MediaPeriodId secondPeriodId) { return firstPeriodId.periodUid.equals(secondPeriodId.periodUid) diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManagerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManagerTest.java index c67d400a92..1ff268ee31 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManagerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/DefaultPreloadManagerTest.java @@ -246,11 +246,10 @@ public class DefaultPreloadManagerTest { FakeMediaSource wrappedMediaSource2 = fakeMediaSourceFactory.getLastCreatedSource(); wrappedMediaSource2.setAllowPreparation(false); - MediaSource.MediaSourceCaller externalCaller = (source, timeline) -> {}; PreloadMediaSource preloadMediaSource2 = (PreloadMediaSource) preloadManager.getMediaSource(mediaItem2); preloadMediaSource2.prepareSource( - externalCaller, bandwidthMeter.getTransferListener(), PlayerId.UNSET); + (source, timeline) -> {}, bandwidthMeter.getTransferListener(), PlayerId.UNSET); preloadManager.setCurrentPlayingIndex(2); preloadManager.invalidate(); shadowOf(Looper.getMainLooper()).idle(); @@ -261,6 +260,51 @@ public class DefaultPreloadManagerTest { assertThat(targetPreloadStatusControlCallReference).containsExactly(2, 1, 0).inOrder(); } + @Test + public void invalidate_sourceHandedOverToPlayerDuringPreloading_continuesPreloadingNextSource() { + ArrayList targetPreloadStatusControlCallReference = new ArrayList<>(); + TargetPreloadStatusControl targetPreloadStatusControl = + rankingData -> { + targetPreloadStatusControlCallReference.add(rankingData); + return new DefaultPreloadManager.Status( + DefaultPreloadManager.Status.STAGE_TIMELINE_REFRESHED); + }; + FakeMediaSourceFactory fakeMediaSourceFactory = new FakeMediaSourceFactory(); + DefaultPreloadManager preloadManager = + new DefaultPreloadManager( + targetPreloadStatusControl, + fakeMediaSourceFactory, + trackSelector, + bandwidthMeter, + rendererCapabilitiesListFactory, + allocator, + Util.getCurrentOrMainLooper()); + MediaItem.Builder mediaItemBuilder = new MediaItem.Builder(); + MediaItem mediaItem0 = + mediaItemBuilder.setMediaId("mediaId0").setUri("http://exoplayer.dev/video0").build(); + MediaItem mediaItem1 = + mediaItemBuilder.setMediaId("mediaId1").setUri("http://exoplayer.dev/video1").build(); + + preloadManager.add(mediaItem0, /* rankingData= */ 0); + FakeMediaSource wrappedMediaSource0 = fakeMediaSourceFactory.getLastCreatedSource(); + wrappedMediaSource0.setAllowPreparation(false); + preloadManager.add(mediaItem1, /* rankingData= */ 1); + FakeMediaSource wrappedMediaSource1 = fakeMediaSourceFactory.getLastCreatedSource(); + wrappedMediaSource1.setAllowPreparation(false); + preloadManager.invalidate(); + assertThat(targetPreloadStatusControlCallReference).containsExactly(0); + + PreloadMediaSource preloadMediaSource0 = + (PreloadMediaSource) preloadManager.getMediaSource(mediaItem0); + preloadMediaSource0.prepareSource( + (source, timeline) -> {}, bandwidthMeter.getTransferListener(), PlayerId.UNSET); + shadowOf(Looper.getMainLooper()).idle(); + + // The preload of mediaItem0 should complete and the preload manager continues to preload + // mediaItem1, even when the preloadMediaSource0 hasn't finished preparation. + assertThat(targetPreloadStatusControlCallReference).containsExactly(0, 1).inOrder(); + } + @Test public void invalidate_beforePreloadCompletedForLastInvalidate_preloadRespectsToLatestOrder() { ArrayList targetPreloadStatusControlCallReference = new ArrayList<>(); diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadAndPlaybackCoordinationTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadAndPlaybackCoordinationTest.java index a8a2d8da7a..534d088f0d 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadAndPlaybackCoordinationTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadAndPlaybackCoordinationTest.java @@ -70,6 +70,7 @@ public class PreloadAndPlaybackCoordinationTest { private final AtomicInteger preloadControlOnSourceInfoRefreshedCalledCounter; private final AtomicInteger preloadControlOnPreparedCalledCounter; + private final AtomicInteger preloadControlOnUsedByPlayerCounter; private final AtomicBoolean playbackSourceCallerOnSourceInfoRefreshedCalled; private final AtomicBoolean playbackPeriodCallbackOnPreparedCalled; private final AtomicReference preloadMediaPeriodReference; @@ -94,6 +95,7 @@ public class PreloadAndPlaybackCoordinationTest { }; preloadControlOnSourceInfoRefreshedCalledCounter = new AtomicInteger(); preloadControlOnPreparedCalledCounter = new AtomicInteger(); + preloadControlOnUsedByPlayerCounter = new AtomicInteger(); playbackSourceCallerOnSourceInfoRefreshedCalled = new AtomicBoolean(); playbackPeriodCallbackOnPreparedCalled = new AtomicBoolean(); preloadMediaPeriodReference = new AtomicReference<>(); @@ -117,6 +119,11 @@ public class PreloadAndPlaybackCoordinationTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return true; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + preloadControlOnUsedByPlayerCounter.addAndGet(1); + } }; PreloadMediaSource.Factory preloadMediaSourceFactory = new PreloadMediaSource.Factory( @@ -168,6 +175,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(0); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(0); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); assertThat(playbackSourceCallerOnSourceInfoRefreshedCalled.get()).isTrue(); assertThat(playbackPeriodCallbackOnPreparedCalled.get()).isTrue(); assertThat(preloadMediaPeriodReference.get()).isNotNull(); @@ -181,6 +189,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(1); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(1); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); } @Test @@ -192,6 +201,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(0); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(0); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(2); assertThat(playbackSourceCallerOnSourceInfoRefreshedCalled.get()).isTrue(); assertThat(playbackPeriodCallbackOnPreparedCalled.get()).isTrue(); assertThat(preloadMediaPeriodReference.get()).isNotNull(); @@ -205,6 +215,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(1); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(1); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(2); } @Test @@ -220,6 +231,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(0); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(0); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); assertThat(playbackSourceCallerOnSourceInfoRefreshedCalled.get()).isTrue(); assertThat(playbackPeriodCallbackOnPreparedCalled.get()).isTrue(); assertThat(preloadMediaPeriodReference.get()).isNotNull(); @@ -233,6 +245,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(1); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(1); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); } @Test @@ -251,6 +264,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(1); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(0); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); assertThat(playbackSourceCallerOnSourceInfoRefreshedCalled.get()).isTrue(); assertThat(playbackPeriodCallbackOnPreparedCalled.get()).isTrue(); assertThat(preloadMediaPeriodReference.get()).isNotNull(); @@ -265,6 +279,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(2); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(1); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); } @Test @@ -277,6 +292,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(1); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(1); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); assertThat(playbackSourceCallerOnSourceInfoRefreshedCalled.get()).isTrue(); assertThat(playbackPeriodCallbackOnPreparedCalled.get()).isTrue(); assertThat(preloadMediaPeriodReference.get()).isNotNull(); @@ -290,6 +306,7 @@ public class PreloadAndPlaybackCoordinationTest { assertThat(preloadControlOnSourceInfoRefreshedCalledCounter.get()).isEqualTo(2); assertThat(preloadControlOnPreparedCalledCounter.get()).isEqualTo(2); + assertThat(preloadControlOnUsedByPlayerCounter.get()).isEqualTo(1); } private static RendererCapabilities[] getRendererCapabilities(RenderersFactory renderersFactory) { diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaSourceTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaSourceTest.java index 14bee635c2..b3c2bdf40e 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaSourceTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaSourceTest.java @@ -104,6 +104,7 @@ public final class PreloadMediaSourceTest { AtomicBoolean onPreparedCalled = new AtomicBoolean(); AtomicBoolean onContinueLoadingStopped = new AtomicBoolean(); AtomicReference preloadMediaSourceReference = new AtomicReference<>(); + AtomicBoolean onUsedByPlayerCalled = new AtomicBoolean(); PreloadMediaSource.PreloadControl preloadControl = new PreloadMediaSource.PreloadControl() { @Override @@ -128,6 +129,11 @@ public final class PreloadMediaSourceTest { } return true; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onUsedByPlayerCalled.set(true); + } }; ProgressiveMediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory( @@ -156,6 +162,7 @@ public final class PreloadMediaSourceTest { assertThat(onTimelineRefreshedCalled.get()).isTrue(); assertThat(onPreparedCalled.get()).isTrue(); + assertThat(onUsedByPlayerCalled.get()).isFalse(); assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); } @@ -165,6 +172,7 @@ public final class PreloadMediaSourceTest { AtomicBoolean onPreparedCalled = new AtomicBoolean(); AtomicReference preloadMediaSourceReference = new AtomicReference<>(); AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean(); + AtomicBoolean onUsedByPlayerCalled = new AtomicBoolean(); PreloadMediaSource.PreloadControl preloadControl = new PreloadMediaSource.PreloadControl() { @Override @@ -186,6 +194,11 @@ public final class PreloadMediaSourceTest { onContinueLoadingRequestedCalled.set(true); return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onUsedByPlayerCalled.set(true); + } }; ProgressiveMediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory( @@ -215,6 +228,7 @@ public final class PreloadMediaSourceTest { assertThat(onTimelineRefreshedCalled.get()).isTrue(); assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(onContinueLoadingRequestedCalled.get()).isFalse(); + assertThat(onUsedByPlayerCalled.get()).isFalse(); } @Test @@ -223,6 +237,7 @@ public final class PreloadMediaSourceTest { AtomicReference preloadMediaSourceReference = new AtomicReference<>(); AtomicBoolean onPreparedCalled = new AtomicBoolean(); AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean(); + AtomicBoolean onUsedByPlayerCalled = new AtomicBoolean(); PreloadMediaSource.PreloadControl preloadControl = new PreloadMediaSource.PreloadControl() { @Override @@ -244,6 +259,11 @@ public final class PreloadMediaSourceTest { onContinueLoadingRequestedCalled.set(true); return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onUsedByPlayerCalled.set(true); + } }; ProgressiveMediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory( @@ -272,12 +292,14 @@ public final class PreloadMediaSourceTest { assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(onPreparedCalled.get()).isFalse(); assertThat(onContinueLoadingRequestedCalled.get()).isFalse(); + assertThat(onUsedByPlayerCalled.get()).isFalse(); } @Test public void preload_whileSourceIsAccessedByExternalCaller_notProceedWithPreloading() { AtomicBoolean onTimelineRefreshedCalled = new AtomicBoolean(false); AtomicBoolean onPreparedCalled = new AtomicBoolean(false); + AtomicBoolean onUsedByPlayerCalled = new AtomicBoolean(); PreloadMediaSource.PreloadControl preloadControl = new PreloadMediaSource.PreloadControl() { @Override @@ -297,6 +319,11 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return true; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onUsedByPlayerCalled.set(true); + } }; TrackSelector trackSelector = new FakeTrackSelector(); trackSelector.init(() -> {}, bandwidthMeter); @@ -332,6 +359,7 @@ public final class PreloadMediaSourceTest { assertThat(externalCallerMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(onTimelineRefreshedCalled.get()).isFalse(); assertThat(onPreparedCalled.get()).isFalse(); + assertThat(onUsedByPlayerCalled.get()).isTrue(); } @Test @@ -339,6 +367,7 @@ public final class PreloadMediaSourceTest { prepareSource_beforeSourceInfoRefreshedForPreloading_onlyInvokeExternalCallerOnSourceInfoRefreshed() { AtomicBoolean onTimelineRefreshedCalled = new AtomicBoolean(false); AtomicBoolean onPreparedCalled = new AtomicBoolean(false); + AtomicBoolean onUsedByPlayerCalled = new AtomicBoolean(); PreloadMediaSource.PreloadControl preloadControl = new PreloadMediaSource.PreloadControl() { @Override @@ -358,6 +387,11 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return true; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onUsedByPlayerCalled.set(true); + } }; FakeMediaSourceFactory mediaSourceFactory = new FakeMediaSourceFactory(); TrackSelector trackSelector = new FakeTrackSelector(); @@ -396,12 +430,14 @@ public final class PreloadMediaSourceTest { assertThat(externalCallerMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(onTimelineRefreshedCalled.get()).isFalse(); assertThat(onPreparedCalled.get()).isFalse(); + assertThat(onUsedByPlayerCalled.get()).isTrue(); } @Test public void prepareSource_afterPreload_immediatelyInvokeExternalCallerOnSourceInfoRefreshed() { AtomicBoolean onTimelineRefreshedCalled = new AtomicBoolean(false); AtomicBoolean onPreparedCalled = new AtomicBoolean(false); + AtomicBoolean onUsedByPlayerCalled = new AtomicBoolean(); PreloadMediaSource.PreloadControl preloadControl = new PreloadMediaSource.PreloadControl() { @Override @@ -421,6 +457,11 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return true; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) { + onUsedByPlayerCalled.set(true); + } }; FakeMediaSourceFactory mediaSourceFactory = new FakeMediaSourceFactory(); TrackSelector trackSelector = new FakeTrackSelector(); @@ -456,6 +497,7 @@ public final class PreloadMediaSourceTest { assertThat(onTimelineRefreshedCalled.get()).isTrue(); assertThat(onPreparedCalled.get()).isTrue(); assertThat(externalCallerMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); + assertThat(onUsedByPlayerCalled.get()).isTrue(); } @Test @@ -480,6 +522,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class); @@ -587,6 +632,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class); @@ -692,6 +740,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class); @@ -769,6 +820,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return true; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class); @@ -847,6 +901,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class); @@ -935,6 +992,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class); @@ -1004,6 +1064,9 @@ public final class PreloadMediaSourceTest { PreloadMediaSource mediaSource, long bufferedPositionUs) { return false; } + + @Override + public void onUsedByPlayer(PreloadMediaSource mediaSource) {} }; AtomicReference internalSourceReference = new AtomicReference<>(); MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class);