From caca14c5f95684526f0c825721913ed932b480d6 Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 3 Jan 2019 14:54:22 +0000 Subject: [PATCH 01/19] Set Player separately in AdsLoader interface. Passing the player through MediaSource.prepare is only needed for the AdsLoader and complicates other usages of MediaSource. Providing the player directly to the AdsLoader is also in line with the usage pattern of PlayerView and other components. Also rename methods to start/stop to better reflect their usage. PiperOrigin-RevId: 227682112 --- .../exoplayer2/demo/PlayerActivity.java | 4 ++ .../exoplayer2/ext/ima/ImaAdsLoader.java | 37 +++++++--- .../exoplayer2/ext/ima/ImaAdsLoaderTest.java | 11 +-- .../exoplayer2/source/ads/AdsLoader.java | 69 ++++++++++++------- .../exoplayer2/source/ads/AdsMediaSource.java | 4 +- 5 files changed, 81 insertions(+), 44 deletions(-) diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index ffa9bafa4f..31d6d332dd 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -534,6 +534,9 @@ public class PlayerActivity extends Activity mediaSource = null; trackSelector = null; } + if (adsLoader != null) { + adsLoader.setPlayer(null); + } releaseMediaDrm(); } @@ -597,6 +600,7 @@ public class PlayerActivity extends Activity // The demo app has a non-null overlay frame layout. playerView.getOverlayFrameLayout().addView(adUiViewGroup); } + adsLoader.setPlayer(player); AdsMediaSource.MediaSourceFactory adMediaSourceFactory = new AdsMediaSource.MediaSourceFactory() { @Override diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index 9b4b66125c..985408cb70 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -46,7 +46,6 @@ import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlaybackException; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Timeline; @@ -73,7 +72,13 @@ import java.util.List; import java.util.Map; import java.util.Set; -/** Loads ads using the IMA SDK. All methods are called on the main thread. */ +/** + * {@link AdsLoader} using the IMA SDK. All methods must be called on the main thread. + * + *

The player instance that will play the loaded ads must be set before playback using {@link + * #setPlayer(Player)}. If the ads loader is no longer required, it must be released by calling + * {@link #release()}. + */ public final class ImaAdsLoader implements Player.EventListener, AdsLoader, @@ -92,9 +97,9 @@ public final class ImaAdsLoader private final Context context; - private @Nullable ImaSdkSettings imaSdkSettings; - private @Nullable AdEventListener adEventListener; - private @Nullable Set adUiElements; + @Nullable private ImaSdkSettings imaSdkSettings; + @Nullable private AdEventListener adEventListener; + @Nullable private Set adUiElements; private int vastLoadTimeoutMs; private int mediaLoadTimeoutMs; private int mediaBitrate; @@ -316,10 +321,11 @@ public final class ImaAdsLoader private final AdDisplayContainer adDisplayContainer; private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader; + @Nullable private Player nextPlayer; private Object pendingAdRequestContext; private List supportedMimeTypes; - private EventListener eventListener; - private Player player; + @Nullable private EventListener eventListener; + @Nullable private Player player; private VideoProgressUpdate lastContentProgress; private VideoProgressUpdate lastAdProgress; private int lastVolumePercentage; @@ -525,6 +531,14 @@ public final class ImaAdsLoader // AdsLoader implementation. + @Override + public void setPlayer(@Nullable Player player) { + Assertions.checkState(Looper.getMainLooper() == Looper.myLooper()); + Assertions.checkState( + player == null || player.getApplicationLooper() == Looper.getMainLooper()); + nextPlayer = player; + } + @Override public void setSupportedContentTypes(@C.ContentType int... contentTypes) { List supportedMimeTypes = new ArrayList<>(); @@ -549,9 +563,10 @@ public final class ImaAdsLoader } @Override - public void attachPlayer(ExoPlayer player, EventListener eventListener, ViewGroup adUiViewGroup) { - Assertions.checkArgument(player.getApplicationLooper() == Looper.getMainLooper()); - this.player = player; + public void start(EventListener eventListener, ViewGroup adUiViewGroup) { + Assertions.checkNotNull( + nextPlayer, "Set player using adsLoader.setPlayer before preparing the player."); + player = nextPlayer; this.eventListener = eventListener; lastVolumePercentage = 0; lastAdProgress = null; @@ -575,7 +590,7 @@ public final class ImaAdsLoader } @Override - public void detachPlayer() { + public void stop() { if (adsManager != null && imaPausedContent) { adPlaybackState = adPlaybackState.withAdResumePositionUs( 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 b0fe731480..0b097f26f0 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 @@ -111,7 +111,7 @@ public class ImaAdsLoaderTest { @Test public void testAttachPlayer_setsAdUiViewGroup() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); - imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup); + imaAdsLoader.start(adsLoaderListener, adUiViewGroup); verify(adDisplayContainer, atLeastOnce()).setAdContainer(adUiViewGroup); } @@ -119,7 +119,7 @@ public class ImaAdsLoaderTest { @Test public void testAttachPlayer_updatesAdPlaybackState() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); - imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup); + imaAdsLoader.start(adsLoaderListener, adUiViewGroup); assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( @@ -131,14 +131,14 @@ public class ImaAdsLoaderTest { public void testAttachAfterRelease() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); imaAdsLoader.release(); - imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup); + imaAdsLoader.start(adsLoaderListener, adUiViewGroup); } @Test public void testAttachAndCallbacksAfterRelease() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); imaAdsLoader.release(); - imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup); + imaAdsLoader.start(adsLoaderListener, adUiViewGroup); fakeExoPlayer.setPlayingContentPosition(/* position= */ 0); fakeExoPlayer.setState(Player.STATE_READY, true); @@ -166,7 +166,7 @@ public class ImaAdsLoaderTest { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); // Load the preroll ad. - imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup); + imaAdsLoader.start(adsLoaderListener, adUiViewGroup); imaAdsLoader.onAdEvent(getAdEvent(AdEventType.LOADED, UNSKIPPABLE_AD)); imaAdsLoader.loadAd(TEST_URI.toString()); imaAdsLoader.onAdEvent(getAdEvent(AdEventType.CONTENT_PAUSE_REQUESTED, UNSKIPPABLE_AD)); @@ -210,6 +210,7 @@ public class ImaAdsLoaderTest { .setImaFactory(testImaFactory) .setImaSdkSettings(imaSdkSettings) .buildForAdTag(TEST_URI); + imaAdsLoader.setPlayer(fakeExoPlayer); } private static AdEvent getAdEvent(AdEventType adEventType, @Nullable Ad ad) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java index f041542356..51de225414 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java @@ -15,9 +15,10 @@ */ package com.google.android.exoplayer2.source.ads; +import android.support.annotation.Nullable; import android.view.ViewGroup; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; +import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException; import com.google.android.exoplayer2.upstream.DataSpec; import java.io.IOException; @@ -30,16 +31,16 @@ import java.io.IOException; * with a new copy of the current {@link AdPlaybackState} whenever further information about ads * becomes known (for example, when an ad media URI is available, or an ad has played to the end). * - *

{@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)} will be called when the ads media - * source first initializes, at which point the loader can request ads. If the player enters the - * background, {@link #detachPlayer()} will be called. Loaders should maintain any ad playback state - * in preparation for a later call to {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. If - * an ad is playing when the player is detached, update the ad playback state with the current - * playback position using {@link AdPlaybackState#withAdResumePositionUs(long)}. + *

{@link #start(EventListener, ViewGroup)} will be called when the ads media source first + * initializes, at which point the loader can request ads. If the player enters the background, + * {@link #stop()} will be called. Loaders should maintain any ad playback state in preparation for + * a later call to {@link #start(EventListener, ViewGroup)}. If an ad is playing when the player is + * detached, update the ad playback state with the current playback position using {@link + * AdPlaybackState#withAdResumePositionUs(long)}. * *

If {@link EventListener#onAdPlaybackState(AdPlaybackState)} has been called, the - * implementation of {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)} should invoke the - * same listener to provide the existing playback state to the new player. + * implementation of {@link #start(EventListener, ViewGroup)} should invoke the same listener to + * provide the existing playback state to the new player. */ public interface AdsLoader { @@ -75,9 +76,34 @@ public interface AdsLoader { } + // Methods called by the application. + /** - * Sets the supported content types for ad media. Must be called before the first call to - * {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. Subsequent calls may be ignored. + * Sets the player that will play the loaded ads. + * + *

This method must be called before the player is prepared with media using this ads loader. + * + *

This method must also be called on the main thread and only players which are accessed on + * the main thread are supported ({@code player.getApplicationLooper() == + * Looper.getMainLooper()}). + * + * @param player The player instance that will play the loaded ads. May be null to delete the + * reference to a previously set player. + */ + void setPlayer(@Nullable Player player); + + /** + * Releases the loader. Must be called by the application on the main thread when the instance is + * no longer needed. + */ + void release(); + + // Methods called by AdsMediaSource. + + /** + * Sets the supported content types for ad media. Must be called before the first call to {@link + * #start(EventListener, ViewGroup)}. Subsequent calls may be ignored. Called on the main thread + * by {@link AdsMediaSource}. * * @param contentTypes The supported content types for ad media. Each element must be one of * {@link C#TYPE_DASH}, {@link C#TYPE_HLS}, {@link C#TYPE_SS} and {@link C#TYPE_OTHER}. @@ -85,32 +111,23 @@ public interface AdsLoader { void setSupportedContentTypes(@C.ContentType int... contentTypes); /** - * Attaches a player that will play ads loaded using this instance. Called on the main thread by - * {@link AdsMediaSource}. + * Starts using the ads loader for playback. Called on the main thread by {@link AdsMediaSource}. * - * @param player The player instance that will play the loaded ads. Only players which are - * accessed on the main thread are supported ({@code player.getApplicationLooper() == - * Looper.getMainLooper()}). * @param eventListener Listener for ads loader events. * @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI. */ - void attachPlayer(ExoPlayer player, EventListener eventListener, ViewGroup adUiViewGroup); + void start(EventListener eventListener, ViewGroup adUiViewGroup); /** - * Detaches the attached player and event listener. Called on the main thread by - * {@link AdsMediaSource}. + * Stops using the ads loader for playback and deregisters the event listener. Called on the main + * thread by {@link AdsMediaSource}. */ - void detachPlayer(); - - /** - * Releases the loader. Called by the application on the main thread when the instance is no - * longer needed. - */ - void release(); + void stop(); /** * Notifies the ads loader that the player was not able to prepare media for a given ad. * Implementations should update the ad playback state as the specified ad has failed to load. + * Called on the main thread by {@link AdsMediaSource}. * * @param adGroupIndex The index of the ad group. * @param adIndexInAdGroup The index of the ad in the ad group. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java index 4bf661ddc0..a8ae3938af 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java @@ -337,7 +337,7 @@ public final class AdsMediaSource extends CompositeMediaSource { final ComponentListener componentListener = new ComponentListener(); this.componentListener = componentListener; prepareChildSource(DUMMY_CONTENT_MEDIA_PERIOD_ID, contentMediaSource); - mainHandler.post(() -> adsLoader.attachPlayer(player, componentListener, adUiViewGroup)); + mainHandler.post(() -> adsLoader.start(componentListener, adUiViewGroup)); } @Override @@ -406,7 +406,7 @@ public final class AdsMediaSource extends CompositeMediaSource { adPlaybackState = null; adGroupMediaSources = new MediaSource[0][]; adGroupTimelines = new Timeline[0][]; - mainHandler.post(adsLoader::detachPlayer); + mainHandler.post(adsLoader::stop); } @Override From 5fc975b728d77497864302a4224af9440bca36ad Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 3 Jan 2019 14:54:37 +0000 Subject: [PATCH 02/19] Replace isTopLevelSource check by period count check in AdsMediaSource. The top level requirement only tried to ensure that the entire timeline only has one period. This is already asserted by ImaAdsLoader. AdsMediaSource itself works fine as long as the wrapped timeline has one period only. This is now asserted instead. PiperOrigin-RevId: 227682141 --- .../google/android/exoplayer2/source/ads/AdsMediaSource.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java index a8ae3938af..355f7d4de9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java @@ -331,9 +331,6 @@ public final class AdsMediaSource extends CompositeMediaSource { boolean isTopLevelSource, @Nullable TransferListener mediaTransferListener) { super.prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); - Assertions.checkArgument( - isTopLevelSource, - "AdsMediaSource must be the top-level source used to prepare the player."); final ComponentListener componentListener = new ComponentListener(); this.componentListener = componentListener; prepareChildSource(DUMMY_CONTENT_MEDIA_PERIOD_ID, contentMediaSource); @@ -446,6 +443,7 @@ public final class AdsMediaSource extends CompositeMediaSource { } private void onContentSourceInfoRefreshed(Timeline timeline, Object manifest) { + Assertions.checkArgument(timeline.getPeriodCount() == 1); contentTimeline = timeline; contentManifest = manifest; maybeUpdateSourceInfo(); From a973b6f34f21b99fba29951d992cdd8c765ca351 Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 4 Jan 2019 17:56:10 +0000 Subject: [PATCH 03/19] Remove player and isTopLevelSource parameters from MediaSource.prepare. They are not longer needed anywhere, are error-prone (because of threading requirements), and complicate testing and using MediaSources without a player. PiperOrigin-RevId: 227871157 --- .../exoplayer2/ext/ima/ImaAdsMediaSource.java | 12 ++--- .../android/exoplayer2/ExoPlayerImpl.java | 1 - .../exoplayer2/ExoPlayerImplInternal.java | 9 +--- .../exoplayer2/source/BaseMediaSource.java | 36 +++++-------- .../source/ClippingMediaSource.java | 8 +-- .../source/CompositeMediaSource.java | 15 +----- .../source/ConcatenatingMediaSource.java | 10 +--- .../source/ExtractorMediaSource.java | 6 +-- .../exoplayer2/source/LoopingMediaSource.java | 7 +-- .../exoplayer2/source/MediaSource.java | 21 +++----- .../exoplayer2/source/MergingMediaSource.java | 8 +-- .../source/SingleSampleMediaSource.java | 6 +-- .../exoplayer2/source/ads/AdsMediaSource.java | 10 ++-- .../android/exoplayer2/ExoPlayerTest.java | 4 +- .../source/dash/DashMediaSource.java | 6 +-- .../exoplayer2/source/hls/HlsMediaSource.java | 6 +-- .../source/smoothstreaming/SsMediaSource.java | 6 +-- .../exoplayer2/testutil/FakeMediaSource.java | 6 +-- .../testutil/MediaSourceTestRunner.java | 51 +------------------ 19 files changed, 45 insertions(+), 183 deletions(-) diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java index 0978ee401c..bcccd6cec7 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java @@ -18,7 +18,6 @@ package com.google.android.exoplayer2.ext.ima; import android.os.Handler; import android.support.annotation.Nullable; import android.view.ViewGroup; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.BaseMediaSource; import com.google.android.exoplayer2.source.MediaPeriod; @@ -33,7 +32,8 @@ import java.io.IOException; /** * A {@link MediaSource} that inserts ads linearly with a provided content media source. * - * @deprecated Use com.google.android.exoplayer2.source.ads.AdsMediaSource with ImaAdsLoader. + * @deprecated Use {@link com.google.android.exoplayer2.source.ads.AdsMediaSource} with + * ImaAdsLoader. */ @Deprecated public final class ImaAdsMediaSource extends BaseMediaSource implements SourceInfoRefreshListener { @@ -83,12 +83,8 @@ public final class ImaAdsMediaSource extends BaseMediaSource implements SourceIn } @Override - public void prepareSourceInternal( - final ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { - adsMediaSource.prepareSource( - player, isTopLevelSource, /* listener= */ this, mediaTransferListener); + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { + adsMediaSource.prepareSource(/* listener= */ this, mediaTransferListener); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index 35fa85e467..de6e867514 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -138,7 +138,6 @@ import java.util.concurrent.CopyOnWriteArraySet; repeatMode, shuffleModeEnabled, eventHandler, - this, clock); internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper()); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index 7f41719d1d..c31c6b75a5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -93,7 +93,6 @@ import java.util.Collections; private final HandlerWrapper handler; private final HandlerThread internalPlaybackThread; private final Handler eventHandler; - private final ExoPlayer player; private final Timeline.Window window; private final Timeline.Period period; private final long backBufferDurationUs; @@ -131,7 +130,6 @@ import java.util.Collections; @Player.RepeatMode int repeatMode, boolean shuffleModeEnabled, Handler eventHandler, - ExoPlayer player, Clock clock) { this.renderers = renderers; this.trackSelector = trackSelector; @@ -142,7 +140,6 @@ import java.util.Collections; this.repeatMode = repeatMode; this.shuffleModeEnabled = shuffleModeEnabled; this.eventHandler = eventHandler; - this.player = player; this.clock = clock; this.queue = new MediaPeriodQueue(); @@ -398,11 +395,7 @@ import java.util.Collections; loadControl.onPrepared(); this.mediaSource = mediaSource; setState(Player.STATE_BUFFERING); - mediaSource.prepareSource( - player, - /* isTopLevelSource= */ true, - /* listener= */ this, - bandwidthMeter.getTransferListener()); + mediaSource.prepareSource(/* listener= */ this, bandwidthMeter.getTransferListener()); handler.sendEmptyMessage(MSG_DO_SOME_WORK); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java index 2feac2978e..189467b47e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/BaseMediaSource.java @@ -16,8 +16,8 @@ package com.google.android.exoplayer2.source; import android.os.Handler; +import android.os.Looper; import android.support.annotation.Nullable; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.util.Assertions; @@ -35,9 +35,9 @@ public abstract class BaseMediaSource implements MediaSource { private final ArrayList sourceInfoListeners; private final MediaSourceEventListener.EventDispatcher eventDispatcher; - private @Nullable ExoPlayer player; - private @Nullable Timeline timeline; - private @Nullable Object manifest; + @Nullable private Looper looper; + @Nullable private Timeline timeline; + @Nullable private Object manifest; public BaseMediaSource() { sourceInfoListeners = new ArrayList<>(/* initialCapacity= */ 1); @@ -48,21 +48,16 @@ public abstract class BaseMediaSource implements MediaSource { * Starts source preparation. This method is called at most once until the next call to {@link * #releaseSourceInternal()}. * - * @param player The player for which this source is being prepared. - * @param isTopLevelSource Whether this source has been passed directly to {@link - * ExoPlayer#prepare(MediaSource)} or {@link ExoPlayer#prepare(MediaSource, boolean, - * boolean)}. * @param mediaTransferListener The transfer listener which should be informed of any media data * transfers. May be null if no listener is available. Note that this listener should usually * be only informed of transfers related to the media loads and not of auxiliary loads for * manifests and other data. */ - protected abstract void prepareSourceInternal( - ExoPlayer player, boolean isTopLevelSource, @Nullable TransferListener mediaTransferListener); + protected abstract void prepareSourceInternal(@Nullable TransferListener mediaTransferListener); /** * Releases the source. This method is called exactly once after each call to {@link - * #prepareSourceInternal(ExoPlayer, boolean, TransferListener)}. + * #prepareSourceInternal(TransferListener)}. */ protected abstract void releaseSourceInternal(); @@ -135,21 +130,14 @@ public abstract class BaseMediaSource implements MediaSource { @Override public final void prepareSource( - ExoPlayer player, boolean isTopLevelSource, SourceInfoRefreshListener listener) { - prepareSource(player, isTopLevelSource, listener, /* mediaTransferListener= */ null); - } - - @Override - public final void prepareSource( - ExoPlayer player, - boolean isTopLevelSource, SourceInfoRefreshListener listener, @Nullable TransferListener mediaTransferListener) { - Assertions.checkArgument(this.player == null || this.player == player); + Looper looper = Looper.myLooper(); + Assertions.checkArgument(this.looper == null || this.looper == looper); sourceInfoListeners.add(listener); - if (this.player == null) { - this.player = player; - prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); + if (this.looper == null) { + this.looper = looper; + prepareSourceInternal(mediaTransferListener); } else if (timeline != null) { listener.onSourceInfoRefreshed(/* source= */ this, timeline, manifest); } @@ -159,7 +147,7 @@ public abstract class BaseMediaSource implements MediaSource { public final void releaseSource(SourceInfoRefreshListener listener) { sourceInfoListeners.remove(listener); if (sourceInfoListeners.isEmpty()) { - player = null; + looper = null; timeline = null; manifest = null; releaseSourceInternal(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java index fce1c4b877..d5399dc02d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java @@ -18,7 +18,6 @@ package com.google.android.exoplayer2.source; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.TransferListener; @@ -223,11 +222,8 @@ public final class ClippingMediaSource extends CompositeMediaSource { } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { - super.prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { + super.prepareSourceInternal(mediaTransferListener); prepareChildSource(/* id= */ null, mediaSource); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java index 69fa4b094b..dbf5812f98 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java @@ -18,7 +18,6 @@ package com.google.android.exoplayer2.source; import android.os.Handler; import android.support.annotation.CallSuper; import android.support.annotation.Nullable; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.util.Assertions; @@ -35,7 +34,6 @@ public abstract class CompositeMediaSource extends BaseMediaSource { private final HashMap childSources; - private @Nullable ExoPlayer player; private @Nullable Handler eventHandler; private @Nullable TransferListener mediaTransferListener; @@ -46,11 +44,7 @@ public abstract class CompositeMediaSource extends BaseMediaSource { @Override @CallSuper - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { - this.player = player; + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { this.mediaTransferListener = mediaTransferListener; eventHandler = new Handler(); } @@ -71,7 +65,6 @@ public abstract class CompositeMediaSource extends BaseMediaSource { childSource.mediaSource.removeEventListener(childSource.eventListener); } childSources.clear(); - player = null; } /** @@ -105,11 +98,7 @@ public abstract class CompositeMediaSource extends BaseMediaSource { MediaSourceEventListener eventListener = new ForwardingEventListener(id); childSources.put(id, new MediaSourceAndListener(mediaSource, sourceListener, eventListener)); mediaSource.addEventListener(Assertions.checkNotNull(eventHandler), eventListener); - mediaSource.prepareSource( - Assertions.checkNotNull(player), - /* isTopLevelSource= */ false, - sourceListener, - mediaTransferListener); + mediaSource.prepareSource(sourceListener, mediaTransferListener); } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java index 7baea9979f..961aaf105f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java @@ -22,7 +22,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Pair; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.ConcatenatingMediaSource.MediaSourceHolder; import com.google.android.exoplayer2.source.ShuffleOrder.DefaultShuffleOrder; @@ -428,10 +427,8 @@ public class ConcatenatingMediaSource extends CompositeMediaSource { } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { - super.prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { + super.prepareSourceInternal(mediaTransferListener); prepareChildSource(/* id= */ null, childSource); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java index 801737faef..b848f292c5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java @@ -18,30 +18,30 @@ package com.google.android.exoplayer2.source; import android.os.Handler; import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.TransferListener; import java.io.IOException; /** - * Defines and provides media to be played by an {@link ExoPlayer}. A MediaSource has two main - * responsibilities: + * Defines and provides media to be played by an {@link com.google.android.exoplayer2.ExoPlayer}. A + * MediaSource has two main responsibilities: * *

* * All methods are called on the player's internal playback thread, as described in the {@link - * ExoPlayer} Javadoc. They should not be called directly from application code. Instances can be - * re-used, but only for one {@link ExoPlayer} instance simultaneously. + * com.google.android.exoplayer2.ExoPlayer} Javadoc. They should not be called directly from + * application code. Instances can be re-used, but only for one {@link + * com.google.android.exoplayer2.ExoPlayer} instance simultaneously. */ public interface MediaSource { @@ -242,11 +242,6 @@ public interface MediaSource { *

For each call to this method, a call to {@link #releaseSource(SourceInfoRefreshListener)} is * needed to remove the listener and to release the source if no longer required. * - * @param player The player for which this source is being prepared. - * @param isTopLevelSource Whether this source has been passed directly to {@link - * ExoPlayer#prepare(MediaSource)} or {@link ExoPlayer#prepare(MediaSource, boolean, - * boolean)}. If {@code false}, this source is being prepared by another source (e.g. {@link - * ConcatenatingMediaSource}) for composition. * @param listener The listener to be added. * @param mediaTransferListener The transfer listener which should be informed of any media data * transfers. May be null if no listener is available. Note that this listener should be only @@ -254,8 +249,6 @@ public interface MediaSource { * and other data. */ void prepareSource( - ExoPlayer player, - boolean isTopLevelSource, SourceInfoRefreshListener listener, @Nullable TransferListener mediaTransferListener); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java index cc7202f9b2..1ea3404e81 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java @@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source; import android.support.annotation.IntDef; import android.support.annotation.Nullable; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.TransferListener; @@ -105,11 +104,8 @@ public final class MergingMediaSource extends CompositeMediaSource { } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { - super.prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { + super.prepareSourceInternal(mediaTransferListener); for (int i = 0; i < mediaSources.length; i++) { prepareChildSource(i, mediaSources[i]); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java index 046672bb77..c028a9e339 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java @@ -18,7 +18,6 @@ package com.google.android.exoplayer2.source; import android.net.Uri; import android.os.Handler; import android.support.annotation.Nullable; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.Allocator; @@ -304,10 +303,7 @@ public final class SingleSampleMediaSource extends BaseMediaSource { } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { transferListener = mediaTransferListener; refreshSourceInfo(timeline, /* manifest= */ null); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java index 355f7d4de9..4754466235 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java @@ -22,7 +22,6 @@ import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.view.ViewGroup; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.CompositeMediaSource; import com.google.android.exoplayer2.source.DeferredMediaPeriod; @@ -326,12 +325,9 @@ public final class AdsMediaSource extends CompositeMediaSource { } @Override - public void prepareSourceInternal( - final ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { - super.prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); - final ComponentListener componentListener = new ComponentListener(); + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { + super.prepareSourceInternal(mediaTransferListener); + ComponentListener componentListener = new ComponentListener(); this.componentListener = componentListener; prepareChildSource(DUMMY_CONTENT_MEDIA_PERIOD_ID, contentMediaSource); mainHandler.post(() -> adsLoader.start(componentListener, adUiViewGroup)); 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 d131ed0f51..fd9100338c 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 @@ -267,10 +267,8 @@ public final class ExoPlayerTest { new FakeMediaSource(timeline, new Object(), Builder.VIDEO_FORMAT) { @Override public synchronized void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, @Nullable TransferListener mediaTransferListener) { - super.prepareSourceInternal(player, isTopLevelSource, mediaTransferListener); + super.prepareSourceInternal(mediaTransferListener); // We've queued a source info refresh on the playback thread's event queue. Allow the // test thread to prepare the player with the third source, and block this thread (the // playback thread) until the test thread's call to prepare() has returned. diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index c65bfceb39..8b503989b7 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -22,7 +22,6 @@ import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.SparseArray; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.Timeline; @@ -614,10 +613,7 @@ public final class DashMediaSource extends BaseMediaSource { } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { this.mediaTransferListener = mediaTransferListener; if (sideloadedManifest) { processManifest(false); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index 2afd041631..cd2cbbcab9 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -19,7 +19,6 @@ import android.net.Uri; import android.os.Handler; import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.source.BaseMediaSource; @@ -397,10 +396,7 @@ public final class HlsMediaSource extends BaseMediaSource } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { this.mediaTransferListener = mediaTransferListener; EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null); playlistTracker.start(manifestUri, eventDispatcher, /* listener= */ this); diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java index d025f8fa3a..fb64f43772 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java @@ -20,7 +20,6 @@ import android.os.Handler; import android.os.SystemClock; import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.Timeline; @@ -510,10 +509,7 @@ public final class SsMediaSource extends BaseMediaSource } @Override - public void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { + public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { this.mediaTransferListener = mediaTransferListener; if (sideloadedManifest) { manifestLoaderErrorThrower = new LoaderErrorThrower.Dummy(); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java index 999372b90a..de4be82b38 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java @@ -22,7 +22,6 @@ import android.os.Handler; import android.os.SystemClock; import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline.Period; @@ -96,10 +95,7 @@ public class FakeMediaSource extends BaseMediaSource { } @Override - public synchronized void prepareSourceInternal( - ExoPlayer player, - boolean isTopLevelSource, - @Nullable TransferListener mediaTransferListener) { + public synchronized void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { assertThat(preparedSource).isFalse(); transferListener = mediaTransferListener; preparedSource = true; diff --git a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java index e6fb5bc5f3..9514768416 100644 --- a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java +++ b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java @@ -17,17 +17,13 @@ package com.google.android.exoplayer2.testutil; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; -import static org.junit.Assert.fail; import android.os.ConditionVariable; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; -import android.os.Message; import android.support.annotation.Nullable; import android.util.Pair; -import com.google.android.exoplayer2.ExoPlaybackException; -import com.google.android.exoplayer2.PlayerMessage; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaSource; @@ -54,7 +50,6 @@ public class MediaSourceTestRunner { public static final int TIMEOUT_MS = 10000; - private final StubExoPlayer player; private final MediaSource mediaSource; private final MediaSourceListener mediaSourceListener; private final HandlerThread playbackThread; @@ -79,7 +74,6 @@ public class MediaSourceTestRunner { playbackThread.start(); Looper playbackLooper = playbackThread.getLooper(); playbackHandler = new Handler(playbackLooper); - player = new EventHandlingExoPlayer(playbackLooper); mediaSourceListener = new MediaSourceListener(); timelines = new LinkedBlockingDeque<>(); completedLoads = new CopyOnWriteArrayList<>(); @@ -121,11 +115,7 @@ public class MediaSourceTestRunner { final IOException[] prepareError = new IOException[1]; runOnPlaybackThread( () -> { - mediaSource.prepareSource( - player, - /* isTopLevelSource= */ true, - mediaSourceListener, - /* mediaTransferListener= */ null); + mediaSource.prepareSource(mediaSourceListener, /* mediaTransferListener= */ null); try { // TODO: This only catches errors that are set synchronously in prepareSource. To // capture async errors we'll need to poll maybeThrowSourceInfoRefreshError until the @@ -430,43 +420,4 @@ public class MediaSourceTestRunner { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); } } - - private static class EventHandlingExoPlayer extends StubExoPlayer - implements Handler.Callback, PlayerMessage.Sender { - - private final Handler handler; - - public EventHandlingExoPlayer(Looper looper) { - this.handler = new Handler(looper, this); - } - - @Override - public Looper getApplicationLooper() { - return handler.getLooper(); - } - - @Override - public PlayerMessage createMessage(PlayerMessage.Target target) { - return new PlayerMessage( - /* sender= */ this, target, Timeline.EMPTY, /* defaultWindowIndex= */ 0, handler); - } - - @Override - public void sendMessage(PlayerMessage message) { - handler.obtainMessage(0, message).sendToTarget(); - } - - @Override - @SuppressWarnings("unchecked") - public boolean handleMessage(Message msg) { - PlayerMessage message = (PlayerMessage) msg.obj; - try { - message.getTarget().handleMessage(message.getType(), message.getPayload()); - message.markAsProcessed(/* isDelivered= */ true); - } catch (ExoPlaybackException e) { - fail("Unexpected ExoPlaybackException."); - } - return true; - } - } } From 85b8e1f706577f53b1589d61961c353dee7784ab Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 29 Jan 2019 12:01:33 +0000 Subject: [PATCH 04/19] Add back deprecated MediaSource.prepareSource for ExoPlayerSampleExtractor. This should be removed after releasing. PiperOrigin-RevId: 231380393 --- .../google/android/exoplayer2/source/MediaSource.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java index b848f292c5..14f9a26245 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source; import android.os.Handler; import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.TransferListener; @@ -226,11 +227,6 @@ public interface MediaSource { return null; } - /** @deprecated Will be removed in the next release. */ - @Deprecated - void prepareSource( - ExoPlayer player, boolean isTopLevelSource, SourceInfoRefreshListener listener); - /** * Starts source preparation if not yet started, and adds a listener for timeline and/or manifest * updates. @@ -249,8 +245,7 @@ public interface MediaSource { * and other data. */ void prepareSource( - SourceInfoRefreshListener listener, - @Nullable TransferListener mediaTransferListener); + SourceInfoRefreshListener listener, @Nullable TransferListener mediaTransferListener); /** * Throws any pending error encountered while loading or refreshing source information. From 0c159984ee9825d76603c8c26c1038d333317ff7 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Tue, 5 Feb 2019 17:46:03 +0000 Subject: [PATCH 05/19] Set player on ads loader in IMA demo Issue: #5476 PiperOrigin-RevId: 232503736 --- .../android/exoplayer2/imademo/PlayerManager.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/demos/ima/src/main/java/com/google/android/exoplayer2/imademo/PlayerManager.java b/demos/ima/src/main/java/com/google/android/exoplayer2/imademo/PlayerManager.java index d67c4549d8..95c49c34b0 100644 --- a/demos/ima/src/main/java/com/google/android/exoplayer2/imademo/PlayerManager.java +++ b/demos/ima/src/main/java/com/google/android/exoplayer2/imademo/PlayerManager.java @@ -29,10 +29,6 @@ import com.google.android.exoplayer2.source.ads.AdsMediaSource; import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; -import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; -import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; -import com.google.android.exoplayer2.trackselection.TrackSelection; -import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; @@ -56,14 +52,9 @@ import com.google.android.exoplayer2.util.Util; } public void init(Context context, PlayerView playerView) { - // Create a default track selector. - TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); - TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); - // Create a player instance. - player = ExoPlayerFactory.newSimpleInstance(context, trackSelector); - - // Bind the player to the view. + player = ExoPlayerFactory.newSimpleInstance(context); + adsLoader.setPlayer(player); playerView.setPlayer(player); // This is the MediaSource representing the content media (i.e. not the ad). @@ -89,6 +80,7 @@ import com.google.android.exoplayer2.util.Util; contentPosition = player.getContentPosition(); player.release(); player = null; + adsLoader.setPlayer(null); } } From 73813b9b11d3ab8db1cc1e07e831b9ac4d9ea19c Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Tue, 5 Feb 2019 18:05:09 +0000 Subject: [PATCH 06/19] Switch to non-deprecated way of setting AdDisplayContainer PiperOrigin-RevId: 232507469 --- .../android/exoplayer2/ext/ima/ImaAdsLoader.java | 12 ++++++------ .../exoplayer2/ext/ima/SingletonImaFactory.java | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index 985408cb70..ef50538930 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -465,11 +465,11 @@ public final class ImaAdsLoader } imaSdkSettings.setPlayerType(IMA_SDK_SETTINGS_PLAYER_TYPE); imaSdkSettings.setPlayerVersion(IMA_SDK_SETTINGS_PLAYER_VERSION); - adsLoader = imaFactory.createAdsLoader(context, imaSdkSettings); period = new Timeline.Period(); adCallbacks = new ArrayList<>(/* initialCapacity= */ 1); adDisplayContainer = imaFactory.createAdDisplayContainer(); adDisplayContainer.setPlayer(/* videoAdPlayer= */ this); + adsLoader = imaFactory.createAdsLoader(context, imaSdkSettings, adDisplayContainer); adsLoader.addAdErrorListener(/* adErrorListener= */ this); adsLoader.addAdsLoadedListener(/* adsLoadedListener= */ this); fakeContentProgressElapsedRealtimeMs = C.TIME_UNSET; @@ -523,7 +523,6 @@ public final class ImaAdsLoader if (vastLoadTimeoutMs != TIMEOUT_UNSET) { request.setVastLoadTimeout(vastLoadTimeoutMs); } - request.setAdDisplayContainer(adDisplayContainer); request.setContentProgressProvider(this); request.setUserRequestContext(pendingAdRequestContext); adsLoader.requestAds(request); @@ -1372,9 +1371,9 @@ public final class ImaAdsLoader AdDisplayContainer createAdDisplayContainer(); /** @see com.google.ads.interactivemedia.v3.api.ImaSdkFactory#createAdsRequest() */ AdsRequest createAdsRequest(); - /** @see ImaSdkFactory#createAdsLoader(Context, ImaSdkSettings) */ + /** @see ImaSdkFactory#createAdsLoader(Context, ImaSdkSettings, AdDisplayContainer) */ com.google.ads.interactivemedia.v3.api.AdsLoader createAdsLoader( - Context context, ImaSdkSettings imaSdkSettings); + Context context, ImaSdkSettings imaSdkSettings, AdDisplayContainer adDisplayContainer); } /** Default {@link ImaFactory} for non-test usage, which delegates to {@link ImaSdkFactory}. */ @@ -1401,8 +1400,9 @@ public final class ImaAdsLoader @Override public com.google.ads.interactivemedia.v3.api.AdsLoader createAdsLoader( - Context context, ImaSdkSettings imaSdkSettings) { - return ImaSdkFactory.getInstance().createAdsLoader(context, imaSdkSettings); + Context context, ImaSdkSettings imaSdkSettings, AdDisplayContainer adDisplayContainer) { + return ImaSdkFactory.getInstance() + .createAdsLoader(context, imaSdkSettings, adDisplayContainer); } } } diff --git a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/SingletonImaFactory.java b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/SingletonImaFactory.java index dd46d8a68b..4efd8cf38c 100644 --- a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/SingletonImaFactory.java +++ b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/SingletonImaFactory.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.ext.ima; import android.content.Context; import com.google.ads.interactivemedia.v3.api.AdDisplayContainer; +import com.google.ads.interactivemedia.v3.api.AdsLoader; import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings; import com.google.ads.interactivemedia.v3.api.AdsRequest; import com.google.ads.interactivemedia.v3.api.ImaSdkSettings; @@ -64,8 +65,8 @@ final class SingletonImaFactory implements ImaAdsLoader.ImaFactory { } @Override - public com.google.ads.interactivemedia.v3.api.AdsLoader createAdsLoader( - Context context, ImaSdkSettings imaSdkSettings) { + public AdsLoader createAdsLoader( + Context context, ImaSdkSettings imaSdkSettings, AdDisplayContainer adDisplayContainer) { return adsLoader; } } From 2e9ef8abeb62437121472a7188b044c21d804db0 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Wed, 6 Feb 2019 16:04:58 +0000 Subject: [PATCH 07/19] Update test names for attach -> start renaming PiperOrigin-RevId: 232676346 --- .../android/exoplayer2/ext/ima/ImaAdsLoaderTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 0b097f26f0..0253e7db13 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 @@ -109,7 +109,7 @@ public class ImaAdsLoaderTest { } @Test - public void testAttachPlayer_setsAdUiViewGroup() { + public void testStart_setsAdUiViewGroup() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); imaAdsLoader.start(adsLoaderListener, adUiViewGroup); @@ -117,7 +117,7 @@ public class ImaAdsLoaderTest { } @Test - public void testAttachPlayer_updatesAdPlaybackState() { + public void testStart_updatesAdPlaybackState() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); imaAdsLoader.start(adsLoaderListener, adUiViewGroup); @@ -128,14 +128,14 @@ public class ImaAdsLoaderTest { } @Test - public void testAttachAfterRelease() { + public void testStartAfterRelease() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); imaAdsLoader.release(); imaAdsLoader.start(adsLoaderListener, adUiViewGroup); } @Test - public void testAttachAndCallbacksAfterRelease() { + public void testStartAndCallbacksAfterRelease() { setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS); imaAdsLoader.release(); imaAdsLoader.start(adsLoaderListener, adUiViewGroup); From c16af7371776f46adbe5a06d61765466ef693d26 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Fri, 8 Feb 2019 09:04:56 +0000 Subject: [PATCH 08/19] Remove deprecated ImaAdsMediaSource and constructors Given the change to require setPlayer on AdsLoaders, it seems like a good opportunity to clean up deprecated ads-related symbols. PiperOrigin-RevId: 233020171 --- .../exoplayer2/ext/ima/ImaAdsMediaSource.java | 115 ------------- .../exoplayer2/source/ads/AdsLoader.java | 23 +-- .../exoplayer2/source/ads/AdsMediaSource.java | 156 +----------------- 3 files changed, 9 insertions(+), 285 deletions(-) delete mode 100644 extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java deleted file mode 100644 index bcccd6cec7..0000000000 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsMediaSource.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.exoplayer2.ext.ima; - -import android.os.Handler; -import android.support.annotation.Nullable; -import android.view.ViewGroup; -import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.source.BaseMediaSource; -import com.google.android.exoplayer2.source.MediaPeriod; -import com.google.android.exoplayer2.source.MediaSource; -import com.google.android.exoplayer2.source.MediaSource.SourceInfoRefreshListener; -import com.google.android.exoplayer2.source.ads.AdsMediaSource; -import com.google.android.exoplayer2.upstream.Allocator; -import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.TransferListener; -import java.io.IOException; - -/** - * A {@link MediaSource} that inserts ads linearly with a provided content media source. - * - * @deprecated Use {@link com.google.android.exoplayer2.source.ads.AdsMediaSource} with - * ImaAdsLoader. - */ -@Deprecated -public final class ImaAdsMediaSource extends BaseMediaSource implements SourceInfoRefreshListener { - - private final AdsMediaSource adsMediaSource; - - /** - * Constructs a new source that inserts ads linearly with the content specified by - * {@code contentMediaSource}. - * - * @param contentMediaSource The {@link MediaSource} providing the content to play. - * @param dataSourceFactory Factory for data sources used to load ad media. - * @param imaAdsLoader The loader for ads. - * @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI. - */ - public ImaAdsMediaSource(MediaSource contentMediaSource, DataSource.Factory dataSourceFactory, - ImaAdsLoader imaAdsLoader, ViewGroup adUiViewGroup) { - this(contentMediaSource, dataSourceFactory, imaAdsLoader, adUiViewGroup, null, null); - } - - /** - * Constructs a new source that inserts ads linearly with the content specified by {@code - * contentMediaSource}. - * - * @param contentMediaSource The {@link MediaSource} providing the content to play. - * @param dataSourceFactory Factory for data sources used to load ad media. - * @param imaAdsLoader The loader for ads. - * @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI. - * @param eventHandler A handler for events. May be null if delivery of events is not required. - * @param eventListener A listener of events. May be null if delivery of events is not required. - */ - public ImaAdsMediaSource( - MediaSource contentMediaSource, - DataSource.Factory dataSourceFactory, - ImaAdsLoader imaAdsLoader, - ViewGroup adUiViewGroup, - @Nullable Handler eventHandler, - @Nullable AdsMediaSource.EventListener eventListener) { - adsMediaSource = new AdsMediaSource(contentMediaSource, dataSourceFactory, imaAdsLoader, - adUiViewGroup, eventHandler, eventListener); - } - - @Override - @Nullable - public Object getTag() { - return adsMediaSource.getTag(); - } - - @Override - public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { - adsMediaSource.prepareSource(/* listener= */ this, mediaTransferListener); - } - - @Override - public void maybeThrowSourceInfoRefreshError() throws IOException { - adsMediaSource.maybeThrowSourceInfoRefreshError(); - } - - @Override - public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) { - return adsMediaSource.createPeriod(id, allocator, startPositionUs); - } - - @Override - public void releasePeriod(MediaPeriod mediaPeriod) { - adsMediaSource.releasePeriod(mediaPeriod); - } - - @Override - public void releaseSourceInternal() { - adsMediaSource.releaseSource(/* listener= */ this); - } - - @Override - public void onSourceInfoRefreshed( - MediaSource source, Timeline timeline, @Nullable Object manifest) { - refreshSourceInfo(timeline, manifest); - } -} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java index 51de225414..48ac79f227 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsLoader.java @@ -26,7 +26,7 @@ import java.io.IOException; /** * Interface for loaders of ads, which can be used with {@link AdsMediaSource}. * - *

Ad loaders notify the {@link AdsMediaSource} about events via {@link EventListener}. In + *

Ads loaders notify the {@link AdsMediaSource} about events via {@link EventListener}. In * particular, implementations must call {@link EventListener#onAdPlaybackState(AdPlaybackState)} * with a new copy of the current {@link AdPlaybackState} whenever further information about ads * becomes known (for example, when an ad media URI is available, or an ad has played to the end). @@ -44,9 +44,7 @@ import java.io.IOException; */ public interface AdsLoader { - /** - * Listener for ad loader events. All methods are called on the main thread. - */ + /** Listener for ads loader events. All methods are called on the main thread. */ interface EventListener { /** @@ -54,7 +52,7 @@ public interface AdsLoader { * * @param adPlaybackState The new ad playback state. */ - void onAdPlaybackState(AdPlaybackState adPlaybackState); + default void onAdPlaybackState(AdPlaybackState adPlaybackState) {} /** * Called when there was an error loading ads. @@ -62,18 +60,13 @@ public interface AdsLoader { * @param error The error. * @param dataSpec The data spec associated with the load error. */ - void onAdLoadError(AdLoadException error, DataSpec dataSpec); + default void onAdLoadError(AdLoadException error, DataSpec dataSpec) {} - /** - * Called when the user clicks through an ad (for example, following a 'learn more' link). - */ - void onAdClicked(); - - /** - * Called when the user taps a non-clickthrough part of an ad. - */ - void onAdTapped(); + /** Called when the user clicks through an ad (for example, following a 'learn more' link). */ + default void onAdClicked() {} + /** Called when the user taps a non-clickthrough part of an ad. */ + default void onAdTapped() {} } // Methods called by the application. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java index 4754466235..e7a5d05173 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java @@ -139,46 +139,6 @@ public final class AdsMediaSource extends CompositeMediaSource { } } - /** - * Listener for ads media source events. - * - * @deprecated To listen for ad load error events, add a listener via {@link - * #addEventListener(Handler, MediaSourceEventListener)} and check for {@link - * AdLoadException}s in {@link MediaSourceEventListener#onLoadError(int, MediaPeriodId, - * LoadEventInfo, MediaLoadData, IOException, boolean)}. Individual ads loader implementations - * should expose ad interaction events, if applicable. - */ - @Deprecated - public interface EventListener { - - /** - * Called if there was an error loading one or more ads. The loader will skip the problematic - * ad(s). - * - * @param error The error. - */ - void onAdLoadError(IOException error); - - /** - * Called when an unexpected internal error is encountered while loading ads. The loader will - * skip all remaining ads, as the error is not recoverable. - * - * @param error The error. - */ - void onInternalAdLoadError(RuntimeException error); - - /** - * Called when the user clicks through an ad (for example, following a 'learn more' link). - */ - void onAdClicked(); - - /** - * Called when the user taps a non-clickthrough part of an ad. - */ - void onAdTapped(); - - } - // Used to identify the content "child" source for CompositeMediaSource. private static final MediaPeriodId DUMMY_CONTENT_MEDIA_PERIOD_ID = new MediaPeriodId(/* periodUid= */ new Object()); @@ -187,8 +147,6 @@ public final class AdsMediaSource extends CompositeMediaSource { private final MediaSourceFactory adMediaSourceFactory; private final AdsLoader adsLoader; private final ViewGroup adUiViewGroup; - @Nullable private final Handler eventHandler; - @Nullable private final EventListener eventListener; private final Handler mainHandler; private final Map> deferredMediaPeriodByAdMediaSource; private final Timeline.Period period; @@ -219,9 +177,7 @@ public final class AdsMediaSource extends CompositeMediaSource { contentMediaSource, new ExtractorMediaSource.Factory(dataSourceFactory), adsLoader, - adUiViewGroup, - /* eventHandler= */ null, - /* eventListener= */ null); + adUiViewGroup); } /** @@ -238,78 +194,10 @@ public final class AdsMediaSource extends CompositeMediaSource { MediaSourceFactory adMediaSourceFactory, AdsLoader adsLoader, ViewGroup adUiViewGroup) { - this( - contentMediaSource, - adMediaSourceFactory, - adsLoader, - adUiViewGroup, - /* eventHandler= */ null, - /* eventListener= */ null); - } - - /** - * Constructs a new source that inserts ads linearly with the content specified by {@code - * contentMediaSource}. Ad media is loaded using {@link ExtractorMediaSource}. - * - * @param contentMediaSource The {@link MediaSource} providing the content to play. - * @param dataSourceFactory Factory for data sources used to load ad media. - * @param adsLoader The loader for ads. - * @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI. - * @param eventHandler A handler for events. May be null if delivery of events is not required. - * @param eventListener A listener of events. May be null if delivery of events is not required. - * @deprecated To listen for ad load error events, add a listener via {@link - * #addEventListener(Handler, MediaSourceEventListener)} and check for {@link - * AdLoadException}s in {@link MediaSourceEventListener#onLoadError(int, MediaPeriodId, - * LoadEventInfo, MediaLoadData, IOException, boolean)}. Individual ads loader implementations - * should expose ad interaction events, if applicable. - */ - @Deprecated - public AdsMediaSource( - MediaSource contentMediaSource, - DataSource.Factory dataSourceFactory, - AdsLoader adsLoader, - ViewGroup adUiViewGroup, - @Nullable Handler eventHandler, - @Nullable EventListener eventListener) { - this( - contentMediaSource, - new ExtractorMediaSource.Factory(dataSourceFactory), - adsLoader, - adUiViewGroup, - eventHandler, - eventListener); - } - - /** - * Constructs a new source that inserts ads linearly with the content specified by {@code - * contentMediaSource}. - * - * @param contentMediaSource The {@link MediaSource} providing the content to play. - * @param adMediaSourceFactory Factory for media sources used to load ad media. - * @param adsLoader The loader for ads. - * @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI. - * @param eventHandler A handler for events. May be null if delivery of events is not required. - * @param eventListener A listener of events. May be null if delivery of events is not required. - * @deprecated To listen for ad load error events, add a listener via {@link - * #addEventListener(Handler, MediaSourceEventListener)} and check for {@link - * AdLoadException}s in {@link MediaSourceEventListener#onLoadError(int, MediaPeriodId, - * LoadEventInfo, MediaLoadData, IOException, boolean)}. Individual ads loader implementations - * should expose ad interaction events, if applicable. - */ - @Deprecated - public AdsMediaSource( - MediaSource contentMediaSource, - MediaSourceFactory adMediaSourceFactory, - AdsLoader adsLoader, - ViewGroup adUiViewGroup, - @Nullable Handler eventHandler, - @Nullable EventListener eventListener) { this.contentMediaSource = contentMediaSource; this.adMediaSourceFactory = adMediaSourceFactory; this.adsLoader = adsLoader; this.adUiViewGroup = adUiViewGroup; - this.eventHandler = eventHandler; - this.eventListener = eventListener; mainHandler = new Handler(Looper.getMainLooper()); deferredMediaPeriodByAdMediaSource = new HashMap<>(); period = new Timeline.Period(); @@ -522,36 +410,6 @@ public final class AdsMediaSource extends CompositeMediaSource { }); } - @Override - public void onAdClicked() { - if (released) { - return; - } - if (eventHandler != null && eventListener != null) { - eventHandler.post( - () -> { - if (!released) { - eventListener.onAdClicked(); - } - }); - } - } - - @Override - public void onAdTapped() { - if (released) { - return; - } - if (eventHandler != null && eventListener != null) { - eventHandler.post( - () -> { - if (!released) { - eventListener.onAdTapped(); - } - }); - } - } - @Override public void onAdLoadError(final AdLoadException error, DataSpec dataSpec) { if (released) { @@ -568,18 +426,6 @@ public final class AdsMediaSource extends CompositeMediaSource { /* bytesLoaded= */ 0, error, /* wasCanceled= */ true); - if (eventHandler != null && eventListener != null) { - eventHandler.post( - () -> { - if (!released) { - if (error.type == AdLoadException.TYPE_UNEXPECTED) { - eventListener.onInternalAdLoadError(error.getRuntimeExceptionForUnexpected()); - } else { - eventListener.onAdLoadError(error); - } - } - }); - } } } From e7687764a178629d5349c566228a09f8eda237cb Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Fri, 8 Feb 2019 17:54:27 +0000 Subject: [PATCH 09/19] Add an overlay FrameLayout for ad UI This will be used instead of the current overlay FrameLayout (which apps can interact with directly). PiperOrigin-RevId: 233077175 --- .../google/android/exoplayer2/ui/PlayerView.java | 13 ++++++++++++- .../src/main/res/layout/exo_simple_player_view.xml | 4 ++++ library/ui/src/main/res/values/ids.xml | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerView.java index 9742d0005a..8871767f49 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerView.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerView.java @@ -221,6 +221,11 @@ import java.util.List; *

+ *
  • {@code exo_ad_overlay} - A {@link FrameLayout} positioned on top of the player which + * is used to show ad UI (if applicable). + * *
  • {@code exo_overlay} - A {@link FrameLayout} positioned on top of the player which * the app can access via {@link #getOverlayFrameLayout()}, provided for convenience. *