@@ -503,7 +503,7 @@ public void playback_withAdNotPreloadingAfterTimeout_hasErrorAdGroup() {
503503 /* periodIndex= */ 0 , Util .usToMs (adGroupPositionInWindowUs ));
504504 fakePlayer .setState (Player .STATE_BUFFERING , /* playWhenReady= */ true );
505505 // Advance past the timeout and simulate polling content progress.
506- ShadowSystemClock .advanceBy (Duration .ofSeconds (5 ));
506+ ShadowSystemClock .advanceBy (Duration .ofSeconds (11 ));
507507 contentProgressProvider .getContentProgress ();
508508
509509 assertThat (getAdPlaybackState (/* periodIndex= */ 0 ))
@@ -515,6 +515,114 @@ public void playback_withAdNotPreloadingAfterTimeout_hasErrorAdGroup() {
515515 .withAdLoadError (/* adGroupIndex= */ 0 , /* adIndexInAdGroup= */ 0 ));
516516 }
517517
518+ @ Test
519+ public void playback_withCustomAdPreloadTimeout_triggersErrorAfterTimeout () {
520+ imaAdsLoader =
521+ new ImaAdsLoader .Builder (getApplicationContext ())
522+ .setImaFactory (mockImaFactory )
523+ .setImaSdkSettings (mockImaSdkSettings )
524+ .setAdPreloadTimeoutMs (3_000 )
525+ .build ();
526+ imaAdsLoader .setPlayer (fakePlayer );
527+ adsMediaSource =
528+ new AdsMediaSource (
529+ new FakeMediaSource (CONTENT_TIMELINE ),
530+ TEST_DATA_SPEC ,
531+ TEST_ADS_ID ,
532+ new DefaultMediaSourceFactory ((Context ) getApplicationContext ()),
533+ imaAdsLoader ,
534+ adViewProvider ,
535+ /* useLazyContentSourcePreparation= */ true );
536+
537+ // Simulate an ad at 2 seconds.
538+ long adGroupPositionInWindowUs = 2 * C .MICROS_PER_SECOND ;
539+ long adGroupTimeUs =
540+ adGroupPositionInWindowUs
541+ + TimelineWindowDefinition .DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US ;
542+ ImmutableList <Float > cuePoints = ImmutableList .of ((float ) adGroupTimeUs / C .MICROS_PER_SECOND );
543+ when (mockAdsManager .getAdCuePoints ()).thenReturn (cuePoints );
544+
545+ // Advance playback to just before the midroll and simulate buffering.
546+ imaAdsLoader .start (
547+ adsMediaSource , TEST_DATA_SPEC , TEST_ADS_ID , adViewProvider , adsLoaderListener );
548+ fakePlayer .setPlayingContentPosition (
549+ /* periodIndex= */ 0 , Util .usToMs (adGroupPositionInWindowUs ));
550+ fakePlayer .setState (Player .STATE_BUFFERING , /* playWhenReady= */ true );
551+
552+ // Advance past the custom timeout.
553+ ShadowSystemClock .advanceBy (Duration .ofSeconds (4 ));
554+ contentProgressProvider .getContentProgress ();
555+
556+ // Verify that the ad group is in an error state.
557+ assertThat (getAdPlaybackState (/* periodIndex= */ 0 ))
558+ .isEqualTo (
559+ new AdPlaybackState (TEST_ADS_ID , getAdGroupTimesUsForCuePoints (cuePoints ))
560+ .withContentDurationUs (CONTENT_PERIOD_DURATION_US )
561+ .withAdDurationsUs (new long [][] {{TEST_AD_DURATION_US }})
562+ .withAdCount (/* adGroupIndex= */ 0 , /* adCount= */ 1 )
563+ .withAdLoadError (/* adGroupIndex= */ 0 , /* adIndexInAdGroup= */ 0 ));
564+ }
565+
566+ @ Test
567+ public void
568+ playback_withAdPreloadTimeoutLessThanVastLoadTimeout_adPreloadTimeoutIncreasedToVastLoadTimeout () {
569+ imaAdsLoader =
570+ new ImaAdsLoader .Builder (getApplicationContext ())
571+ .setImaFactory (mockImaFactory )
572+ .setImaSdkSettings (mockImaSdkSettings )
573+ .setVastLoadTimeoutMs (5_000 )
574+ .setAdPreloadTimeoutMs (3_000 )
575+ .build ();
576+ imaAdsLoader .setPlayer (fakePlayer );
577+ adsMediaSource =
578+ new AdsMediaSource (
579+ new FakeMediaSource (CONTENT_TIMELINE ),
580+ TEST_DATA_SPEC ,
581+ TEST_ADS_ID ,
582+ new DefaultMediaSourceFactory ((Context ) getApplicationContext ()),
583+ imaAdsLoader ,
584+ adViewProvider ,
585+ /* useLazyContentSourcePreparation= */ true );
586+
587+ // Simulate an ad at 2 seconds.
588+ long adGroupPositionInWindowUs = 2 * C .MICROS_PER_SECOND ;
589+ long adGroupTimeUs =
590+ adGroupPositionInWindowUs
591+ + TimelineWindowDefinition .DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US ;
592+ ImmutableList <Float > cuePoints = ImmutableList .of ((float ) adGroupTimeUs / C .MICROS_PER_SECOND );
593+ when (mockAdsManager .getAdCuePoints ()).thenReturn (cuePoints );
594+
595+ // Advance playback to just before the midroll and simulate buffering.
596+ imaAdsLoader .start (
597+ adsMediaSource , TEST_DATA_SPEC , TEST_ADS_ID , adViewProvider , adsLoaderListener );
598+ fakePlayer .setPlayingContentPosition (
599+ /* periodIndex= */ 0 , Util .usToMs (adGroupPositionInWindowUs ));
600+ fakePlayer .setState (Player .STATE_BUFFERING , /* playWhenReady= */ true );
601+
602+ // Advance past the original adPreloadTimeout (3s) but not the vastLoadTimeout (5s).
603+ ShadowSystemClock .advanceBy (Duration .ofSeconds (4 ));
604+ contentProgressProvider .getContentProgress ();
605+
606+ // Verify that the ad has not errored out, as the timeout should be 5s.
607+ assertThat (getAdPlaybackState (/* periodIndex= */ 0 ))
608+ .isEqualTo (
609+ new AdPlaybackState (TEST_ADS_ID , getAdGroupTimesUsForCuePoints (cuePoints ))
610+ .withContentDurationUs (CONTENT_PERIOD_DURATION_US ));
611+
612+ // Advance past the vastLoadTimeout.
613+ ShadowSystemClock .advanceBy (Duration .ofSeconds (2 )); // Total advance is 6s.
614+ contentProgressProvider .getContentProgress ();
615+
616+ // Verify that the ad group is now in an error state.
617+ assertThat (getAdPlaybackState (/* periodIndex= */ 0 ))
618+ .isEqualTo (
619+ new AdPlaybackState (TEST_ADS_ID , getAdGroupTimesUsForCuePoints (cuePoints ))
620+ .withContentDurationUs (CONTENT_PERIOD_DURATION_US )
621+ .withAdDurationsUs (new long [][] {{TEST_AD_DURATION_US }})
622+ .withAdCount (/* adGroupIndex= */ 0 , /* adCount= */ 1 )
623+ .withAdLoadError (/* adGroupIndex= */ 0 , /* adIndexInAdGroup= */ 0 ));
624+ }
625+
518626 @ Test
519627 public void startPlaybackAfterMidroll_doesNotSkipMidroll () {
520628 // Simulate an ad at 2 seconds, and starting playback with an initial seek position at the ad.
@@ -561,7 +669,7 @@ public void startPlaybackAfterMidroll_withAdNotPreloadingAfterTimeout_hasErrorAd
561669 imaAdsLoader .start (
562670 adsMediaSource , TEST_DATA_SPEC , TEST_ADS_ID , adViewProvider , adsLoaderListener );
563671 contentProgressProvider .getContentProgress ();
564- ShadowSystemClock .advanceBy (Duration .ofSeconds (5 ));
672+ ShadowSystemClock .advanceBy (Duration .ofSeconds (11 ));
565673 contentProgressProvider .getContentProgress ();
566674
567675 assertThat (getAdPlaybackState (/* periodIndex= */ 0 ))
0 commit comments