Add focusSkipButtonWhenAvailable to focus UI on ATV

For TV devices the skip button needs to have the focus to be accessible with
the remote control. This property makes this configurable while being set to
true by default.

PiperOrigin-RevId: 501077608
(cherry picked from commit d2898b70ead3b2ad1244a730c3b456146755c138)
This commit is contained in:
bachinger 2023-01-10 21:19:55 +00:00 committed by christosts
parent f4386071d7
commit 61eeb8b15e
2 changed files with 34 additions and 5 deletions

View File

@ -67,6 +67,7 @@ import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DrmSessionManagerProvider;
import com.google.android.exoplayer2.ext.ima.ImaUtil.ServerSideAdInsertionConfiguration;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.emsg.EventMessage;
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
@ -191,6 +192,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
@Nullable private AdErrorEvent.AdErrorListener adErrorListener;
private State state;
private ImmutableList<CompanionAdSlot> companionAdSlots;
private boolean focusSkipButtonWhenAvailable;
/**
* Creates an instance.
@ -203,6 +205,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
this.adViewProvider = adViewProvider;
companionAdSlots = ImmutableList.of();
state = new State(ImmutableMap.of());
focusSkipButtonWhenAvailable = true;
}
/**
@ -272,6 +275,22 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
return this;
}
/**
* Sets whether to focus the skip button (when available) on Android TV devices. The default
* setting is {@code true}.
*
* @param focusSkipButtonWhenAvailable Whether to focus the skip button (when available) on
* Android TV devices.
* @return This builder, for convenience.
* @see AdsRenderingSettings#setFocusSkipButtonWhenAvailable(boolean)
*/
@CanIgnoreReturnValue
public AdsLoader.Builder setFocusSkipButtonWhenAvailable(
boolean focusSkipButtonWhenAvailable) {
this.focusSkipButtonWhenAvailable = focusSkipButtonWhenAvailable;
return this;
}
/** Returns a new {@link AdsLoader}. */
public AdsLoader build() {
@Nullable ImaSdkSettings imaSdkSettings = this.imaSdkSettings;
@ -279,13 +298,14 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
imaSdkSettings.setLanguage(Util.getSystemLanguageCodes()[0]);
}
ImaUtil.ServerSideAdInsertionConfiguration configuration =
new ImaUtil.ServerSideAdInsertionConfiguration(
ServerSideAdInsertionConfiguration configuration =
new ServerSideAdInsertionConfiguration(
adViewProvider,
imaSdkSettings,
adEventListener,
adErrorListener,
companionAdSlots,
focusSkipButtonWhenAvailable,
imaSdkSettings.isDebugMode());
return new AdsLoader(context, configuration, state);
}
@ -352,7 +372,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
}
}
private final ImaUtil.ServerSideAdInsertionConfiguration configuration;
private final ServerSideAdInsertionConfiguration configuration;
private final Context context;
private final Map<ImaServerSideAdInsertionMediaSource, MediaSourceResourceHolder>
mediaSourceResources;
@ -361,7 +381,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
@Nullable private Player player;
private AdsLoader(
Context context, ImaUtil.ServerSideAdInsertionConfiguration configuration, State state) {
Context context, ServerSideAdInsertionConfiguration configuration, State state) {
this.context = context.getApplicationContext();
this.configuration = configuration;
mediaSourceResources = new HashMap<>();
@ -502,6 +522,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
StreamManagerLoadable streamManagerLoadable =
new StreamManagerLoadable(
sdkAdsLoader,
adsLoader.configuration,
streamRequest,
streamPlayer,
applicationAdErrorListener,
@ -930,6 +951,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
implements Loadable, AdsLoadedListener, AdErrorListener {
private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader;
private final ServerSideAdInsertionConfiguration serverSideAdInsertionConfiguration;
private final StreamRequest request;
private final StreamPlayer streamPlayer;
@Nullable private final AdErrorListener adErrorListener;
@ -946,11 +968,13 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
/** Creates an instance. */
private StreamManagerLoadable(
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader,
ServerSideAdInsertionConfiguration serverSideAdInsertionConfiguration,
StreamRequest request,
StreamPlayer streamPlayer,
@Nullable AdErrorListener adErrorListener,
int loadVideoTimeoutMs) {
this.adsLoader = adsLoader;
this.serverSideAdInsertionConfiguration = serverSideAdInsertionConfiguration;
this.request = request;
this.streamPlayer = streamPlayer;
this.adErrorListener = adErrorListener;
@ -1027,6 +1051,8 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
AdsRenderingSettings adsRenderingSettings =
ImaSdkFactory.getInstance().createAdsRenderingSettings();
adsRenderingSettings.setLoadVideoTimeout(loadVideoTimeoutMs);
adsRenderingSettings.setFocusSkipButtonWhenAvailable(
serverSideAdInsertionConfiguration.focusSkipButtonWhenAvailable);
// After initialization completed the streamUri will be reported to the streamPlayer.
streamManager.init(adsRenderingSettings);
this.streamManager = streamManager;
@ -1259,7 +1285,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
private static StreamDisplayContainer createStreamDisplayContainer(
ImaSdkFactory imaSdkFactory,
ImaUtil.ServerSideAdInsertionConfiguration config,
ServerSideAdInsertionConfiguration config,
StreamPlayer streamPlayer) {
StreamDisplayContainer container =
ImaSdkFactory.createStreamDisplayContainer(

View File

@ -166,6 +166,7 @@ import java.util.Set;
@Nullable public final AdEvent.AdEventListener applicationAdEventListener;
@Nullable public final AdErrorEvent.AdErrorListener applicationAdErrorListener;
public final ImmutableList<CompanionAdSlot> companionAdSlots;
public final boolean focusSkipButtonWhenAvailable;
public final boolean debugModeEnabled;
public ServerSideAdInsertionConfiguration(
@ -174,12 +175,14 @@ import java.util.Set;
@Nullable AdEvent.AdEventListener applicationAdEventListener,
@Nullable AdErrorEvent.AdErrorListener applicationAdErrorListener,
List<CompanionAdSlot> companionAdSlots,
boolean focusSkipButtonWhenAvailable,
boolean debugModeEnabled) {
this.imaSdkSettings = imaSdkSettings;
this.adViewProvider = adViewProvider;
this.applicationAdEventListener = applicationAdEventListener;
this.applicationAdErrorListener = applicationAdErrorListener;
this.companionAdSlots = ImmutableList.copyOf(companionAdSlots);
this.focusSkipButtonWhenAvailable = focusSkipButtonWhenAvailable;
this.debugModeEnabled = debugModeEnabled;
}
}