Commit d1b90060 by tonihei Committed by Andrew Lewis

Add test to ensure AdsLoader is initialized.

This tests explicitly that initialization happens even if the Timeline
is a placeholder.

No other change is needed. While the Timeline is still a placeholder
ImaAdsLoader.getCurrentPeriodPosition will return 0 and trigger
pre-rolls (intended behaviour) and it doesn't matter whether the
actual initial period position may be somewhere else.

PiperOrigin-RevId: 298833867
parent 03be1551
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.ext.ima; package com.google.android.exoplayer2.ext.ima;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
...@@ -39,11 +40,14 @@ import com.google.android.exoplayer2.C; ...@@ -39,11 +40,14 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.SinglePeriodTimeline; import com.google.android.exoplayer2.Timeline.Period;
import com.google.android.exoplayer2.ext.ima.ImaAdsLoader.ImaFactory;
import com.google.android.exoplayer2.source.MaskingMediaSource;
import com.google.android.exoplayer2.source.ads.AdPlaybackState; import com.google.android.exoplayer2.source.ads.AdPlaybackState;
import com.google.android.exoplayer2.source.ads.AdsLoader; import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException; import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException;
import com.google.android.exoplayer2.source.ads.SinglePeriodAdTimeline; import com.google.android.exoplayer2.source.ads.SinglePeriodAdTimeline;
import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
...@@ -63,8 +67,11 @@ public class ImaAdsLoaderTest { ...@@ -63,8 +67,11 @@ public class ImaAdsLoaderTest {
private static final long CONTENT_DURATION_US = 10 * C.MICROS_PER_SECOND; private static final long CONTENT_DURATION_US = 10 * C.MICROS_PER_SECOND;
private static final Timeline CONTENT_TIMELINE = private static final Timeline CONTENT_TIMELINE =
new SinglePeriodTimeline( new FakeTimeline(
CONTENT_DURATION_US, /* isSeekable= */ true, /* isDynamic= */ false, /* isLive= */ false); new FakeTimeline.TimelineWindowDefinition(
/* isSeekable= */ true, /* isDynamic= */ false, CONTENT_DURATION_US));
private static final long CONTENT_PERIOD_DURATION_US =
CONTENT_TIMELINE.getPeriod(/* periodIndex= */ 0, new Period()).durationUs;
private static final Uri TEST_URI = Uri.EMPTY; private static final Uri TEST_URI = Uri.EMPTY;
private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND; private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND;
private static final long[][] PREROLL_ADS_DURATIONS_US = new long[][] {{TEST_AD_DURATION_US}}; private static final long[][] PREROLL_ADS_DURATIONS_US = new long[][] {{TEST_AD_DURATION_US}};
...@@ -72,11 +79,11 @@ public class ImaAdsLoaderTest { ...@@ -72,11 +79,11 @@ public class ImaAdsLoaderTest {
private static final FakeAd UNSKIPPABLE_AD = private static final FakeAd UNSKIPPABLE_AD =
new FakeAd(/* skippable= */ false, /* podIndex= */ 0, /* totalAds= */ 1, /* adPosition= */ 1); new FakeAd(/* skippable= */ false, /* podIndex= */ 0, /* totalAds= */ 1, /* adPosition= */ 1);
private @Mock ImaSdkSettings imaSdkSettings; @Mock private ImaSdkSettings imaSdkSettings;
private @Mock AdsRenderingSettings adsRenderingSettings; @Mock private AdsRenderingSettings adsRenderingSettings;
private @Mock AdDisplayContainer adDisplayContainer; @Mock private AdDisplayContainer adDisplayContainer;
private @Mock AdsManager adsManager; @Mock private AdsManager adsManager;
private SingletonImaFactory testImaFactory; @Mock private ImaFactory mockImaFactory;
private ViewGroup adViewGroup; private ViewGroup adViewGroup;
private View adOverlayView; private View adOverlayView;
private AdsLoader.AdViewProvider adViewProvider; private AdsLoader.AdViewProvider adViewProvider;
...@@ -89,13 +96,11 @@ public class ImaAdsLoaderTest { ...@@ -89,13 +96,11 @@ public class ImaAdsLoaderTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
FakeAdsRequest fakeAdsRequest = new FakeAdsRequest(); FakeAdsRequest fakeAdsRequest = new FakeAdsRequest();
FakeAdsLoader fakeAdsLoader = new FakeAdsLoader(imaSdkSettings, adsManager); FakeAdsLoader fakeAdsLoader = new FakeAdsLoader(imaSdkSettings, adsManager);
testImaFactory = when(mockImaFactory.createAdDisplayContainer()).thenReturn(adDisplayContainer);
new SingletonImaFactory( when(mockImaFactory.createAdsRenderingSettings()).thenReturn(adsRenderingSettings);
imaSdkSettings, when(mockImaFactory.createAdsRequest()).thenReturn(fakeAdsRequest);
adsRenderingSettings, when(mockImaFactory.createImaSdkSettings()).thenReturn(imaSdkSettings);
adDisplayContainer, when(mockImaFactory.createAdsLoader(any(), any(), any())).thenReturn(fakeAdsLoader);
fakeAdsRequest,
fakeAdsLoader);
adViewGroup = new FrameLayout(ApplicationProvider.getApplicationContext()); adViewGroup = new FrameLayout(ApplicationProvider.getApplicationContext());
adOverlayView = new View(ApplicationProvider.getApplicationContext()); adOverlayView = new View(ApplicationProvider.getApplicationContext());
adViewProvider = adViewProvider =
...@@ -137,15 +142,25 @@ public class ImaAdsLoaderTest { ...@@ -137,15 +142,25 @@ public class ImaAdsLoaderTest {
} }
@Test @Test
public void testStart_withPlaceholderContent_initializedAdsLoader() {
Timeline placeholderTimeline = new MaskingMediaSource.DummyTimeline(/* tag= */ null);
setupPlayback(placeholderTimeline, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
imaAdsLoader.start(adsLoaderListener, adViewProvider);
// We'll only create the rendering settings when initializing the ads loader.
verify(mockImaFactory).createAdsRenderingSettings();
}
@Test
public void testStart_updatesAdPlaybackState() { public void testStart_updatesAdPlaybackState() {
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
imaAdsLoader.start(adsLoaderListener, adViewProvider); imaAdsLoader.start(adsLoaderListener, adViewProvider);
assertThat(adsLoaderListener.adPlaybackState) assertThat(adsLoaderListener.adPlaybackState)
.isEqualTo( .isEqualTo(
new AdPlaybackState(/* adGroupTimesUs= */ 0) new AdPlaybackState(/* adGroupTimesUs...= */ 0)
.withAdDurationsUs(PREROLL_ADS_DURATIONS_US) .withAdDurationsUs(PREROLL_ADS_DURATIONS_US)
.withContentDurationUs(CONTENT_DURATION_US)); .withContentDurationUs(CONTENT_PERIOD_DURATION_US));
} }
@Test @Test
...@@ -213,8 +228,8 @@ public class ImaAdsLoaderTest { ...@@ -213,8 +228,8 @@ public class ImaAdsLoaderTest {
// Verify that the preroll ad has been marked as played. // Verify that the preroll ad has been marked as played.
assertThat(adsLoaderListener.adPlaybackState) assertThat(adsLoaderListener.adPlaybackState)
.isEqualTo( .isEqualTo(
new AdPlaybackState(/* adGroupTimesUs= */ 0) new AdPlaybackState(/* adGroupTimesUs...= */ 0)
.withContentDurationUs(CONTENT_DURATION_US) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)
.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1)
.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, /* uri= */ TEST_URI) .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, /* uri= */ TEST_URI)
.withAdDurationsUs(PREROLL_ADS_DURATIONS_US) .withAdDurationsUs(PREROLL_ADS_DURATIONS_US)
...@@ -240,7 +255,7 @@ public class ImaAdsLoaderTest { ...@@ -240,7 +255,7 @@ public class ImaAdsLoaderTest {
when(adsManager.getAdCuePoints()).thenReturn(Arrays.asList(cuePoints)); when(adsManager.getAdCuePoints()).thenReturn(Arrays.asList(cuePoints));
imaAdsLoader = imaAdsLoader =
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext()) new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
.setImaFactory(testImaFactory) .setImaFactory(mockImaFactory)
.setImaSdkSettings(imaSdkSettings) .setImaSdkSettings(imaSdkSettings)
.buildForAdTag(TEST_URI); .buildForAdTag(TEST_URI);
imaAdsLoader.setPlayer(fakeExoPlayer); imaAdsLoader.setPlayer(fakeExoPlayer);
......
/*
* Copyright (C) 2018 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 android.content.Context;
import com.google.ads.interactivemedia.v3.api.AdDisplayContainer;
import com.google.ads.interactivemedia.v3.api.AdsLoader;
import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings;
import com.google.ads.interactivemedia.v3.api.AdsRequest;
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
/** {@link ImaAdsLoader.ImaFactory} that returns provided instances from each getter, for tests. */
final class SingletonImaFactory implements ImaAdsLoader.ImaFactory {
private final ImaSdkSettings imaSdkSettings;
private final AdsRenderingSettings adsRenderingSettings;
private final AdDisplayContainer adDisplayContainer;
private final AdsRequest adsRequest;
private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader;
public SingletonImaFactory(
ImaSdkSettings imaSdkSettings,
AdsRenderingSettings adsRenderingSettings,
AdDisplayContainer adDisplayContainer,
AdsRequest adsRequest,
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader) {
this.imaSdkSettings = imaSdkSettings;
this.adsRenderingSettings = adsRenderingSettings;
this.adDisplayContainer = adDisplayContainer;
this.adsRequest = adsRequest;
this.adsLoader = adsLoader;
}
@Override
public ImaSdkSettings createImaSdkSettings() {
return imaSdkSettings;
}
@Override
public AdsRenderingSettings createAdsRenderingSettings() {
return adsRenderingSettings;
}
@Override
public AdDisplayContainer createAdDisplayContainer() {
return adDisplayContainer;
}
@Override
public AdsRequest createAdsRequest() {
return adsRequest;
}
@Override
public AdsLoader createAdsLoader(
Context context, ImaSdkSettings imaSdkSettings, AdDisplayContainer adDisplayContainer) {
return adsLoader;
}
}
...@@ -293,7 +293,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -293,7 +293,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
} }
/** Dummy placeholder timeline with one dynamic window with a period of indeterminate duration. */ /** Dummy placeholder timeline with one dynamic window with a period of indeterminate duration. */
private static final class DummyTimeline extends Timeline { public static final class DummyTimeline extends Timeline {
@Nullable private final Object tag; @Nullable private final Object tag;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment