diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdPlaybackStateFactory.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdPlaybackStateFactory.java new file mode 100644 index 0000000000..3c1b6954aa --- /dev/null +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdPlaybackStateFactory.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.ext.ima; + +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.source.ads.AdPlaybackState; +import java.util.Arrays; +import java.util.List; + +/** + * Static utility class for constructing {@link AdPlaybackState} instances from IMA-specific data. + */ +/* package */ final class AdPlaybackStateFactory { + private AdPlaybackStateFactory() {} + + /** + * Construct an {@link AdPlaybackState} from the provided {@code cuePoints}. + * + * @param cuePoints The cue points of the ads in seconds. + * @return The {@link AdPlaybackState}. + */ + public static AdPlaybackState fromCuePoints(List cuePoints) { + if (cuePoints.isEmpty()) { + // If no cue points are specified, there is a preroll ad. + return new AdPlaybackState(/* adGroupTimesUs...= */ 0); + } + + int count = cuePoints.size(); + long[] adGroupTimesUs = new long[count]; + int adGroupIndex = 0; + for (int i = 0; i < count; i++) { + double cuePoint = cuePoints.get(i); + if (cuePoint == -1.0) { + adGroupTimesUs[count - 1] = C.TIME_END_OF_SOURCE; + } else { + adGroupTimesUs[adGroupIndex++] = (long) (C.MICROS_PER_SECOND * cuePoint); + } + } + // Cue points may be out of order, so sort them. + Arrays.sort(adGroupTimesUs, 0, adGroupIndex); + return new AdPlaybackState(adGroupTimesUs); + } +} diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index 3bb8d9f386..f4d78893a9 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -662,7 +662,7 @@ public final class ImaAdsLoader adsManager.resume(); } } else if (adsManager != null) { - adPlaybackState = new AdPlaybackState(getAdGroupTimesUs(adsManager.getAdCuePoints())); + adPlaybackState = AdPlaybackStateFactory.fromCuePoints(adsManager.getAdCuePoints()); updateAdPlaybackState(); } else { // Ads haven't loaded yet, so request them. @@ -739,7 +739,7 @@ public final class ImaAdsLoader if (player != null) { // If a player is attached already, start playback immediately. try { - adPlaybackState = new AdPlaybackState(getAdGroupTimesUs(adsManager.getAdCuePoints())); + adPlaybackState = AdPlaybackStateFactory.fromCuePoints(adsManager.getAdCuePoints()); hasAdPlaybackState = true; updateAdPlaybackState(); } catch (RuntimeException e) { @@ -1545,28 +1545,6 @@ public final class ImaAdsLoader : timeline.getPeriod(/* periodIndex= */ 0, period).getPositionInWindowMs()); } - private static long[] getAdGroupTimesUs(List cuePoints) { - if (cuePoints.isEmpty()) { - // If no cue points are specified, there is a preroll ad. - return new long[] {0}; - } - - int count = cuePoints.size(); - long[] adGroupTimesUs = new long[count]; - int adGroupIndex = 0; - for (int i = 0; i < count; i++) { - double cuePoint = cuePoints.get(i); - if (cuePoint == -1.0) { - adGroupTimesUs[count - 1] = C.TIME_END_OF_SOURCE; - } else { - adGroupTimesUs[adGroupIndex++] = (long) (C.MICROS_PER_SECOND * cuePoint); - } - } - // Cue points may be out of order, so sort them. - Arrays.sort(adGroupTimesUs, 0, adGroupIndex); - return adGroupTimesUs; - } - private static boolean isAdGroupLoadError(AdError adError) { // TODO: Find out what other errors need to be handled (if any), and whether each one relates to // a single ad, ad group or the whole timeline. diff --git a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java index a8317f8cc4..88e712f6ea 100644 --- a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java +++ b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java @@ -58,6 +58,7 @@ import com.google.android.exoplayer2.source.ads.SinglePeriodAdTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.upstream.DataSpec; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.time.Duration; @@ -93,7 +94,7 @@ public final class ImaAdsLoaderTest { private static final Uri TEST_URI = Uri.EMPTY; private static final AdMediaInfo TEST_AD_MEDIA_INFO = new AdMediaInfo(TEST_URI.toString()); private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND; - private static final Float[] PREROLL_CUE_POINTS_SECONDS = new Float[] {0f}; + private static final ImmutableList PREROLL_CUE_POINTS_SECONDS = ImmutableList.of(0f); @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @@ -256,7 +257,7 @@ public final class ImaAdsLoaderTest { @Test public void playback_withPostrollFetchError_marksAdAsInErrorState() { - setupPlayback(CONTENT_TIMELINE, new Float[] {-1f}); + setupPlayback(CONTENT_TIMELINE, ImmutableList.of(-1f)); // Simulate loading an empty postroll ad. imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -275,9 +276,9 @@ public final class ImaAdsLoaderTest { public void playback_withAdNotPreloadingBeforeTimeout_hasNoError() { // Simulate an ad at 2 seconds. long adGroupPositionInWindowUs = 2 * C.MICROS_PER_SECOND; - setupPlayback( - CONTENT_TIMELINE, - new Float[] {(float) adGroupPositionInWindowUs / C.MICROS_PER_SECOND}); + long adGroupTimeUs = adGroupPositionInWindowUs; + ImmutableList cuePoints = ImmutableList.of((float) adGroupTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); // Advance playback to just before the midroll and simulate buffering. imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -289,7 +290,7 @@ public final class ImaAdsLoaderTest { assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ adGroupPositionInWindowUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)); } @@ -297,9 +298,9 @@ public final class ImaAdsLoaderTest { public void playback_withAdNotPreloadingAfterTimeout_hasErrorAdGroup() { // Simulate an ad at 2 seconds. long adGroupPositionInWindowUs = 2 * C.MICROS_PER_SECOND; - setupPlayback( - CONTENT_TIMELINE, - new Float[] {(float) adGroupPositionInWindowUs / C.MICROS_PER_SECOND}); + long adGroupTimeUs = adGroupPositionInWindowUs; + ImmutableList cuePoints = ImmutableList.of((float) adGroupTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); // Advance playback to just before the midroll and simulate buffering. imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -311,7 +312,7 @@ public final class ImaAdsLoaderTest { assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ adGroupPositionInWindowUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}}) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) @@ -321,10 +322,10 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackBeforeMidroll_playsPreroll() { long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long midrollPeriodTimeUs = - midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; - setupPlayback( - CONTENT_TIMELINE, new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND}); + long midrollPeriodTimeUs = midrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs) - 1_000); imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -332,17 +333,17 @@ public final class ImaAdsLoaderTest { verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble()); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)); } @Test public void resumePlaybackAtMidroll_skipsPreroll() { long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long midrollPeriodTimeUs = - midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; - setupPlayback( - CONTENT_TIMELINE, new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND}); + long midrollPeriodTimeUs = midrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs)); imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -355,7 +356,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withSkippedAdGroup(/* adGroupIndex= */ 0)); } @@ -363,10 +364,10 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackAfterMidroll_skipsPreroll() { long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long midrollPeriodTimeUs = - midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; - setupPlayback( - CONTENT_TIMELINE, new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND}); + long midrollPeriodTimeUs = midrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs) + 1_000); imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -379,7 +380,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withSkippedAdGroup(/* adGroupIndex= */ 0)); } @@ -387,19 +388,14 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackBeforeSecondMidroll_playsFirstMidroll() { long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long firstMidrollPeriodTimeUs = - firstMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs; long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND; - long secondMidrollPeriodTimeUs = - secondMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; - setupPlayback( - CONTENT_TIMELINE, - new Float[] { - (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, - (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND - }); + long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of( + (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, + (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); fakeExoPlayer.setPlayingContentPosition(C.usToMs(secondMidrollWindowTimeUs) - 1_000); imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -407,27 +403,21 @@ public final class ImaAdsLoaderTest { verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble()); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState( - /* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)); } @Test public void resumePlaybackAtSecondMidroll_skipsFirstMidroll() { long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long firstMidrollPeriodTimeUs = - firstMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs; long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND; - long secondMidrollPeriodTimeUs = - secondMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; - setupPlayback( - CONTENT_TIMELINE, - new Float[] { - (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, - (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND - }); + long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of( + (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, + (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND); + setupPlayback(CONTENT_TIMELINE, cuePoints); fakeExoPlayer.setPlayingContentPosition(C.usToMs(secondMidrollWindowTimeUs)); imaAdsLoader.start(adsLoaderListener, adViewProvider); @@ -440,8 +430,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState( - /* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withSkippedAdGroup(/* adGroupIndex= */ 0)); } @@ -449,11 +438,12 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackBeforeMidroll_withoutPlayAdBeforeStartPosition_skipsPreroll() { long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long midrollPeriodTimeUs = - midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long midrollPeriodTimeUs = midrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND); setupPlayback( CONTENT_TIMELINE, - new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND}, + cuePoints, new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext()) .setPlayAdBeforeStartPosition(false) .setImaFactory(mockImaFactory) @@ -471,7 +461,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withSkippedAdGroup(/* adGroupIndex= */ 0) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)); } @@ -479,11 +469,12 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackAtMidroll_withoutPlayAdBeforeStartPosition_skipsPreroll() { long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long midrollPeriodTimeUs = - midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long midrollPeriodTimeUs = midrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND); setupPlayback( CONTENT_TIMELINE, - new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND}, + cuePoints, new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext()) .setPlayAdBeforeStartPosition(false) .setImaFactory(mockImaFactory) @@ -501,7 +492,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withSkippedAdGroup(/* adGroupIndex= */ 0)); } @@ -509,11 +500,12 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackAfterMidroll_withoutPlayAdBeforeStartPosition_skipsMidroll() { long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long midrollPeriodTimeUs = - midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long midrollPeriodTimeUs = midrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND); setupPlayback( CONTENT_TIMELINE, - new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND}, + cuePoints, new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext()) .setPlayAdBeforeStartPosition(false) .setImaFactory(mockImaFactory) @@ -526,7 +518,7 @@ public final class ImaAdsLoaderTest { verify(mockAdsManager).destroy(); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withSkippedAdGroup(/* adGroupIndex= */ 0) .withSkippedAdGroup(/* adGroupIndex= */ 1)); @@ -536,19 +528,16 @@ public final class ImaAdsLoaderTest { public void resumePlaybackBeforeSecondMidroll_withoutPlayAdBeforeStartPosition_skipsFirstMidroll() { long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long firstMidrollPeriodTimeUs = - firstMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs; long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND; - long secondMidrollPeriodTimeUs = - secondMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of( + (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, + (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND); setupPlayback( CONTENT_TIMELINE, - new Float[] { - (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, - (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND - }, + cuePoints, new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext()) .setPlayAdBeforeStartPosition(false) .setImaFactory(mockImaFactory) @@ -566,8 +555,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState( - /* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withSkippedAdGroup(/* adGroupIndex= */ 0) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)); } @@ -575,19 +563,16 @@ public final class ImaAdsLoaderTest { @Test public void resumePlaybackAtSecondMidroll_withoutPlayAdBeforeStartPosition_skipsFirstMidroll() { long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND; - long firstMidrollPeriodTimeUs = - firstMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs; long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND; - long secondMidrollPeriodTimeUs = - secondMidrollWindowTimeUs - + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US; + long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs; + ImmutableList cuePoints = + ImmutableList.of( + (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, + (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND); setupPlayback( CONTENT_TIMELINE, - new Float[] { - (float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND, - (float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND - }, + cuePoints, new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext()) .setPlayAdBeforeStartPosition(false) .setImaFactory(mockImaFactory) @@ -605,8 +590,7 @@ public final class ImaAdsLoaderTest { .of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( - new AdPlaybackState( - /* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs) + AdPlaybackStateFactory.fromCuePoints(cuePoints) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withSkippedAdGroup(/* adGroupIndex= */ 0)); } @@ -623,7 +607,7 @@ public final class ImaAdsLoaderTest { inOrder.verify(mockAdDisplayContainer).unregisterAllVideoControlsOverlays(); } - private void setupPlayback(Timeline contentTimeline, Float[] cuePoints) { + private void setupPlayback(Timeline contentTimeline, List cuePoints) { setupPlayback( contentTimeline, cuePoints, @@ -634,10 +618,10 @@ public final class ImaAdsLoaderTest { } private void setupPlayback( - Timeline contentTimeline, Float[] cuePoints, ImaAdsLoader imaAdsLoader) { + Timeline contentTimeline, List cuePoints, ImaAdsLoader imaAdsLoader) { fakeExoPlayer = new FakePlayer(); adsLoaderListener = new TestAdsLoaderListener(fakeExoPlayer, contentTimeline); - when(mockAdsManager.getAdCuePoints()).thenReturn(Arrays.asList(cuePoints)); + when(mockAdsManager.getAdCuePoints()).thenReturn(cuePoints); this.imaAdsLoader = imaAdsLoader; imaAdsLoader.setPlayer(fakeExoPlayer); }