Commit 58293abc by andrewlewis Committed by Oliver Woodman

Remove IMA dependency and add AdsMediaSource

AdsMediaSource lives in the core library so only ImaAdsLoader remains in
the ima extension. AdsMediaSource takes an AdsLoader implementation.

ImaAdsMediaSource is deprecated rather than removed for now.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=168707921
parent 0ad39c64
......@@ -56,6 +56,8 @@ import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
......@@ -73,8 +75,6 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
......@@ -129,9 +129,9 @@ public class PlayerActivity extends Activity implements OnClickListener, EventLi
// Fields used only for ad playback. The ads loader is loaded via reflection.
private Object imaAdsLoader; // com.google.android.exoplayer2.ext.ima.ImaAdsLoader
private AdsLoader adsLoader;
private Uri loadedAdTagUri;
private ViewGroup adOverlayViewGroup;
private ViewGroup adUiViewGroup;
// Activity lifecycle
......@@ -453,32 +453,20 @@ public class PlayerActivity extends Activity implements OnClickListener, EventLi
// Load the extension source using reflection so the demo app doesn't have to depend on it.
// The ads loader is reused for multiple playbacks, so that ad playback can resume.
Class<?> loaderClass = Class.forName("com.google.android.exoplayer2.ext.ima.ImaAdsLoader");
if (imaAdsLoader == null) {
imaAdsLoader = loaderClass.getConstructor(Context.class, Uri.class)
if (adsLoader == null) {
adsLoader = (AdsLoader) loaderClass.getConstructor(Context.class, Uri.class)
.newInstance(this, adTagUri);
adOverlayViewGroup = new FrameLayout(this);
adUiViewGroup = new FrameLayout(this);
// The demo app has a non-null overlay frame layout.
simpleExoPlayerView.getOverlayFrameLayout().addView(adOverlayViewGroup);
simpleExoPlayerView.getOverlayFrameLayout().addView(adUiViewGroup);
}
Class<?> sourceClass =
Class.forName("com.google.android.exoplayer2.ext.ima.ImaAdsMediaSource");
Constructor<?> constructor = sourceClass.getConstructor(MediaSource.class,
DataSource.Factory.class, loaderClass, ViewGroup.class);
return (MediaSource) constructor.newInstance(mediaSource, mediaDataSourceFactory, imaAdsLoader,
adOverlayViewGroup);
return new AdsMediaSource(mediaSource, mediaDataSourceFactory, adsLoader, adUiViewGroup);
}
private void releaseAdsLoader() {
if (imaAdsLoader != null) {
try {
Class<?> loaderClass = Class.forName("com.google.android.exoplayer2.ext.ima.ImaAdsLoader");
Method releaseMethod = loaderClass.getMethod("release");
releaseMethod.invoke(imaAdsLoader);
} catch (Exception e) {
// Should never happen.
throw new IllegalStateException(e);
}
imaAdsLoader = null;
if (adsLoader != null) {
adsLoader.release();
adsLoader = null;
loadedAdTagUri = null;
simpleExoPlayerView.getOverlayFrameLayout().removeAllViews();
}
......
......@@ -29,7 +29,6 @@ import com.google.ads.interactivemedia.v3.api.AdEvent;
import com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener;
import com.google.ads.interactivemedia.v3.api.AdEvent.AdEventType;
import com.google.ads.interactivemedia.v3.api.AdPodInfo;
import com.google.ads.interactivemedia.v3.api.AdsLoader;
import com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener;
import com.google.ads.interactivemedia.v3.api.AdsManager;
import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent;
......@@ -48,6 +47,8 @@ import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
......@@ -58,40 +59,9 @@ import java.util.Map;
/**
* Loads ads using the IMA SDK. All methods are called on the main thread.
*/
public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
public final class ImaAdsLoader implements AdsLoader, Player.EventListener, VideoAdPlayer,
ContentProgressProvider, AdErrorListener, AdsLoadedListener, AdEventListener {
/**
* Listener for ad loader events. All methods are called on the main thread.
*/
/* package */ interface EventListener {
/**
* Called when the ad playback state has been updated.
*
* @param adPlaybackState The new ad playback state.
*/
void onAdPlaybackState(AdPlaybackState adPlaybackState);
/**
* Called when there was an error loading ads.
*
* @param error The error.
*/
void onLoadError(IOException 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();
}
static {
ExoPlayerLibraryInfo.registerModule("goog.exo.ima");
}
......@@ -126,7 +96,7 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
private final List<VideoAdPlayerCallback> adCallbacks;
private final ImaSdkFactory imaSdkFactory;
private final AdDisplayContainer adDisplayContainer;
private final AdsLoader adsLoader;
private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader;
private EventListener eventListener;
private Player player;
......@@ -160,7 +130,8 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
*/
private boolean imaPausedInAd;
/**
* Whether {@link AdsLoader#contentComplete()} has been called since starting ad playback.
* Whether {@link com.google.ads.interactivemedia.v3.api.AdsLoader#contentComplete()} has been
* called since starting ad playback.
*/
private boolean sentContentComplete;
......@@ -248,15 +219,8 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
contentDurationMs = C.TIME_UNSET;
}
/**
* Attaches a player that will play ads loaded using this instance.
*
* @param player The player instance that will play the loaded ads.
* @param eventListener Listener for ads loader events.
* @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI.
*/
/* package */ void attachPlayer(ExoPlayer player, EventListener eventListener,
ViewGroup adUiViewGroup) {
@Override
public void attachPlayer(ExoPlayer player, EventListener eventListener, ViewGroup adUiViewGroup) {
this.player = player;
this.eventListener = eventListener;
this.adUiViewGroup = adUiViewGroup;
......@@ -265,7 +229,7 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
adDisplayContainer.setAdContainer(adUiViewGroup);
player.addListener(this);
if (adPlaybackState != null) {
eventListener.onAdPlaybackState(adPlaybackState);
eventListener.onAdPlaybackState(adPlaybackState.copy());
if (imaPausedContent) {
adsManager.resume();
}
......@@ -274,12 +238,8 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
}
}
/**
* Detaches the attached player and event listener. To attach a new player, call
* {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. Call {@link #release()} to release
* all resources associated with this instance.
*/
/* package */ void detachPlayer() {
@Override
public void detachPlayer() {
if (adsManager != null && imaPausedContent) {
adPlaybackState.setAdResumePositionUs(C.msToUs(player.getCurrentPosition()));
adsManager.pause();
......@@ -292,9 +252,7 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
adUiViewGroup = null;
}
/**
* Releases the loader. Must be called when the instance is no longer needed.
*/
@Override
public void release() {
released = true;
if (adsManager != null) {
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.ext.ima;
package com.google.android.exoplayer2.source.ads;
import android.net.Uri;
import com.google.android.exoplayer2.C;
......@@ -22,7 +22,7 @@ import java.util.Arrays;
/**
* Represents the structure of ads to play and the state of loaded/played ads.
*/
/* package */ final class AdPlaybackState {
public final class AdPlaybackState {
/**
* The number of ad groups.
......
/*
* 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.source.ads;
import android.view.ViewGroup;
import com.google.android.exoplayer2.ExoPlayer;
import java.io.IOException;
/**
* Interface for loaders of ads, which can be used with {@link AdsMediaSource}.
* <p>
* Ad 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).
* <p>
* {@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, store the current playback position via
* {@link AdPlaybackState#setAdResumePositionUs(long)}.
* <p>
* 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.
*/
public interface AdsLoader {
/**
* Listener for ad loader events. All methods are called on the main thread.
*/
interface EventListener {
/**
* Called when the ad playback state has been updated.
*
* @param adPlaybackState The new ad playback state.
*/
void onAdPlaybackState(AdPlaybackState adPlaybackState);
/**
* Called when there was an error loading ads.
*
* @param error The error.
*/
void onLoadError(IOException 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();
}
/**
* Attaches a player that will play ads loaded using this instance. Called on the main thread by
* {@link AdsMediaSource}.
*
* @param player The player instance that will play the loaded ads.
* @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);
/**
* Detaches the attached player and 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();
}
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.ext.ima;
package com.google.android.exoplayer2.source.ads;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline;
......
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