Don't modify playWhenReady in ImaAdsLoader, except for playAd

Store playWhenReady when playAd is called, and restore it if necessary when the
content resumes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=162471616
This commit is contained in:
andrewlewis 2017-07-19 04:49:27 -07:00 committed by Oliver Woodman
parent 5e81cf99dc
commit 4658e619b3

View file

@ -143,6 +143,10 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
// Fields tracking the player/loader state. // Fields tracking the player/loader state.
/**
* Whether the player's play when ready flag has temporarily been set to true for playing ads.
*/
private boolean playWhenReadyOverriddenForAds;
/** /**
* Whether the player is playing an ad. * Whether the player is playing an ad.
*/ */
@ -243,12 +247,11 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
} }
/** /**
* Detaches any attached player and event listener. To attach a new player, call * Detaches the attached player and event listener. To attach a new player, call
* {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. Call {@link #release()} to release * {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. Call {@link #release()} to release
* all resources associated with this instance. * all resources associated with this instance.
*/ */
/* package */ void detachPlayer() { /* package */ void detachPlayer() {
if (player != null) {
if (adsManager != null && imaPausedContent) { if (adsManager != null && imaPausedContent) {
adPlaybackState.setAdResumePositionUs(C.msToUs(player.getCurrentPosition())); adPlaybackState.setAdResumePositionUs(C.msToUs(player.getCurrentPosition()));
adsManager.pause(); adsManager.pause();
@ -259,7 +262,6 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
player = null; player = null;
eventListener = null; eventListener = null;
} }
}
/** /**
* Releases the loader. Must be called when the instance is no longer needed. * Releases the loader. Must be called when the instance is no longer needed.
@ -268,9 +270,11 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
if (adsManager != null) { if (adsManager != null) {
adsManager.destroy(); adsManager.destroy();
adsManager = null; adsManager = null;
if (player != null) {
detachPlayer(); detachPlayer();
} }
} }
}
// AdsLoader.AdsLoadedListener implementation. // AdsLoader.AdsLoadedListener implementation.
@ -330,16 +334,12 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
// After CONTENT_PAUSE_REQUESTED, IMA will playAd/pauseAd/stopAd to show one or more ads // After CONTENT_PAUSE_REQUESTED, IMA will playAd/pauseAd/stopAd to show one or more ads
// before sending CONTENT_RESUME_REQUESTED. // before sending CONTENT_RESUME_REQUESTED.
imaPausedContent = true; imaPausedContent = true;
if (player != null) {
pauseContentInternal(); pauseContentInternal();
}
break; break;
case SKIPPED: // Fall through. case SKIPPED: // Fall through.
case CONTENT_RESUME_REQUESTED: case CONTENT_RESUME_REQUESTED:
imaPausedContent = false; imaPausedContent = false;
if (player != null) {
resumeContentInternal(); resumeContentInternal();
}
break; break;
case ALL_ADS_COMPLETED: case ALL_ADS_COMPLETED:
// Do nothing. The ads manager will be released when the source is released. // Do nothing. The ads manager will be released when the source is released.
@ -425,6 +425,9 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
if (player == null) { if (player == null) {
// Sometimes messages from IMA arrive after detaching the player. See [Internal: b/63801642]. // Sometimes messages from IMA arrive after detaching the player. See [Internal: b/63801642].
Log.w(TAG, "Unexpected playAd while detached"); Log.w(TAG, "Unexpected playAd while detached");
} else if (!player.getPlayWhenReady()) {
playWhenReadyOverriddenForAds = true;
player.setPlayWhenReady(true);
} }
if (imaPlayingAd && !imaPausedInAd) { if (imaPlayingAd && !imaPausedInAd) {
// Work around an issue where IMA does not always call stopAd before resuming content. // Work around an issue where IMA does not always call stopAd before resuming content.
@ -432,9 +435,6 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
Log.w(TAG, "Unexpected playAd without stopAd"); Log.w(TAG, "Unexpected playAd without stopAd");
stopAdInternal(); stopAdInternal();
} }
if (player != null) {
player.setPlayWhenReady(true);
}
if (!imaPlayingAd) { if (!imaPlayingAd) {
imaPlayingAd = true; imaPlayingAd = true;
for (VideoAdPlayerCallback callback : adCallbacks) { for (VideoAdPlayerCallback callback : adCallbacks) {
@ -474,9 +474,6 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
return; return;
} }
imaPausedInAd = true; imaPausedInAd = true;
if (player != null) {
player.setPlayWhenReady(false);
}
for (VideoAdPlayerCallback callback : adCallbacks) { for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onPause(); callback.onPause();
} }
@ -560,6 +557,10 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
} }
return; return;
} }
if (!playingAd && playWhenReadyOverriddenForAds) {
playWhenReadyOverriddenForAds = false;
player.setPlayWhenReady(false);
}
if (!sentContentComplete) { if (!sentContentComplete) {
boolean adFinished = boolean adFinished =
!playingAd || playingAdIndexInAdGroup != player.getCurrentAdIndexInAdGroup(); !playingAd || playingAdIndexInAdGroup != player.getCurrentAdIndexInAdGroup();
@ -571,7 +572,6 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
} }
} }
if (playingAd && !wasPlayingAd) { if (playingAd && !wasPlayingAd) {
player.setPlayWhenReady(false);
int adGroupIndex = player.getCurrentAdGroupIndex(); int adGroupIndex = player.getCurrentAdGroupIndex();
// IMA hasn't sent CONTENT_PAUSE_REQUESTED yet, so fake the content position. // IMA hasn't sent CONTENT_PAUSE_REQUESTED yet, so fake the content position.
Assertions.checkState(fakeContentProgressElapsedRealtimeMs == C.TIME_UNSET); Assertions.checkState(fakeContentProgressElapsedRealtimeMs == C.TIME_UNSET);
@ -601,8 +601,7 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
} }
private void resumeContentInternal() { private void resumeContentInternal() {
if (contentDurationMs != C.TIME_UNSET) { if (contentDurationMs != C.TIME_UNSET && imaPlayingAd) {
if (imaPlayingAd) {
// Work around an issue where IMA does not always call stopAd before resuming content. // Work around an issue where IMA does not always call stopAd before resuming content.
// See [Internal: b/38354028]. // See [Internal: b/38354028].
if (DEBUG) { if (DEBUG) {
@ -610,8 +609,6 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
} }
stopAdInternal(); stopAdInternal();
} }
}
player.setPlayWhenReady(true);
clearFlags(); clearFlags();
} }
@ -623,15 +620,11 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
// IMA is requesting to pause content, so stop faking the content position. // IMA is requesting to pause content, so stop faking the content position.
fakeContentProgressElapsedRealtimeMs = C.TIME_UNSET; fakeContentProgressElapsedRealtimeMs = C.TIME_UNSET;
fakeContentProgressOffsetMs = C.TIME_UNSET; fakeContentProgressOffsetMs = C.TIME_UNSET;
player.setPlayWhenReady(false);
clearFlags(); clearFlags();
} }
private void stopAdInternal() { private void stopAdInternal() {
Assertions.checkState(imaPlayingAd); Assertions.checkState(imaPlayingAd);
if (player != null) {
player.setPlayWhenReady(false);
}
adPlaybackState.playedAd(adGroupIndex); adPlaybackState.playedAd(adGroupIndex);
updateAdPlaybackState(); updateAdPlaybackState();
if (!playingAd) { if (!playingAd) {