Commit 17edae65 by tonihei Committed by Oliver Woodman

Make AdsMediaSource reusable.

Also fixes a bug where deferred media periods were kept in the list for
an unprepared media source although the media period was already released.

Issue:#3498

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183800889
parent 6709dc7f
...@@ -102,14 +102,11 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -102,14 +102,11 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
@Nullable private final Handler eventHandler; @Nullable private final Handler eventHandler;
@Nullable private final EventListener eventListener; @Nullable private final EventListener eventListener;
private final Handler mainHandler; private final Handler mainHandler;
private final ComponentListener componentListener;
private final Map<MediaSource, List<DeferredMediaPeriod>> deferredMediaPeriodByAdMediaSource; private final Map<MediaSource, List<DeferredMediaPeriod>> deferredMediaPeriodByAdMediaSource;
private final Timeline.Period period; private final Timeline.Period period;
private Handler playerHandler;
private volatile boolean released;
// Accessed on the player thread. // Accessed on the player thread.
private ComponentListener componentListener;
private Timeline contentTimeline; private Timeline contentTimeline;
private Object contentManifest; private Object contentManifest;
private AdPlaybackState adPlaybackState; private AdPlaybackState adPlaybackState;
...@@ -192,7 +189,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -192,7 +189,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.eventListener = eventListener; this.eventListener = eventListener;
mainHandler = new Handler(Looper.getMainLooper()); mainHandler = new Handler(Looper.getMainLooper());
componentListener = new ComponentListener();
deferredMediaPeriodByAdMediaSource = new HashMap<>(); deferredMediaPeriodByAdMediaSource = new HashMap<>();
period = new Timeline.Period(); period = new Timeline.Period();
adGroupMediaSources = new MediaSource[0][]; adGroupMediaSources = new MediaSource[0][];
...@@ -204,9 +200,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -204,9 +200,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
public void prepareSource(final ExoPlayer player, boolean isTopLevelSource, Listener listener) { public void prepareSource(final ExoPlayer player, boolean isTopLevelSource, Listener listener) {
super.prepareSource(player, isTopLevelSource, listener); super.prepareSource(player, isTopLevelSource, listener);
Assertions.checkArgument(isTopLevelSource); Assertions.checkArgument(isTopLevelSource);
Assertions.checkState(this.listener == null, MEDIA_SOURCE_REUSED_ERROR_MESSAGE); final ComponentListener componentListener = new ComponentListener();
this.listener = listener; this.listener = listener;
playerHandler = new Handler(); this.componentListener = componentListener;
prepareChildSource(new MediaPeriodId(/* periodIndex= */ 0), contentMediaSource); prepareChildSource(new MediaPeriodId(/* periodIndex= */ 0), contentMediaSource);
mainHandler.post(new Runnable() { mainHandler.post(new Runnable() {
@Override @Override
...@@ -258,13 +254,27 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -258,13 +254,27 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
@Override @Override
public void releasePeriod(MediaPeriod mediaPeriod) { public void releasePeriod(MediaPeriod mediaPeriod) {
((DeferredMediaPeriod) mediaPeriod).releasePeriod(); DeferredMediaPeriod deferredMediaPeriod = (DeferredMediaPeriod) mediaPeriod;
List<DeferredMediaPeriod> mediaPeriods =
deferredMediaPeriodByAdMediaSource.get(deferredMediaPeriod.mediaSource);
if (mediaPeriods != null) {
mediaPeriods.remove(deferredMediaPeriod);
}
deferredMediaPeriod.releasePeriod();
} }
@Override @Override
public void releaseSource() { public void releaseSource() {
super.releaseSource(); super.releaseSource();
released = true; componentListener.release();
componentListener = null;
deferredMediaPeriodByAdMediaSource.clear();
contentTimeline = null;
contentManifest = null;
adPlaybackState = null;
adGroupMediaSources = new MediaSource[0][];
adDurationsUs = new long[0][];
listener = null;
mainHandler.post(new Runnable() { mainHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -301,20 +311,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -301,20 +311,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
maybeUpdateSourceInfo(); maybeUpdateSourceInfo();
} }
private void onLoadError(final IOException error) {
Log.w(TAG, "Ad load error", error);
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
if (!released) {
eventListener.onAdLoadError(error);
}
}
});
}
}
private void onContentSourceInfoRefreshed(Timeline timeline, Object manifest) { private void onContentSourceInfoRefreshed(Timeline timeline, Object manifest) {
contentTimeline = timeline; contentTimeline = timeline;
contentManifest = manifest; contentManifest = manifest;
...@@ -349,6 +345,23 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -349,6 +345,23 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
/** Listener for component events. All methods are called on the main thread. */ /** Listener for component events. All methods are called on the main thread. */
private final class ComponentListener implements AdsLoader.EventListener { private final class ComponentListener implements AdsLoader.EventListener {
private final Handler playerHandler;
private volatile boolean released;
/**
* Creates new listener which forwards ad playback states on the creating thread and all other
* events on the external event listener thread.
*/
public ComponentListener() {
playerHandler = new Handler();
}
/** Releases the component listener. */
public void release() {
released = true;
playerHandler.removeCallbacksAndMessages(null);
}
@Override @Override
public void onAdPlaybackState(final AdPlaybackState adPlaybackState) { public void onAdPlaybackState(final AdPlaybackState adPlaybackState) {
if (released) { if (released) {
...@@ -367,6 +380,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -367,6 +380,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
@Override @Override
public void onAdClicked() { public void onAdClicked() {
if (released) {
return;
}
if (eventHandler != null && eventListener != null) { if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() { eventHandler.post(new Runnable() {
@Override @Override
...@@ -381,6 +397,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -381,6 +397,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
@Override @Override
public void onAdTapped() { public void onAdTapped() {
if (released) {
return;
}
if (eventHandler != null && eventListener != null) { if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() { eventHandler.post(new Runnable() {
@Override @Override
...@@ -398,15 +417,18 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -398,15 +417,18 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
if (released) { if (released) {
return; return;
} }
playerHandler.post(new Runnable() { Log.w(TAG, "Ad load error", error);
@Override if (eventHandler != null && eventListener != null) {
public void run() { eventHandler.post(
if (released) { new Runnable() {
return; @Override
} public void run() {
AdsMediaSource.this.onLoadError(error); if (!released) {
} eventListener.onAdLoadError(error);
}); }
}
});
}
} }
} }
......
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