Workaround unexpected discard of preloaded ad

After an ad pod coming up has preloaded, if the user seeks before it
plays we get pauseAd/stopAd called for that ad pod. Also, the ad will
not load again. Work around this unexpected behavior by handling
pauseAd/stopAd and discarding the ad.

In future, it's likely that the IMA SDK will stop calling those
methods, and will loadAd again for the preloaded ad that was
unexpectedly discarded. This change should be compatible with that,
because the ad won't be discarded any more due to not calling stopAd.

Issue: #7492
PiperOrigin-RevId: 316873699
This commit is contained in:
andrewlewis 2020-06-17 14:08:29 +01:00 committed by Andrew Lewis
parent 2546be51fe
commit ed0778d0ef
2 changed files with 32 additions and 5 deletions

View File

@ -220,6 +220,9 @@
([#7508](https://github.com/google/ExoPlayer/issues/7508)). ([#7508](https://github.com/google/ExoPlayer/issues/7508)).
* Fix a bug where the number of ads in an ad group couldn't change * Fix a bug where the number of ads in an ad group couldn't change
([#7477](https://github.com/google/ExoPlayer/issues/7477)). ([#7477](https://github.com/google/ExoPlayer/issues/7477)).
* Work around unexpected `pauseAd`/`stopAd` for ads that have preloaded
on seeking to another position
([#7492](https://github.com/google/ExoPlayer/issues/7492)).
* Demo app: Retain previous position in list of samples. * Demo app: Retain previous position in list of samples.
* Add Guava dependency. * Add Guava dependency.

View File

@ -1478,11 +1478,16 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
@Override @Override
public void loadAd(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) { public void loadAd(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) {
try { try {
if (DEBUG) {
Log.d(TAG, "loadAd " + getAdMediaInfoString(adMediaInfo) + ", ad pod " + adPodInfo);
}
if (adsManager == null) { if (adsManager == null) {
// Drop events after release. // Drop events after release.
if (DEBUG) {
Log.d(
TAG,
"loadAd after release "
+ getAdMediaInfoString(adMediaInfo)
+ ", ad pod "
+ adPodInfo);
}
return; return;
} }
@ -1490,6 +1495,9 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
int adIndexInAdGroup = adPodInfo.getAdPosition() - 1; int adIndexInAdGroup = adPodInfo.getAdPosition() - 1;
AdInfo adInfo = new AdInfo(adGroupIndex, adIndexInAdGroup); AdInfo adInfo = new AdInfo(adGroupIndex, adIndexInAdGroup);
adInfoByAdMediaInfo.put(adMediaInfo, adInfo); adInfoByAdMediaInfo.put(adMediaInfo, adInfo);
if (DEBUG) {
Log.d(TAG, "loadAd " + getAdMediaInfoString(adMediaInfo));
}
if (adPlaybackState.isAdInErrorState(adGroupIndex, adIndexInAdGroup)) { if (adPlaybackState.isAdInErrorState(adGroupIndex, adIndexInAdGroup)) {
// We have already marked this ad as having failed to load, so ignore the request. IMA // We have already marked this ad as having failed to load, so ignore the request. IMA
// will timeout after its media load timeout. // will timeout after its media load timeout.
@ -1590,10 +1598,21 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
// Drop event after release. // Drop event after release.
return; return;
} }
if (imaAdState == IMA_AD_STATE_NONE) {
// This method is called if loadAd has been called but the preloaded ad won't play due to a
// seek to a different position, so drop the event and discard the ad. See also [Internal:
// b/159111848].
@Nullable AdInfo adInfo = adInfoByAdMediaInfo.get(adMediaInfo);
if (adInfo != null) {
adPlaybackState =
adPlaybackState.withSkippedAd(adInfo.adGroupIndex, adInfo.adIndexInAdGroup);
updateAdPlaybackState();
}
return;
}
try { try {
Assertions.checkNotNull(player); Assertions.checkNotNull(player);
Assertions.checkState(imaAdState != IMA_AD_STATE_NONE);
stopAdInternal(); stopAdInternal();
} catch (RuntimeException e) { } catch (RuntimeException e) {
maybeNotifyInternalError("stopAd", e); maybeNotifyInternalError("stopAd", e);
@ -1605,8 +1624,13 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "pauseAd " + getAdMediaInfoString(adMediaInfo)); Log.d(TAG, "pauseAd " + getAdMediaInfoString(adMediaInfo));
} }
if (adsManager == null) {
// Drop event after release.
return;
}
if (imaAdState == IMA_AD_STATE_NONE) { if (imaAdState == IMA_AD_STATE_NONE) {
// This method is called after content is resumed. // This method is called if loadAd has been called but the loaded ad won't play due to a
// seek to a different position, so drop the event. See also [Internal: b/159111848].
return; return;
} }