Skip to content

Commit

Permalink
Improve ad loader listening in ImaAdsLoaderTest
Browse files Browse the repository at this point in the history
It is more realistic for each source to have its own listener and to share
`TimelineWindowDefinition`s between them.

Issue: #3750
PiperOrigin-RevId: 347398769
  • Loading branch information
andrewlewis authored and christosts committed Dec 17, 2020
1 parent 6114c89 commit 4139ee5
Showing 1 changed file with 65 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public final class ImaAdsLoaderTest {
@Mock private AdPodInfo mockAdPodInfo;
@Mock private Ad mockPrerollSingleAd;

private TimelineWindowDefinition[] timelineWindowDefinitions;
private AdsMediaSource adsMediaSource;
private ViewGroup adViewGroup;
private AdsLoader.AdViewProvider adViewProvider;
Expand Down Expand Up @@ -183,7 +184,9 @@ public ImmutableList<AdsLoader.OverlayInfo> getAdOverlayInfos() {
new DefaultMediaSourceFactory((Context) getApplicationContext()),
imaAdsLoader,
adViewProvider);
adsLoaderListener = new TestAdsLoaderListener(getInitialTimelineWindowDefinition(TEST_ADS_ID));
timelineWindowDefinitions =
new TimelineWindowDefinition[] {getInitialTimelineWindowDefinition(TEST_ADS_ID)};
adsLoaderListener = new TestAdsLoaderListener(/* periodIndex= */ 0);
when(mockAdsManager.getAdCuePoints()).thenReturn(PREROLL_CUE_POINTS_SECONDS);
}

Expand Down Expand Up @@ -224,9 +227,10 @@ public void startForAudioOnlyAds_createsAudioOnlyAdDisplayContainer() {

@Test
public void start_withPlaceholderContent_initializedAdsLoader() {
adsLoaderListener =
new TestAdsLoaderListener(
getInitialTimelineWindowDefinition(TEST_ADS_ID, /* isPlaceholder= */ true));
timelineWindowDefinitions =
new TimelineWindowDefinition[] {
getInitialTimelineWindowDefinition(TEST_ADS_ID, /* isPlaceholder= */ true)
};

when(mockAdsManager.getAdCuePoints()).thenReturn(PREROLL_CUE_POINTS_SECONDS);
imaAdsLoader.start(
Expand All @@ -241,7 +245,7 @@ public void start_updatesAdPlaybackState() {
imaAdsLoader.start(
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);

assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0)
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
Expand Down Expand Up @@ -312,7 +316,7 @@ public void playback_withPrerollAd_marksAdAsPlayed() {
adEventListener.onAdEvent(getAdEvent(AdEventType.CONTENT_RESUME_REQUESTED, /* ad= */ null));

// Verify that the preroll ad has been marked as played.
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0)
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand All @@ -336,7 +340,7 @@ public void playback_withMidrollFetchError_marksAdAsInErrorState() {
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
adEventListener.onAdEvent(mockMidrollFetchErrorAdEvent);

assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 20_500_000)
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -384,7 +388,7 @@ public void playback_withPostrollFetchError_marksAdAsInErrorState() {
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
adEventListener.onAdEvent(mockPostrollFetchErrorAdEvent);

assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ C.TIME_END_OF_SOURCE)
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -412,7 +416,7 @@ public void playback_withAdNotPreloadingBeforeTimeout_hasNoError() {
ShadowSystemClock.advanceBy(Duration.ofSeconds(1));
contentProgressProvider.getContentProgress();

assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
Expand All @@ -437,7 +441,7 @@ public void playback_withAdNotPreloadingAfterTimeout_hasErrorAdGroup() {
ShadowSystemClock.advanceBy(Duration.ofSeconds(5));
contentProgressProvider.getContentProgress();

assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -537,7 +541,7 @@ public void resumePlaybackBeforeMidroll_playsPreroll() {
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);

verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble());
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
Expand All @@ -562,7 +566,7 @@ public void resumePlaybackAtMidroll_skipsPreroll() {
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand All @@ -589,7 +593,7 @@ public void resumePlaybackAfterMidroll_skipsPreroll() {
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -618,7 +622,7 @@ public void resumePlaybackBeforeSecondMidroll_playsFirstMidroll() {
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);

verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble());
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
Expand Down Expand Up @@ -650,7 +654,7 @@ public void resumePlaybackAtSecondMidroll_skipsFirstMidroll() {
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -692,7 +696,7 @@ public void resumePlaybackBeforeMidroll_withoutPlayAdBeforeStartPosition_skipsPr
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1d)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withSkippedAdGroup(/* adGroupIndex= */ 0)
Expand Down Expand Up @@ -733,7 +737,7 @@ public void resumePlaybackAtMidroll_withoutPlayAdBeforeStartPosition_skipsPrerol
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1d)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -770,7 +774,7 @@ public void resumePlaybackAfterMidroll_withoutPlayAdBeforeStartPosition_skipsMid
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);

verify(mockAdsManager).destroy();
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -821,7 +825,7 @@ public void resumePlaybackAfterMidroll_withoutPlayAdBeforeStartPosition_skipsMid
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1d)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withSkippedAdGroup(/* adGroupIndex= */ 0)
Expand Down Expand Up @@ -869,7 +873,7 @@ public void resumePlaybackAtSecondMidroll_withoutPlayAdBeforeStartPosition_skips
assertThat(playAdsAfterTimeCaptor.getValue())
.isWithin(0.1d)
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand Down Expand Up @@ -998,7 +1002,7 @@ public double getTimeOffset() {
}
});

assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints))
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand All @@ -1018,10 +1022,12 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTag() {
new DefaultMediaSourceFactory((Context) getApplicationContext()),
imaAdsLoader,
adViewProvider);
adsLoaderListener =
new TestAdsLoaderListener(
getInitialTimelineWindowDefinition(TEST_ADS_ID),
getInitialTimelineWindowDefinition(secondAdsId));
timelineWindowDefinitions =
new TimelineWindowDefinition[] {
getInitialTimelineWindowDefinition(TEST_ADS_ID),
getInitialTimelineWindowDefinition(secondAdsId)
};
TestAdsLoaderListener secondAdsLoaderListener = new TestAdsLoaderListener(/* periodIndex= */ 1);

// Load and play the preroll ad then content.
imaAdsLoader.start(
Expand All @@ -1047,10 +1053,10 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTag() {

// Simulate starting to buffer the second ads media source.
imaAdsLoader.start(
secondAdsMediaSource, TEST_DATA_SPEC, secondAdsId, adViewProvider, adsLoaderListener);
secondAdsMediaSource, TEST_DATA_SPEC, secondAdsId, adViewProvider, secondAdsLoaderListener);

// Verify that the preroll ad has been marked as played.
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0)
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand All @@ -1060,7 +1066,7 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTag() {
.withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0)
.withAdResumePositionUs(/* adResumePositionUs= */ 0));
// Verify that the second source's ad cue points have preloaded.
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 1))
assertThat(getAdPlaybackState(/* periodIndex= */ 1))
.isEqualTo(new AdPlaybackState(secondAdsId, /* adGroupTimesUs...= */ 0));
}

Expand All @@ -1075,10 +1081,12 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTagWithBackgroundResu
new DefaultMediaSourceFactory((Context) getApplicationContext()),
imaAdsLoader,
adViewProvider);
adsLoaderListener =
new TestAdsLoaderListener(
getInitialTimelineWindowDefinition(TEST_ADS_ID),
getInitialTimelineWindowDefinition(secondAdsId));
timelineWindowDefinitions =
new TimelineWindowDefinition[] {
getInitialTimelineWindowDefinition(TEST_ADS_ID),
getInitialTimelineWindowDefinition(secondAdsId)
};
TestAdsLoaderListener secondAdsLoaderListener = new TestAdsLoaderListener(/* periodIndex= */ 1);

// Load and play the preroll ad then content.
imaAdsLoader.start(
Expand All @@ -1104,18 +1112,18 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTagWithBackgroundResu

// Simulate starting to buffer the second ads media source.
imaAdsLoader.start(
secondAdsMediaSource, TEST_DATA_SPEC, secondAdsId, adViewProvider, adsLoaderListener);
secondAdsMediaSource, TEST_DATA_SPEC, secondAdsId, adViewProvider, secondAdsLoaderListener);

// Simulate backgrounding/resuming.
imaAdsLoader.stop(adsMediaSource);
imaAdsLoader.stop(secondAdsMediaSource);
imaAdsLoader.start(
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
imaAdsLoader.start(
secondAdsMediaSource, TEST_DATA_SPEC, secondAdsId, adViewProvider, adsLoaderListener);
secondAdsMediaSource, TEST_DATA_SPEC, secondAdsId, adViewProvider, secondAdsLoaderListener);

// Verify that the preroll ad has been marked as played.
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 0))
assertThat(getAdPlaybackState(/* periodIndex= */ 0))
.isEqualTo(
new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0)
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
Expand All @@ -1125,7 +1133,7 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTagWithBackgroundResu
.withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0)
.withAdResumePositionUs(/* adResumePositionUs= */ 0));
// Verify that the second source's ad cue points have preloaded.
assertThat(adsLoaderListener.getAdPlaybackState(/* periodIndex= */ 1))
assertThat(getAdPlaybackState(/* periodIndex= */ 1))
.isEqualTo(new AdPlaybackState(secondAdsId, /* adGroupTimesUs...= */ 0));
}

Expand Down Expand Up @@ -1254,6 +1262,10 @@ private void setupMocks() {
when(mockPrerollSingleAd.getAdPodInfo()).thenReturn(mockAdPodInfo);
}

private AdPlaybackState getAdPlaybackState(int periodIndex) {
return timelineWindowDefinitions[periodIndex].adPlaybackState;
}

private static AdEvent getAdEvent(AdEventType adEventType, @Nullable Ad ad) {
return new AdEvent() {
@Override
Expand All @@ -1277,14 +1289,10 @@ public Map<String, String> getAdData() {
/** Ad loader event listener that forwards ad playback state to a fake player. */
private final class TestAdsLoaderListener implements AdsLoader.EventListener {

private final TimelineWindowDefinition[] timelineWindowDefinitions;
private final int periodIndex;

public TestAdsLoaderListener(TimelineWindowDefinition... timelineWindowDefinitions) {
this.timelineWindowDefinitions = timelineWindowDefinitions;
}

public AdPlaybackState getAdPlaybackState(int periodIndex) {
return timelineWindowDefinitions[periodIndex].adPlaybackState;
public TestAdsLoaderListener(int periodIndex) {
this.periodIndex = periodIndex;
}

@Override
Expand All @@ -1296,25 +1304,20 @@ public void onAdPlaybackState(AdPlaybackState adPlaybackState) {
}
adPlaybackState = adPlaybackState.withAdDurationsUs(adDurationsUs);

// Update the timeline window definition(s) to reflect the new ad playback state.
for (int i = 0; i < timelineWindowDefinitions.length; i++) {
TimelineWindowDefinition timelineWindowDefinition = timelineWindowDefinitions[i];
if (!Util.areEqual(timelineWindowDefinition.adPlaybackState.adsId, adPlaybackState.adsId)) {
continue;
}
timelineWindowDefinitions[i] =
new TimelineWindowDefinition(
timelineWindowDefinition.periodCount,
timelineWindowDefinition.id,
timelineWindowDefinition.isSeekable,
timelineWindowDefinition.isDynamic,
timelineWindowDefinition.isLive,
timelineWindowDefinition.isPlaceholder,
timelineWindowDefinition.durationUs,
timelineWindowDefinition.defaultPositionUs,
timelineWindowDefinition.windowOffsetInFirstPeriodUs,
adPlaybackState);
}
TimelineWindowDefinition timelineWindowDefinition = timelineWindowDefinitions[periodIndex];
assertThat(adPlaybackState.adsId).isEqualTo(timelineWindowDefinition.adPlaybackState.adsId);
timelineWindowDefinitions[periodIndex] =
new TimelineWindowDefinition(
timelineWindowDefinition.periodCount,
timelineWindowDefinition.id,
timelineWindowDefinition.isSeekable,
timelineWindowDefinition.isDynamic,
timelineWindowDefinition.isLive,
timelineWindowDefinition.isPlaceholder,
timelineWindowDefinition.durationUs,
timelineWindowDefinition.defaultPositionUs,
timelineWindowDefinition.windowOffsetInFirstPeriodUs,
adPlaybackState);
fakePlayer.updateTimeline(
new FakeTimeline(timelineWindowDefinitions), Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
}
Expand Down

0 comments on commit 4139ee5

Please sign in to comment.