Search in sources :

Example 36 with FakeClock

use of com.google.android.exoplayer2.testutil.FakeClock in project ExoPlayer by google.

the class ServerSideAdInsertionMediaSourceTest method playbackWithSeek_isHandledCorrectly.

@Test
public void playbackWithSeek_isHandledCorrectly() throws Exception {
    Context context = ApplicationProvider.getApplicationContext();
    ExoPlayer player = new ExoPlayer.Builder(context).setClock(new FakeClock(/* isAutoAdvancing= */
    true)).build();
    player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */
    1)));
    AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */
    new Object());
    adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
    0, /* contentResumeOffsetUs= */
    0, /* adDurationsUs...= */
    100_000);
    adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
    600_000, /* contentResumeOffsetUs= */
    1_000_000, /* adDurationsUs...= */
    100_000);
    AdPlaybackState firstAdPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
    900_000, /* contentResumeOffsetUs= */
    0, /* adDurationsUs...= */
    100_000);
    AtomicReference<ServerSideAdInsertionMediaSource> mediaSourceRef = new AtomicReference<>();
    mediaSourceRef.set(new ServerSideAdInsertionMediaSource(new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)), /* adPlaybackStateUpdater= */
    contentTimeline -> {
        Object periodUid = checkNotNull(contentTimeline.getPeriod(/* periodIndex= */
        0, new Timeline.Period(), /* setIds= */
        true).uid);
        mediaSourceRef.get().setAdPlaybackStates(ImmutableMap.of(periodUid, firstAdPlaybackState));
        return true;
    }));
    AnalyticsListener listener = mock(AnalyticsListener.class);
    player.addAnalyticsListener(listener);
    player.setMediaSource(mediaSourceRef.get());
    player.prepare();
    // Play to the first content part, then seek past the midroll.
    playUntilPosition(player, /* mediaItemIndex= */
    0, /* positionMs= */
    100);
    player.seekTo(/* positionMs= */
    1_600);
    runUntilPendingCommandsAreFullyHandled(player);
    long positionAfterSeekMs = player.getCurrentPosition();
    long contentPositionAfterSeekMs = player.getContentPosition();
    player.play();
    runUntilPlaybackState(player, Player.STATE_ENDED);
    player.release();
    // Assert playback has been reported with ads: [ad0][content] seek [ad1][content][ad2][content]
    // 6*2(audio+video) format changes, 4 auto-transitions between parts, 1 seek with adjustment.
    verify(listener, times(4)).onPositionDiscontinuity(any(), any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
    verify(listener, times(1)).onPositionDiscontinuity(any(), any(), any(), eq(Player.DISCONTINUITY_REASON_SEEK));
    verify(listener, times(1)).onPositionDiscontinuity(any(), any(), any(), eq(Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT));
    verify(listener, times(12)).onDownstreamFormatChanged(any(), any());
    assertThat(contentPositionAfterSeekMs).isEqualTo(1_600);
    // Beginning of second ad.
    assertThat(positionAfterSeekMs).isEqualTo(0);
    // Assert renderers played through without reset, except for the seek.
    verify(listener, times(2)).onVideoEnabled(any(), any());
    verify(listener, times(2)).onAudioEnabled(any(), any());
    // Assert playback progression was smooth (=no unexpected delays that cause audio to underrun)
    verify(listener, never()).onAudioUnderrun(any(), anyInt(), anyLong(), anyLong());
}
Also used : Context(android.content.Context) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AnalyticsListener(com.google.android.exoplayer2.analytics.AnalyticsListener) Context(android.content.Context) TestPlayerRunHelper.runUntilPendingCommandsAreFullyHandled(com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilPendingCommandsAreFullyHandled) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Pair(android.util.Pair) RunWith(org.junit.runner.RunWith) Player(com.google.android.exoplayer2.Player) DefaultMediaSourceFactory(com.google.android.exoplayer2.source.DefaultMediaSourceFactory) TestPlayerRunHelper.playUntilPosition(com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilPosition) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) AtomicReference(java.util.concurrent.atomic.AtomicReference) ApplicationProvider(androidx.test.core.app.ApplicationProvider) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) PlayerId(com.google.android.exoplayer2.analytics.PlayerId) ShadowMediaCodecConfig(com.google.android.exoplayer2.robolectric.ShadowMediaCodecConfig) ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) RobolectricUtil.runMainLooperUntil(com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil) SurfaceTexture(android.graphics.SurfaceTexture) MediaItem(com.google.android.exoplayer2.MediaItem) TestPlayerRunHelper.runUntilPlaybackState(com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilPlaybackState) Surface(android.view.Surface) ImmutableMap(com.google.common.collect.ImmutableMap) CapturingRenderersFactory(com.google.android.exoplayer2.testutil.CapturingRenderersFactory) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) FakeClock(com.google.android.exoplayer2.testutil.FakeClock) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) Mockito.never(org.mockito.Mockito.never) Timeline(com.google.android.exoplayer2.Timeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) Rule(org.junit.Rule) DumpFileAsserts(com.google.android.exoplayer2.testutil.DumpFileAsserts) PlaybackOutput(com.google.android.exoplayer2.robolectric.PlaybackOutput) Assert(org.junit.Assert) Assertions.checkNotNull(com.google.android.exoplayer2.util.Assertions.checkNotNull) Mockito.mock(org.mockito.Mockito.mock) AnalyticsListener(com.google.android.exoplayer2.analytics.AnalyticsListener) FakeClock(com.google.android.exoplayer2.testutil.FakeClock) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) Surface(android.view.Surface) SurfaceTexture(android.graphics.SurfaceTexture) ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState) DefaultMediaSourceFactory(com.google.android.exoplayer2.source.DefaultMediaSourceFactory) Test(org.junit.Test)

Example 37 with FakeClock

use of com.google.android.exoplayer2.testutil.FakeClock in project ExoPlayer by google.

the class ServerSideAdInsertionMediaSourceTest method playbackWithPredefinedAds_playsSuccessfulWithoutRendererResets.

@Test
public void playbackWithPredefinedAds_playsSuccessfulWithoutRendererResets() throws Exception {
    Context context = ApplicationProvider.getApplicationContext();
    CapturingRenderersFactory renderersFactory = new CapturingRenderersFactory(context);
    ExoPlayer player = new ExoPlayer.Builder(context, renderersFactory).setClock(new FakeClock(/* isAutoAdvancing= */
    true)).build();
    player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */
    1)));
    PlaybackOutput playbackOutput = PlaybackOutput.register(player, renderersFactory);
    AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */
    new Object());
    adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
    0, /* contentResumeOffsetUs= */
    0, /* adDurationsUs...= */
    200_000);
    adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
    400_000, /* contentResumeOffsetUs= */
    1_000_000, /* adDurationsUs...= */
    300_000);
    AdPlaybackState firstAdPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
    900_000, /* contentResumeOffsetUs= */
    0, /* adDurationsUs...= */
    100_000);
    AtomicReference<ServerSideAdInsertionMediaSource> mediaSourceRef = new AtomicReference<>();
    mediaSourceRef.set(new ServerSideAdInsertionMediaSource(new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)), contentTimeline -> {
        Object periodUid = checkNotNull(contentTimeline.getPeriod(/* periodIndex= */
        0, new Timeline.Period(), /* setIds= */
        true).uid);
        mediaSourceRef.get().setAdPlaybackStates(ImmutableMap.of(periodUid, firstAdPlaybackState));
        return true;
    }));
    AnalyticsListener listener = mock(AnalyticsListener.class);
    player.addAnalyticsListener(listener);
    player.setMediaSource(mediaSourceRef.get());
    player.prepare();
    player.play();
    runUntilPlaybackState(player, Player.STATE_ENDED);
    player.release();
    // Assert all samples have been played.
    DumpFileAsserts.assertOutput(context, playbackOutput, TEST_ASSET_DUMP);
    // Assert playback has been reported with ads: [ad0][content][ad1][content][ad2][content]
    // 6*2(audio+video) format changes, 5 discontinuities between parts.
    verify(listener, times(5)).onPositionDiscontinuity(any(), any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
    verify(listener, times(12)).onDownstreamFormatChanged(any(), any());
    // Assert renderers played through without reset (=decoders have been enabled only once).
    verify(listener).onVideoEnabled(any(), any());
    verify(listener).onAudioEnabled(any(), any());
    // Assert playback progression was smooth (=no unexpected delays that cause audio to underrun)
    verify(listener, never()).onAudioUnderrun(any(), anyInt(), anyLong(), anyLong());
}
Also used : Context(android.content.Context) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AnalyticsListener(com.google.android.exoplayer2.analytics.AnalyticsListener) Context(android.content.Context) TestPlayerRunHelper.runUntilPendingCommandsAreFullyHandled(com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilPendingCommandsAreFullyHandled) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Pair(android.util.Pair) RunWith(org.junit.runner.RunWith) Player(com.google.android.exoplayer2.Player) DefaultMediaSourceFactory(com.google.android.exoplayer2.source.DefaultMediaSourceFactory) TestPlayerRunHelper.playUntilPosition(com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilPosition) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) AtomicReference(java.util.concurrent.atomic.AtomicReference) ApplicationProvider(androidx.test.core.app.ApplicationProvider) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) PlayerId(com.google.android.exoplayer2.analytics.PlayerId) ShadowMediaCodecConfig(com.google.android.exoplayer2.robolectric.ShadowMediaCodecConfig) ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) RobolectricUtil.runMainLooperUntil(com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil) SurfaceTexture(android.graphics.SurfaceTexture) MediaItem(com.google.android.exoplayer2.MediaItem) TestPlayerRunHelper.runUntilPlaybackState(com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilPlaybackState) Surface(android.view.Surface) ImmutableMap(com.google.common.collect.ImmutableMap) CapturingRenderersFactory(com.google.android.exoplayer2.testutil.CapturingRenderersFactory) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) FakeClock(com.google.android.exoplayer2.testutil.FakeClock) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) Mockito.never(org.mockito.Mockito.never) Timeline(com.google.android.exoplayer2.Timeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) Rule(org.junit.Rule) DumpFileAsserts(com.google.android.exoplayer2.testutil.DumpFileAsserts) PlaybackOutput(com.google.android.exoplayer2.robolectric.PlaybackOutput) Assert(org.junit.Assert) Assertions.checkNotNull(com.google.android.exoplayer2.util.Assertions.checkNotNull) Mockito.mock(org.mockito.Mockito.mock) AnalyticsListener(com.google.android.exoplayer2.analytics.AnalyticsListener) CapturingRenderersFactory(com.google.android.exoplayer2.testutil.CapturingRenderersFactory) FakeClock(com.google.android.exoplayer2.testutil.FakeClock) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) Surface(android.view.Surface) PlaybackOutput(com.google.android.exoplayer2.robolectric.PlaybackOutput) SurfaceTexture(android.graphics.SurfaceTexture) ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState) DefaultMediaSourceFactory(com.google.android.exoplayer2.source.DefaultMediaSourceFactory) Test(org.junit.Test)

Example 38 with FakeClock

use of com.google.android.exoplayer2.testutil.FakeClock in project ExoPlayer by google.

the class FakeClockTest method createHandler_withIsAutoAdvancing_advancesTimeToNextMessages.

@Test
public void createHandler_withIsAutoAdvancing_advancesTimeToNextMessages() {
    HandlerThread handlerThread = new HandlerThread("FakeClockTest");
    handlerThread.start();
    FakeClock fakeClock = new FakeClock(/* initialTimeMs= */
    0, /* isAutoAdvancing= */
    true);
    HandlerWrapper handler = fakeClock.createHandler(handlerThread.getLooper(), /* callback= */
    null);
    // Post a series of immediate and delayed messages.
    ArrayList<Long> clockTimes = new ArrayList<>();
    handler.post(() -> {
        handler.postDelayed(() -> clockTimes.add(fakeClock.elapsedRealtime()), /* delayMs= */
        100);
        handler.postDelayed(() -> clockTimes.add(fakeClock.elapsedRealtime()), /* delayMs= */
        50);
        handler.post(() -> clockTimes.add(fakeClock.elapsedRealtime()));
        handler.postDelayed(() -> {
            clockTimes.add(fakeClock.elapsedRealtime());
            handler.postDelayed(() -> clockTimes.add(fakeClock.elapsedRealtime()), /* delayMs= */
            50);
        }, /* delayMs= */
        20);
    });
    ShadowLooper.idleMainLooper();
    shadowOf(handler.getLooper()).idle();
    assertThat(clockTimes).containsExactly(0L, 20L, 50L, 70L, 100L).inOrder();
}
Also used : HandlerThread(android.os.HandlerThread) ArrayList(java.util.ArrayList) HandlerWrapper(com.google.android.exoplayer2.util.HandlerWrapper) Test(org.junit.Test)

Example 39 with FakeClock

use of com.google.android.exoplayer2.testutil.FakeClock in project ExoPlayer by google.

the class FakeClockTest method createHandler_blockingThreadWithOnBusyWaiting_canBeUnblockedByOtherThread.

@Test
public void createHandler_blockingThreadWithOnBusyWaiting_canBeUnblockedByOtherThread() {
    HandlerThread handlerThread1 = new HandlerThread("FakeClockTest");
    handlerThread1.start();
    HandlerThread handlerThread2 = new HandlerThread("FakeClockTest");
    handlerThread2.start();
    FakeClock fakeClock = new FakeClock(/* initialTimeMs= */
    0, /* isAutoAdvancing= */
    true);
    HandlerWrapper handler1 = fakeClock.createHandler(handlerThread1.getLooper(), /* callback= */
    null);
    HandlerWrapper handler2 = fakeClock.createHandler(handlerThread2.getLooper(), /* callback= */
    null);
    ArrayList<Integer> executionOrder = new ArrayList<>();
    handler1.post(() -> {
        executionOrder.add(1);
        ConditionVariable blockingCondition = new ConditionVariable();
        handler2.postDelayed(() -> {
            executionOrder.add(2);
            blockingCondition.open();
        }, /* delayMs= */
        50);
        handler1.post(() -> executionOrder.add(4));
        fakeClock.onThreadBlocked();
        blockingCondition.block();
        executionOrder.add(3);
    });
    ShadowLooper.idleMainLooper();
    shadowOf(handler1.getLooper()).idle();
    shadowOf(handler2.getLooper()).idle();
    assertThat(executionOrder).containsExactly(1, 2, 3, 4).inOrder();
}
Also used : ConditionVariable(android.os.ConditionVariable) HandlerThread(android.os.HandlerThread) ArrayList(java.util.ArrayList) HandlerWrapper(com.google.android.exoplayer2.util.HandlerWrapper) Test(org.junit.Test)

Example 40 with FakeClock

use of com.google.android.exoplayer2.testutil.FakeClock in project ExoPlayer by google.

the class FakeClockTest method createHandler_removeAllMessages_removesAllMessages.

@Test
public void createHandler_removeAllMessages_removesAllMessages() {
    HandlerThread handlerThread = new HandlerThread("FakeClockTest");
    handlerThread.start();
    FakeClock fakeClock = new FakeClock(/* initialTimeMs= */
    0);
    TestCallback callback = new TestCallback();
    HandlerWrapper handler = fakeClock.createHandler(handlerThread.getLooper(), callback);
    TestCallback otherCallback = new TestCallback();
    HandlerWrapper otherHandler = fakeClock.createHandler(handlerThread.getLooper(), otherCallback);
    TestRunnable testRunnable1 = new TestRunnable();
    TestRunnable testRunnable2 = new TestRunnable();
    Object messageToken = new Object();
    handler.obtainMessage(/* what= */
    1, /* obj= */
    messageToken).sendToTarget();
    handler.sendEmptyMessageDelayed(/* what= */
    2, /* delayMs= */
    50);
    handler.post(testRunnable1);
    handler.postDelayed(testRunnable2, /* delayMs= */
    25);
    handler.sendEmptyMessage(/* what= */
    3);
    otherHandler.sendEmptyMessage(/* what= */
    1);
    handler.removeCallbacksAndMessages(/* token= */
    null);
    fakeClock.advanceTime(50);
    ShadowLooper.idleMainLooper();
    shadowOf(handlerThread.getLooper()).idle();
    assertThat(callback.messages).isEmpty();
    assertThat(testRunnable1.hasRun).isFalse();
    assertThat(testRunnable2.hasRun).isFalse();
    // Assert that message on other handler wasn't removed.
    assertThat(otherCallback.messages).containsExactly(new MessageData(/* what= */
    1, /* arg1= */
    0, /* arg2= */
    0, /* obj=*/
    null));
}
Also used : HandlerThread(android.os.HandlerThread) HandlerWrapper(com.google.android.exoplayer2.util.HandlerWrapper) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)44 FakeClock (com.google.android.exoplayer2.testutil.FakeClock)39 ExoPlayer (com.google.android.exoplayer2.ExoPlayer)23 Context (android.content.Context)21 PlaybackOutput (com.google.android.exoplayer2.robolectric.PlaybackOutput)21 CapturingRenderersFactory (com.google.android.exoplayer2.testutil.CapturingRenderersFactory)21 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)16 FakeTimeline (com.google.android.exoplayer2.testutil.FakeTimeline)15 SurfaceTexture (android.graphics.SurfaceTexture)13 Surface (android.view.Surface)13 TestExoPlayerBuilder (com.google.android.exoplayer2.testutil.TestExoPlayerBuilder)12 SinglePeriodTimeline (com.google.android.exoplayer2.source.SinglePeriodTimeline)10 TimelineWindowDefinition (com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition)10 NoUidTimeline (com.google.android.exoplayer2.testutil.NoUidTimeline)10 HandlerThread (android.os.HandlerThread)9 TestPlayerRunHelper.playUntilStartOfMediaItem (com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilStartOfMediaItem)9 HandlerWrapper (com.google.android.exoplayer2.util.HandlerWrapper)9 MediaItem (com.google.android.exoplayer2.MediaItem)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 ApplicationProvider (androidx.test.core.app.ApplicationProvider)5