diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java index 90d2901efc3..bdd34f6f047 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java @@ -965,7 +965,7 @@ private void loadAdInternal(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) { Uri adUri = Uri.parse(adMediaInfo.getUrl()); adPlaybackState = - adPlaybackState.withAdUri(adInfo.adGroupIndex, adInfo.adIndexInAdGroup, adUri); + adPlaybackState.withAvailableAdUri(adInfo.adGroupIndex, adInfo.adIndexInAdGroup, adUri); updateAdPlaybackState(); } 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 d3f945a29e0..aa541a75185 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 @@ -315,7 +315,7 @@ public void playback_withPrerollAd_marksAdAsPlayed() { new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) .withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}}) .withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0) .withAdResumePositionUs(/* adResumePositionUs= */ 0)); @@ -1063,7 +1063,7 @@ public double getTimeOffset() { new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints)) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) .withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}})); } @@ -1117,7 +1117,7 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTag() { new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) .withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}}) .withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0) .withAdResumePositionUs(/* adResumePositionUs= */ 0)); @@ -1184,7 +1184,7 @@ public void playbackWithTwoAdsMediaSources_preloadsSecondAdTagWithBackgroundResu new AdPlaybackState(TEST_ADS_ID, /* adGroupTimesUs...= */ 0) .withContentDurationUs(CONTENT_PERIOD_DURATION_US) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, TEST_URI) .withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}}) .withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0) .withAdResumePositionUs(/* adResumePositionUs= */ 0)); diff --git a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java index 738cb3f015b..7a4db08de6a 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java @@ -126,6 +126,9 @@ public int getFirstAdIndexToPlay() { * Returns the index of the next ad in the ad group that should be played after playing {@code * lastPlayedAdIndex}, or {@link #count} if no later ads should be played. If no ads have been * played, pass -1 to get the index of the first ad to play. + * + *

Note: {@linkplain #isServerSideInserted Server side inserted ads} are always considered + * playable. */ public int getNextAdIndexToPlay(@IntRange(from = -1) int lastPlayedAdIndex) { int nextAdIndexToPlay = lastPlayedAdIndex + 1; @@ -236,7 +239,7 @@ public AdGroup withAdUri(Uri uri, @IntRange(from = 0) int index) { @CheckResult public AdGroup withAdState(@AdState int state, @IntRange(from = 0) int index) { checkArgument(count == C.LENGTH_UNSET || index < count); - @AdState int[] states = copyStatesWithSpaceForAdCount(this.states, index + 1); + @AdState int[] states = copyStatesWithSpaceForAdCount(this.states, /* count= */ index + 1); checkArgument( states[index] == AD_STATE_UNAVAILABLE || states[index] == AD_STATE_AVAILABLE @@ -471,7 +474,7 @@ private static String keyForField(@AdGroup.FieldNumber int field) { */ public final long contentDurationUs; /** - * The number of ad groups the have been removed. Ad groups with indices between {@code 0} + * The number of ad groups that have been removed. Ad groups with indices between {@code 0} * (inclusive) and {@code removedAdGroupCount} (exclusive) will be empty and must not be modified * by any of the {@code with*} methods. */ @@ -640,18 +643,40 @@ public AdPlaybackState withAdCount( adsId, adGroups, adResumePositionUs, contentDurationUs, removedAdGroupCount); } - /** Returns an instance with the specified ad URI. */ + /** + * Returns an instance with the specified ad URI and the ad marked as {@linkplain + * #AD_STATE_AVAILABLE available}. + * + * @throws IllegalStateException If {@link Uri#EMPTY} is passed as argument for a client-side + * inserted ad group. + */ @CheckResult - public AdPlaybackState withAdUri( + public AdPlaybackState withAvailableAdUri( @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup, Uri uri) { int adjustedIndex = adGroupIndex - removedAdGroupCount; AdGroup[] adGroups = Util.nullSafeArrayCopy(this.adGroups, this.adGroups.length); + checkState(!Uri.EMPTY.equals(uri) || adGroups[adjustedIndex].isServerSideInserted); adGroups[adjustedIndex] = adGroups[adjustedIndex].withAdUri(uri, adIndexInAdGroup); return new AdPlaybackState( adsId, adGroups, adResumePositionUs, contentDurationUs, removedAdGroupCount); } - /** Returns an instance with the specified ad marked as played. */ + /** + * Returns an instance with the specified ad marked as {@linkplain #AD_STATE_AVAILABLE available}. + * + *

Must not be called with client side inserted ad groups. Client side inserted ads should use + * {@link #withAvailableAdUri}. + * + * @throws IllegalStateException in case this methods is called on an ad group that {@linkplain + * AdGroup#isServerSideInserted is not server side inserted}. + */ + @CheckResult + public AdPlaybackState withAvailableAd( + @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { + return withAvailableAdUri(adGroupIndex, adIndexInAdGroup, Uri.EMPTY); + } + + /** Returns an instance with the specified ad marked as {@linkplain #AD_STATE_PLAYED played}. */ @CheckResult public AdPlaybackState withPlayedAd( @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { @@ -663,7 +688,7 @@ public AdPlaybackState withPlayedAd( adsId, adGroups, adResumePositionUs, contentDurationUs, removedAdGroupCount); } - /** Returns an instance with the specified ad marked as skipped. */ + /** Returns an instance with the specified ad marked as {@linkplain #AD_STATE_SKIPPED skipped}. */ @CheckResult public AdPlaybackState withSkippedAd( @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { @@ -675,7 +700,10 @@ public AdPlaybackState withSkippedAd( adsId, adGroups, adResumePositionUs, contentDurationUs, removedAdGroupCount); } - /** Returns an instance with the specified ad marked as having a load error. */ + /** + * Returns an instance with the specified ad marked {@linkplain #AD_STATE_ERROR as having a load + * error}. + */ @CheckResult public AdPlaybackState withAdLoadError( @IntRange(from = 0) int adGroupIndex, @IntRange(from = 0) int adIndexInAdGroup) { diff --git a/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java b/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java index 1d9176b6180..ab7ce2d1aad 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java @@ -26,6 +26,7 @@ import android.net.Uri; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,7 +35,7 @@ public class AdPlaybackStateTest { private static final long[] TEST_AD_GROUP_TIMES_US = new long[] {0, 5_000_000, 10_000_000}; - private static final Uri TEST_URI = Uri.EMPTY; + private static final Uri TEST_URI = Uri.parse("http://www.google.com"); private static final Object TEST_ADS_ID = new Object(); @Test @@ -53,7 +54,7 @@ public void setAdUriBeforeAdCount() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 2); assertThat(state.getAdGroup(1).uris[0]).isNull(); @@ -100,7 +101,7 @@ public void withNewAdGroup_addsGroupAndKeepsExistingGroups() { .withRemovedAdGroupCount(1) .withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 2) .withAdCount(/* adGroupIndex= */ 2, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI) .withSkippedAd(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 0); state = @@ -140,8 +141,8 @@ public void getFirstAdIndexToPlayIsZero() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); assertThat(state.getAdGroup(1).getFirstAdIndexToPlay()).isEqualTo(0); } @@ -151,8 +152,8 @@ public void getFirstAdIndexToPlaySkipsPlayedAd() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); state = state.withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0); @@ -166,8 +167,8 @@ public void getFirstAdIndexToPlaySkipsSkippedAd() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); state = state.withSkippedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0); @@ -181,8 +182,8 @@ public void getFirstAdIndexToPlaySkipsErrorAds() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); state = state.withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0); state = state.withAdLoadError(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1); @@ -195,7 +196,7 @@ public void getNextAdIndexToPlaySkipsErrorAds() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); state = state.withAdLoadError(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1); @@ -208,9 +209,9 @@ public void getFirstAdIndexToPlay_withPlayedServerSideInsertedAds_returnsFirstIn new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withIsServerSideInserted(/* adGroupIndex= */ 1, /* isServerSideInserted= */ true); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); state = state.withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0); @@ -223,9 +224,9 @@ public void getNextAdIndexToPlay_withPlayedServerSideInsertedAds_returnsNextInde new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US).withRemovedAdGroupCount(1); state = state.withIsServerSideInserted(/* adGroupIndex= */ 1, /* isServerSideInserted= */ true); state = state.withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 3); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); state = state.withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0); state = state.withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1); @@ -248,6 +249,51 @@ public void setAdStateTwiceThrows() { } } + @Test + public void withAvailableAd() { + int adGroupIndex = 2; + AdPlaybackState state = + new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US) + .withRemovedAdGroupCount(2) + .withAdCount(adGroupIndex, 3) + .withAdDurationsUs(adGroupIndex, /* adDurationsUs...*/ 10, 20, 30) + .withIsServerSideInserted(adGroupIndex, true); + + state = state.withAvailableAd(adGroupIndex, /* adIndexInAdGroup= */ 2); + + assertThat(state.getAdGroup(adGroupIndex).states) + .asList() + .containsExactly(AD_STATE_UNAVAILABLE, AD_STATE_UNAVAILABLE, AD_STATE_AVAILABLE) + .inOrder(); + assertThat(state.getAdGroup(adGroupIndex).uris) + .asList() + .containsExactly(null, null, Uri.EMPTY) + .inOrder(); + + state = + state + .withAvailableAd(adGroupIndex, /* adIndexInAdGroup= */ 0) + .withAvailableAd(adGroupIndex, /* adIndexInAdGroup= */ 1) + .withAvailableAd(adGroupIndex, /* adIndexInAdGroup= */ 2); + + assertThat(state.getAdGroup(adGroupIndex).states) + .asList() + .containsExactly(AD_STATE_AVAILABLE, AD_STATE_AVAILABLE, AD_STATE_AVAILABLE) + .inOrder(); + } + + @Test + public void withAvailableAd_forClientSideAdGroup_throwsRuntimeException() { + AdPlaybackState state = + new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US) + .withRemovedAdGroupCount(2) + .withAdCount(/* adGroupIndex= */ 2, 3) + .withAdDurationsUs(/* adGroupIndex= */ 2, /* adDurationsUs...*/ 10, 20, 30); + + Assert.assertThrows( + IllegalStateException.class, () -> state.withAvailableAd(/* adGroupIndex= */ 2, 1)); + } + @Test public void skipAllWithoutAdCount() { AdPlaybackState state = new AdPlaybackState(TEST_ADS_ID, TEST_AD_GROUP_TIMES_US); @@ -273,10 +319,10 @@ public void withResetAdGroup_resetsAdsInFinalStates() { state = state.withAdDurationsUs( /* adGroupIndex= */ 1, /* adDurationsUs...= */ 1_000L, 2_000L, 3_000L, 4_000L, 5_000L); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, Uri.EMPTY); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, Uri.EMPTY); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 3, Uri.EMPTY); - state = state.withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 4, Uri.EMPTY); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 1, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 3, TEST_URI); + state = state.withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 4, TEST_URI); state = state.withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 2); state = state.withSkippedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 3); state = state.withAdLoadError(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 4); @@ -304,7 +350,7 @@ public void withResetAdGroup_resetsAdsInFinalStates() { .inOrder(); assertThat(state.getAdGroup(/* adGroupIndex= */ 1).uris) .asList() - .containsExactly(null, Uri.EMPTY, Uri.EMPTY, Uri.EMPTY, Uri.EMPTY) + .containsExactly(null, TEST_URI, TEST_URI, TEST_URI, TEST_URI) .inOrder(); assertThat(state.getAdGroup(/* adGroupIndex= */ 1).durationsUs) .asList() @@ -318,12 +364,12 @@ public void roundTripViaBundle_yieldsEqualFieldsExceptAdsId() { .withRemovedAdGroupCount(1) .withAdCount(/* adGroupIndex= */ 1, /* adCount= */ 1) .withPlayedAd(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0) - .withAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0, TEST_URI) .withAdCount(/* adGroupIndex= */ 2, /* adCount= */ 2) .withSkippedAd(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 0) .withPlayedAd(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 1) - .withAdUri(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 0, TEST_URI) - .withAdUri(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 1, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 0, TEST_URI) + .withAvailableAdUri(/* adGroupIndex= */ 2, /* adIndexInAdGroup= */ 1, TEST_URI) .withContentResumeOffsetUs(/* adGroupIndex= */ 1, /* contentResumeOffsetUs= */ 4444) .withContentResumeOffsetUs(/* adGroupIndex= */ 2, /* contentResumeOffsetUs= */ 3333) .withIsServerSideInserted(/* adGroupIndex= */ 1, /* isServerSideInserted= */ true) diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index e4c733fd88f..3d9d5d4f2e3 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -4748,7 +4748,8 @@ public void addMediaSource_whilePlayingAd_correctMasking() throws Exception { new AdPlaybackState(/* adsId= */ new Object(), /* adGroupTimesUs...= */ 0); adPlaybackState = adPlaybackState.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1); adPlaybackState = - adPlaybackState.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.EMPTY); + adPlaybackState.withAvailableAdUri( + /* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.parse("https://google.com/ad")); long[][] durationsUs = new long[1][]; durationsUs[0] = new long[] {Util.msToUs(adDurationMs)}; adPlaybackState = adPlaybackState.withAdDurationsUs(durationsUs); @@ -4849,7 +4850,8 @@ public void seekTo_whilePlayingAd_correctMasking() throws Exception { new AdPlaybackState(/* adsId= */ new Object(), /* adGroupTimesUs...= */ 0); adPlaybackState = adPlaybackState.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1); adPlaybackState = - adPlaybackState.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.EMPTY); + adPlaybackState.withAvailableAdUri( + /* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.parse("https://google.com/ad")); long[][] durationsUs = new long[1][]; durationsUs[0] = new long[] {Util.msToUs(adDurationMs)}; adPlaybackState = adPlaybackState.withAdDurationsUs(durationsUs); @@ -4930,7 +4932,10 @@ public void seekTo_whilePlayingAd_doesntBlockFutureUpdates() throws Exception { AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object(), /* adGroupTimesUs...= */ 0) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.EMPTY); + .withAvailableAdUri( + /* adGroupIndex= */ 0, + /* adIndexInAdGroup= */ 0, + Uri.parse("https://google.com/ad")); long[][] durationsUs = new long[1][]; durationsUs[0] = new long[] {Util.msToUs(adDurationMs)}; adPlaybackState = adPlaybackState.withAdDurationsUs(durationsUs); @@ -9042,7 +9047,10 @@ public void isCommandAvailable_duringAd_isFalseForSeekCommands() throws Exceptio AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object(), /* adGroupTimesUs...= */ 0) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.EMPTY) + .withAvailableAdUri( + /* adGroupIndex= */ 0, + /* adIndexInAdGroup= */ 0, + Uri.parse("https://google.com/ad")) .withAdDurationsUs(/* adDurationUs= */ new long[][] {{Util.msToUs(4_000)}}); Timeline adTimeline = new FakeTimeline( diff --git a/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java b/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java index 80b90c40e44..db0f15cf111 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java @@ -64,6 +64,7 @@ public final class MediaPeriodQueueTest { private static final long FIRST_AD_START_TIME_US = 10 * C.MICROS_PER_SECOND; private static final long SECOND_AD_START_TIME_US = 20 * C.MICROS_PER_SECOND; + private static final Uri AD_URI = Uri.parse("https://google.com/empty"); private static final Timeline CONTENT_TIMELINE = new SinglePeriodTimeline( CONTENT_DURATION_US, @@ -71,8 +72,7 @@ public final class MediaPeriodQueueTest { /* isDynamic= */ false, /* useLiveConfiguration= */ false, /* manifest= */ null, - MediaItem.fromUri(Uri.EMPTY)); - private static final Uri AD_URI = Uri.EMPTY; + MediaItem.fromUri(AD_URI)); private MediaPeriodQueue mediaPeriodQueue; private AdPlaybackState adPlaybackState; @@ -1168,7 +1168,7 @@ private void setAdGroupLoaded(int adGroupIndex) { adPlaybackState = adPlaybackState .withAdCount(adGroupIndex, /* adCount= */ 1) - .withAdUri(adGroupIndex, /* adIndexInAdGroup= */ 0, AD_URI) + .withAvailableAdUri(adGroupIndex, /* adIndexInAdGroup= */ 0, AD_URI) .withAdDurationsUs(newDurations); updateTimeline(); } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdsMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdsMediaSourceTest.java index e5f5f2b8df5..2c376074171 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdsMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdsMediaSourceTest.java @@ -61,7 +61,7 @@ public final class AdsMediaSourceTest { /* isDynamic= */ false, /* useLiveConfiguration= */ false, /* manifest= */ null, - MediaItem.fromUri(Uri.EMPTY)); + MediaItem.fromUri(Uri.parse("https://google.com/empty"))); private static final Object PREROLL_AD_PERIOD_UID = PREROLL_AD_TIMELINE.getUidOfPeriod(/* periodIndex= */ 0); @@ -73,7 +73,7 @@ public final class AdsMediaSourceTest { /* isDynamic= */ false, /* useLiveConfiguration= */ false, /* manifest= */ null, - MediaItem.fromUri(Uri.EMPTY)); + MediaItem.fromUri(Uri.parse("https://google.com/empty"))); private static final Object CONTENT_PERIOD_UID = CONTENT_TIMELINE.getUidOfPeriod(/* periodIndex= */ 0); @@ -81,7 +81,8 @@ public final class AdsMediaSourceTest { new AdPlaybackState(/* adsId= */ new Object(), /* adGroupTimesUs...= */ 0) .withContentDurationUs(CONTENT_DURATION_US) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) - .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.EMPTY) + .withAvailableAdUri( + /* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.parse("https://google.com/ad")) .withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0) .withAdResumePositionUs(/* adResumePositionUs= */ 0); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java index 8eb6cca922a..20d9e213437 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java @@ -293,7 +293,7 @@ public static AdPlaybackState createAdPlaybackState(int adsPerAdGroup, long... a adPlaybackState = adPlaybackState.withAdCount(/* adGroupIndex= */ i, adsPerAdGroup); for (int j = 0; j < adsPerAdGroup; j++) { adPlaybackState = - adPlaybackState.withAdUri( + adPlaybackState.withAvailableAdUri( /* adGroupIndex= */ i, /* adIndexInAdGroup= */ j, Uri.parse("https://example.com/ad/" + i + "/" + j));