-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[interactive_media_ads] Adds support to define parameters that control the rendering of ads #8057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 27 commits
fc00df8
efc63c0
ca5c47d
70be676
d0e0de9
c10c14f
7f9a563
5b3e3ae
bae565f
e5abb39
3071bf5
bf2a118
aa443bc
832d86e
efa6b2d
63eabc3
b69a9bd
e7aaf61
4c8bc86
300a608
b2abcd1
3b79dd0
e80a923
1e58518
9d85bf8
d9b81e6
35e05c5
aea49fe
4b4bf9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'ads_loader.dart'; | ||
import 'platform_interface/platform_interface.dart'; | ||
|
||
/// Defines parameters that control the rendering of ads. | ||
class AdsRenderingSettings { | ||
/// Creates an [AdsRenderingSettings]. | ||
AdsRenderingSettings({ | ||
int? bitrate, | ||
bool? enablePreloading, | ||
Duration loadVideoTimeout = const Duration(seconds: 8), | ||
List<String>? mimeTypes, | ||
Duration? playAdsAfterTime, | ||
Set<AdUIElement>? uiElements, | ||
}) : this.fromPlatform(PlatformAdsRenderingSettings( | ||
PlatformAdsRenderingSettingsCreationParams( | ||
bitrate: bitrate, | ||
enablePreloading: enablePreloading, | ||
loadVideoTimeout: loadVideoTimeout, | ||
mimeTypes: mimeTypes, | ||
playAdsAfterTime: playAdsAfterTime, | ||
uiElements: uiElements, | ||
), | ||
)); | ||
|
||
/// Constructs an [AdsRenderingSettings] from a specific platform | ||
/// implementation. | ||
AdsRenderingSettings.fromPlatform(this.platform); | ||
|
||
/// Implementation of [PlatformAdsRenderingSettings] for the current platform. | ||
final PlatformAdsRenderingSettings platform; | ||
|
||
/// Maximum recommended bitrate. | ||
/// | ||
/// The value is in kbit/s. | ||
/// | ||
/// The SDK will select media which has a bitrate below the specified max or | ||
/// the closest bitrate if there is no media with a lower bitrate found. | ||
/// | ||
/// If null, the bitrate will be selected by the SDK, using the currently | ||
/// detected network speed (cellular or Wi-Fi). | ||
int? get bitrate => platform.params.bitrate; | ||
|
||
/// If set, the SDK will instruct the player to load the creative in response | ||
/// to [AdsManager.init]. | ||
/// | ||
/// This allows the player to preload the ad at any point before | ||
/// [AdsManager.start]. | ||
/// | ||
/// If null, the platform will decide the default value. | ||
bool? get enablePreloading => platform.params.enablePreloading; | ||
|
||
/// Specifies a non-default amount of time to wait for media to load before | ||
/// timing out. | ||
/// | ||
/// This only applies to the IMA client-side SDK.. | ||
Duration get loadVideoTimeout => platform.params.loadVideoTimeout; | ||
|
||
/// The SDK will prioritize the media with MIME type on the list. | ||
/// | ||
/// This only refers to the mime types of videos to be selected for linear | ||
/// ads. | ||
List<String>? get mimeTypes => platform.params.mimeTypes; | ||
|
||
/// For VMAP and ad rules playlists, only play ad breaks scheduled after this | ||
/// time. | ||
/// | ||
/// This setting is strictly after the specified time. For example, setting | ||
/// `playAdsAfterTime` to 15s will ignore an ad break scheduled to play at | ||
/// 15s. | ||
Duration? get playAdsAfterTime => platform.params.playAdsAfterTime; | ||
|
||
/// Sets the ad UI elements to be rendered by the IMA SDK. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Sets the" -> "The" (since it's a getter) |
||
/// | ||
/// Some modifications to the uiElements list may have no effect for specific | ||
/// ads. | ||
Set<AdUIElement>? get uiElements => platform.params.uiElements; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment about nullability. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'dart:async'; | ||
|
||
import 'package:meta/meta.dart'; | ||
|
||
import '../platform_interface/platform_interface.dart'; | ||
import 'interactive_media_ads.g.dart' as ima; | ||
import 'interactive_media_ads_proxy.dart'; | ||
|
||
/// Android implementation of [PlatformAdsRenderingSettingsCreationParams]. | ||
final class AndroidAdsRenderingSettingsCreationParams | ||
extends PlatformAdsRenderingSettingsCreationParams { | ||
/// Constructs an [AndroidAdsRenderingSettingsCreationParams]. | ||
const AndroidAdsRenderingSettingsCreationParams({ | ||
super.bitrate, | ||
super.enablePreloading, | ||
super.loadVideoTimeout, | ||
super.mimeTypes, | ||
super.playAdsAfterTime, | ||
super.uiElements, | ||
this.enableCustomTabs = false, | ||
@visibleForTesting InteractiveMediaAdsProxy? proxy, | ||
}) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), | ||
super(); | ||
|
||
/// Creates a [AndroidAdsRenderingSettingsCreationParams] from an instance of | ||
/// [PlatformAdsRenderingSettingsCreationParams]. | ||
factory AndroidAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( | ||
PlatformAdsRenderingSettingsCreationParams params, { | ||
bool enableCustomTabs = false, | ||
}) { | ||
return AndroidAdsRenderingSettingsCreationParams( | ||
bitrate: params.bitrate, | ||
enablePreloading: params.enablePreloading, | ||
loadVideoTimeout: params.loadVideoTimeout, | ||
mimeTypes: params.mimeTypes, | ||
playAdsAfterTime: params.playAdsAfterTime, | ||
uiElements: params.uiElements, | ||
enableCustomTabs: enableCustomTabs, | ||
); | ||
} | ||
|
||
final InteractiveMediaAdsProxy _proxy; | ||
|
||
/// Notifies the SDK whether to launch the click-through URL using Custom Tabs | ||
/// feature. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thought process was that I was actually considering what a better design for setting optional native parameters was. Is it better to always set a value if the default is stated or provide an option to not set it? (e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the internal implementation level, either is fine, we should just document what |
||
final bool enableCustomTabs; | ||
} | ||
|
||
/// Android implementation of [PlatformAdsRenderingSettings]. | ||
base class AndroidAdsRenderingSettings extends PlatformAdsRenderingSettings { | ||
/// Constructs an [AndroidAdsRenderingSettings]. | ||
AndroidAdsRenderingSettings(super.params) : super.implementation() { | ||
final Completer<ima.AdsRenderingSettings> nativeSettingsCompleter = | ||
Completer<ima.AdsRenderingSettings>(); | ||
nativeSettings = nativeSettingsCompleter.future; | ||
|
||
_androidParams._proxy | ||
.instanceImaSdkFactory() | ||
.createAdsRenderingSettings() | ||
.then((ima.AdsRenderingSettings nativeSettings) async { | ||
await Future.wait(<Future<void>>[ | ||
if (_androidParams.bitrate != null) | ||
nativeSettings.setBitrateKbps(params.bitrate!), | ||
if (_androidParams.enablePreloading != null) | ||
nativeSettings.setEnablePreloading(_androidParams.enablePreloading!), | ||
nativeSettings.setLoadVideoTimeout( | ||
_androidParams.loadVideoTimeout.inMilliseconds, | ||
), | ||
if (_androidParams.mimeTypes != null) | ||
nativeSettings.setMimeTypes(_androidParams.mimeTypes!), | ||
if (_androidParams.playAdsAfterTime != null) | ||
nativeSettings.setPlayAdsAfterTime( | ||
_androidParams.playAdsAfterTime!.inMicroseconds / | ||
Duration.microsecondsPerSecond, | ||
), | ||
if (_androidParams.uiElements != null) | ||
nativeSettings.setUiElements( | ||
_androidParams.uiElements!.map( | ||
(AdUIElement element) { | ||
return switch (element) { | ||
AdUIElement.adAttribution => ima.UiElement.adAttribution, | ||
AdUIElement.countdown => ima.UiElement.countdown, | ||
}; | ||
}, | ||
).toList(), | ||
), | ||
nativeSettings.setEnableCustomTabs(_androidParams.enableCustomTabs) | ||
]); | ||
|
||
nativeSettingsCompleter.complete(nativeSettings); | ||
}); | ||
} | ||
|
||
/// The native Android AdsRenderingSettings. | ||
/// | ||
/// The instantiation of the native AdsRenderingSettings is asynchronous, so | ||
/// this provides access to the value after it is created and all params have | ||
/// been set. | ||
@internal | ||
late final Future<ima.AdsRenderingSettings> nativeSettings; | ||
|
||
late final AndroidAdsRenderingSettingsCreationParams _androidParams = | ||
params is AndroidAdsRenderingSettingsCreationParams | ||
? params as AndroidAdsRenderingSettingsCreationParams | ||
: AndroidAdsRenderingSettingsCreationParams | ||
.fromPlatformAdsRenderingSettingsCreationParams( | ||
params, | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're keeping nullability, this needs a comment explaining that null means platform default.