[interactive_media_ads] Adds support for time offsets of ad breaks (#9953)
Fixes https://github.com/flutter/flutter/issues/174405
## Pre-Review Checklist
**Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.
[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md
index 5c84cf2..456b0b5 100644
--- a/packages/interactive_media_ads/CHANGELOG.md
+++ b/packages/interactive_media_ads/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.2.7
+
+* Adds support to retrieve content time offsets at which ad breaks are scheduled. See
+ `AdsManager.adCuePoints`
+
## 0.2.6+7
* Updates Android `PlatformAdDisplayContainer` implementation to support preloading ads.
diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt
index c4348ca..f958887 100644
--- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt
+++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApi.kt
@@ -26,7 +26,7 @@
pigeon_instance.start()
}
- override fun getAdCuePoints(pigeon_instance: AdsManager): List<Double> {
+ override fun adCuePoints(pigeon_instance: AdsManager): List<Double> {
return pigeon_instance.adCuePoints.map { it.toDouble() }
}
diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt
index 3081008..fb74ed5 100644
--- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt
+++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt
@@ -21,7 +21,7 @@
*
* This must match the version in pubspec.yaml.
*/
- const val pluginVersion = "0.2.6+7"
+ const val pluginVersion = "0.2.7"
}
override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {
diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt
index 38edc43..43a7942 100644
--- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt
+++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt
@@ -2074,6 +2074,15 @@
abstract class PigeonApiAdsManager(
open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar
) {
+ /**
+ * List of content time offsets in seconds at which ad breaks are scheduled.
+ *
+ * The list will be empty if no ad breaks are scheduled.
+ */
+ abstract fun adCuePoints(
+ pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager
+ ): List<Double>
+
/** Discards current ad break and resumes content. */
abstract fun discardAdBreak(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager)
@@ -2083,15 +2092,6 @@
/** Starts playing the ads. */
abstract fun start(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager)
- /**
- * List of content time offsets in seconds at which ad breaks are scheduled.
- *
- * The list will be empty if no ad breaks are scheduled.
- */
- abstract fun getAdCuePoints(
- pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager
- ): List<Double>
-
/** Resumes the current ad. */
abstract fun resume(pigeon_instance: com.google.ads.interactivemedia.v3.api.AdsManager)
@@ -2175,28 +2175,6 @@
val channel =
BasicMessageChannel<Any?>(
binaryMessenger,
- "dev.flutter.pigeon.interactive_media_ads.AdsManager.getAdCuePoints",
- codec)
- if (api != null) {
- channel.setMessageHandler { message, reply ->
- val args = message as List<Any?>
- val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.AdsManager
- val wrapped: List<Any?> =
- try {
- listOf(api.getAdCuePoints(pigeon_instanceArg))
- } catch (exception: Throwable) {
- InteractiveMediaAdsLibraryPigeonUtils.wrapError(exception)
- }
- reply.reply(wrapped)
- }
- } else {
- channel.setMessageHandler(null)
- }
- }
- run {
- val channel =
- BasicMessageChannel<Any?>(
- binaryMessenger,
"dev.flutter.pigeon.interactive_media_ads.AdsManager.resume",
codec)
if (api != null) {
@@ -2255,11 +2233,12 @@
} else {
val pigeon_identifierArg =
pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg)
+ val adCuePointsArg = adCuePoints(pigeon_instanceArg)
val binaryMessenger = pigeonRegistrar.binaryMessenger
val codec = pigeonRegistrar.codec
val channelName = "dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
- channel.send(listOf(pigeon_identifierArg)) {
+ channel.send(listOf(pigeon_identifierArg, adCuePointsArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(
diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt
index cccb782..f82623b 100644
--- a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt
+++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsManagerProxyApiTest.kt
@@ -43,14 +43,14 @@
}
@Test
- fun getAdCuePoints() {
+ fun adCuePoints() {
val api = TestProxyApiRegistrar().getPigeonApiAdsManager()
val instance = mock<AdsManager>()
val value = listOf(1.0)
whenever(instance.adCuePoints).thenReturn(listOf(1.0f))
- assertEquals(value, api.getAdCuePoints(instance))
+ assertEquals(value, api.adCuePoints(instance))
}
@Test
diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift
index c0232b4..206ccc6 100644
--- a/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift
+++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdsManagerTests.swift
@@ -101,6 +101,17 @@
XCTAssertTrue(instance.destroyCalled)
}
+
+ func testAdCuePoints() {
+ let registrar = TestProxyApiRegistrar()
+ let api = registrar.apiDelegate.pigeonApiIMAAdsManager(registrar)
+
+ let instance = TestAdsManager.customInit()
+
+ let value = try? api.pigeonDelegate.adCuePoints(pigeonApi: api, pigeonInstance: instance)
+
+ XCTAssertEqual(value, [2.2, 3.3])
+ }
}
class TestAdsManager: IMAAdsManager {
@@ -146,4 +157,8 @@
override func destroy() {
destroyCalled = true
}
+
+ override var adCuePoints: [Any] {
+ return [2.2, 3.3]
+ }
}
diff --git a/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart b/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart
index abcd9e3..a248a27 100644
--- a/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart
+++ b/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart
@@ -70,6 +70,7 @@
_adsLoader = AdsLoader(
container: container,
onAdsLoaded: (OnAdsLoadedData data) {
+ debugPrint('OnAdsLoaded: (cuePoints: ${data.manager.adCuePoints})');
final AdsManager manager = data.manager;
_adsManager = data.manager;
diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift
index a19f004..2e50d4a 100644
--- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift
+++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsManagerProxyAPIDelegate.swift
@@ -47,4 +47,12 @@
func destroy(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws {
pigeonInstance.destroy()
}
+
+ func adCuePoints(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws
+ -> [Double]
+ {
+ return pigeonInstance.adCuePoints.map { cuePoint -> Double in
+ return (cuePoint as! NSNumber).doubleValue
+ }
+ }
}
diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift
index 51c134a..6ac61aa 100644
--- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift
+++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift
@@ -13,7 +13,7 @@
/// The current version of the `interactive_media_ads` plugin.
///
/// This must match the version in pubspec.yaml.
- static let pluginVersion = "0.2.6+7"
+ static let pluginVersion = "0.2.7"
func pigeonDefaultConstructor(
pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer,
diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift
index 7063553..ef2f9f2 100644
--- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift
+++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift
@@ -3157,6 +3157,12 @@
}
}
protocol PigeonApiDelegateIMAAdsManager {
+ /// List of content time offsets at which ad breaks are scheduled.
+ ///
+ /// List of double values in seconds. Empty list for single ads or if no ad
+ /// breaks are scheduled.
+ func adCuePoints(pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager) throws
+ -> [Double]
/// The `IMAAdsManagerDelegate` to notify with events during ad playback.
func setDelegate(
pigeonApi: PigeonApiIMAAdsManager, pigeonInstance: IMAAdsManager,
@@ -3365,13 +3371,15 @@
} else {
let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance(
pigeonInstance as AnyObject)
+ let adCuePointsArg = try! pigeonDelegate.adCuePoints(
+ pigeonApi: self, pigeonInstance: pigeonInstance)
let binaryMessenger = pigeonRegistrar.binaryMessenger
let codec = pigeonRegistrar.codec
let channelName: String =
"dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance"
let channel = FlutterBasicMessageChannel(
name: channelName, binaryMessenger: binaryMessenger, codec: codec)
- channel.sendMessage([pigeonIdentifierArg] as [Any?]) { response in
+ channel.sendMessage([pigeonIdentifierArg, adCuePointsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName: channelName)))
return
diff --git a/packages/interactive_media_ads/lib/src/ads_loader.dart b/packages/interactive_media_ads/lib/src/ads_loader.dart
index cff115a..6bbf7d1 100644
--- a/packages/interactive_media_ads/lib/src/ads_loader.dart
+++ b/packages/interactive_media_ads/lib/src/ads_loader.dart
@@ -151,6 +151,11 @@
/// Implementation of [PlatformAdsManager] for the current platform.
final PlatformAdsManager platform;
+ /// List of content time offsets at which ad breaks are scheduled.
+ ///
+ /// The list will be empty for single ads or if no ad breaks are scheduled.
+ List<Duration> get adCuePoints => platform.adCuePoints;
+
/// Initializes the ad experience using default rendering settings.
Future<void> init({AdsRenderingSettings? settings}) {
return platform.init(settings: settings?.platform);
diff --git a/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart b/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart
index 10a5e18..a8968d5 100644
--- a/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart
+++ b/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart
@@ -151,7 +151,7 @@
}
// Resets the state to before an ad is loaded and releases references to all
- // ads and allbacks.
+ // ads and callbacks.
void _release() {
_resetStateForNextAd();
_loadedAdMediaInfoQueue.clear();
diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart b/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart
index f299b0c..c0a61fb 100644
--- a/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart
+++ b/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart
@@ -18,7 +18,16 @@
@internal
AndroidAdsManager(ima.AdsManager manager, {InteractiveMediaAdsProxy? proxy})
: _manager = manager,
- _proxy = proxy ?? const InteractiveMediaAdsProxy();
+ _proxy = proxy ?? const InteractiveMediaAdsProxy(),
+ super(
+ adCuePoints: List<Duration>.unmodifiable(
+ manager.adCuePoints.map((double seconds) {
+ return Duration(
+ milliseconds: (seconds * Duration.millisecondsPerSecond).round(),
+ );
+ }),
+ ),
+ );
final ima.AdsManager _manager;
final InteractiveMediaAdsProxy _proxy;
diff --git a/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart
index 8bbed1f..dfb02c6 100644
--- a/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart
+++ b/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart
@@ -2250,16 +2250,22 @@
AdsManager.pigeon_detached({
super.pigeon_binaryMessenger,
super.pigeon_instanceManager,
+ required this.adCuePoints,
}) : super.pigeon_detached();
late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecAdsManager =
_PigeonInternalProxyApiBaseCodec(pigeon_instanceManager);
+ /// List of content time offsets in seconds at which ad breaks are scheduled.
+ ///
+ /// The list will be empty if no ad breaks are scheduled.
+ final List<double> adCuePoints;
+
static void pigeon_setUpMessageHandlers({
bool pigeon_clearHandlers = false,
BinaryMessenger? pigeon_binaryMessenger,
PigeonInstanceManager? pigeon_instanceManager,
- AdsManager Function()? pigeon_newInstance,
+ AdsManager Function(List<double> adCuePoints)? pigeon_newInstance,
}) {
final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec =
_PigeonInternalProxyApiBaseCodec(
@@ -2287,13 +2293,20 @@
arg_pigeon_instanceIdentifier != null,
'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance was null, expected non-null int.',
);
+ final List<double>? arg_adCuePoints =
+ (args[1] as List<Object?>?)?.cast<double>();
+ assert(
+ arg_adCuePoints != null,
+ 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance was null, expected non-null List<double>.',
+ );
try {
(pigeon_instanceManager ?? PigeonInstanceManager.instance)
.addHostCreatedInstance(
- pigeon_newInstance?.call() ??
+ pigeon_newInstance?.call(arg_adCuePoints!) ??
AdsManager.pigeon_detached(
pigeon_binaryMessenger: pigeon_binaryMessenger,
pigeon_instanceManager: pigeon_instanceManager,
+ adCuePoints: arg_adCuePoints!,
),
arg_pigeon_instanceIdentifier!,
);
@@ -2403,44 +2416,6 @@
}
}
- /// List of content time offsets in seconds at which ad breaks are scheduled.
- ///
- /// The list will be empty if no ad breaks are scheduled.
- Future<List<double>> getAdCuePoints() async {
- final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec =
- _pigeonVar_codecAdsManager;
- final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger;
- const String pigeonVar_channelName =
- 'dev.flutter.pigeon.interactive_media_ads.AdsManager.getAdCuePoints';
- final BasicMessageChannel<Object?> pigeonVar_channel =
- BasicMessageChannel<Object?>(
- pigeonVar_channelName,
- pigeonChannelCodec,
- binaryMessenger: pigeonVar_binaryMessenger,
- );
- final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
- <Object?>[this],
- );
- final List<Object?>? pigeonVar_replyList =
- await pigeonVar_sendFuture as List<Object?>?;
- if (pigeonVar_replyList == null) {
- throw _createConnectionError(pigeonVar_channelName);
- } else if (pigeonVar_replyList.length > 1) {
- throw PlatformException(
- code: pigeonVar_replyList[0]! as String,
- message: pigeonVar_replyList[1] as String?,
- details: pigeonVar_replyList[2],
- );
- } else if (pigeonVar_replyList[0] == null) {
- throw PlatformException(
- code: 'null-error',
- message: 'Host platform returned null value for non-null return value.',
- );
- } else {
- return (pigeonVar_replyList[0] as List<Object?>?)!.cast<double>();
- }
- }
-
/// Resumes the current ad.
Future<void> resume() async {
final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec =
@@ -2511,6 +2486,7 @@
return AdsManager.pigeon_detached(
pigeon_binaryMessenger: pigeon_binaryMessenger,
pigeon_instanceManager: pigeon_instanceManager,
+ adCuePoints: adCuePoints,
);
}
}
diff --git a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart
index 42f16e6..053defe 100644
--- a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart
+++ b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart
@@ -3855,16 +3855,23 @@
IMAAdsManager.pigeon_detached({
super.pigeon_binaryMessenger,
super.pigeon_instanceManager,
+ required this.adCuePoints,
}) : super.pigeon_detached();
late final _PigeonInternalProxyApiBaseCodec _pigeonVar_codecIMAAdsManager =
_PigeonInternalProxyApiBaseCodec(pigeon_instanceManager);
+ /// List of content time offsets at which ad breaks are scheduled.
+ ///
+ /// List of double values in seconds. Empty list for single ads or if no ad
+ /// breaks are scheduled.
+ final List<double> adCuePoints;
+
static void pigeon_setUpMessageHandlers({
bool pigeon_clearHandlers = false,
BinaryMessenger? pigeon_binaryMessenger,
PigeonInstanceManager? pigeon_instanceManager,
- IMAAdsManager Function()? pigeon_newInstance,
+ IMAAdsManager Function(List<double> adCuePoints)? pigeon_newInstance,
}) {
final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec =
_PigeonInternalProxyApiBaseCodec(
@@ -3892,13 +3899,20 @@
arg_pigeon_instanceIdentifier != null,
'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance was null, expected non-null int.',
);
+ final List<double>? arg_adCuePoints =
+ (args[1] as List<Object?>?)?.cast<double>();
+ assert(
+ arg_adCuePoints != null,
+ 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance was null, expected non-null List<double>.',
+ );
try {
(pigeon_instanceManager ?? PigeonInstanceManager.instance)
.addHostCreatedInstance(
- pigeon_newInstance?.call() ??
+ pigeon_newInstance?.call(arg_adCuePoints!) ??
IMAAdsManager.pigeon_detached(
pigeon_binaryMessenger: pigeon_binaryMessenger,
pigeon_instanceManager: pigeon_instanceManager,
+ adCuePoints: arg_adCuePoints!,
),
arg_pigeon_instanceIdentifier!,
);
@@ -4169,6 +4183,7 @@
return IMAAdsManager.pigeon_detached(
pigeon_binaryMessenger: pigeon_binaryMessenger,
pigeon_instanceManager: pigeon_instanceManager,
+ adCuePoints: adCuePoints,
);
}
}
diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart
index 058faa0..f8a8c01 100644
--- a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart
+++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart
@@ -15,7 +15,17 @@
class IOSAdsManager extends PlatformAdsManager {
/// Constructs an [IOSAdsManager].
@internal
- IOSAdsManager(IMAAdsManager manager) : _manager = manager;
+ IOSAdsManager(IMAAdsManager manager)
+ : _manager = manager,
+ super(
+ adCuePoints: List<Duration>.unmodifiable(
+ manager.adCuePoints.map((double seconds) {
+ return Duration(
+ milliseconds: (seconds * Duration.millisecondsPerSecond).round(),
+ );
+ }),
+ ),
+ );
final IMAAdsManager _manager;
diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart
index 33c5dd1..cc77cd5 100644
--- a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart
+++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_manager.dart
@@ -15,7 +15,12 @@
abstract class PlatformAdsManager {
/// Creates a [PlatformAdsManager].
@protected
- PlatformAdsManager();
+ PlatformAdsManager({required this.adCuePoints});
+
+ /// List of content time offsets at which ad breaks are scheduled.
+ ///
+ /// The list will be empty if no ad breaks are scheduled.
+ final List<Duration> adCuePoints;
/// Initializes the ad experience using default rendering settings.
Future<void> init({PlatformAdsRenderingSettings? settings});
diff --git a/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart
index 43ceedc..5bd6231 100644
--- a/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart
+++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart
@@ -448,6 +448,11 @@
),
)
abstract class AdsManager extends BaseManager {
+ /// List of content time offsets in seconds at which ad breaks are scheduled.
+ ///
+ /// The list will be empty if no ad breaks are scheduled.
+ late List<double> adCuePoints;
+
/// Discards current ad break and resumes content.
void discardAdBreak();
@@ -457,11 +462,6 @@
/// Starts playing the ads.
void start();
- /// List of content time offsets in seconds at which ad breaks are scheduled.
- ///
- /// The list will be empty if no ad breaks are scheduled.
- List<double> getAdCuePoints();
-
/// Resumes the current ad.
void resume();
diff --git a/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart b/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart
index e325dbd..ce39fd5 100644
--- a/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart
+++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart
@@ -630,6 +630,12 @@
/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsManager.html.
@ProxyApi()
abstract class IMAAdsManager extends NSObject {
+ /// List of content time offsets at which ad breaks are scheduled.
+ ///
+ /// List of double values in seconds. Empty list for single ads or if no ad
+ /// breaks are scheduled.
+ late List<double> adCuePoints;
+
/// The `IMAAdsManagerDelegate` to notify with events during ad playback.
void setDelegate(IMAAdsManagerDelegate? delegate);
diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml
index 17bb2c2..385101a 100644
--- a/packages/interactive_media_ads/pubspec.yaml
+++ b/packages/interactive_media_ads/pubspec.yaml
@@ -2,7 +2,7 @@
description: A Flutter plugin for using the Interactive Media Ads SDKs on Android and iOS.
repository: https://github.com/flutter/packages/tree/main/packages/interactive_media_ads
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+interactive_media_ads%22
-version: 0.2.6+7 # This must match the version in
+version: 0.2.7 # This must match the version in
# `android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt` and
# `ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift`
diff --git a/packages/interactive_media_ads/test/ads_manager_test.dart b/packages/interactive_media_ads/test/ads_manager_test.dart
index b812ee3..836b5cb 100644
--- a/packages/interactive_media_ads/test/ads_manager_test.dart
+++ b/packages/interactive_media_ads/test/ads_manager_test.dart
@@ -102,6 +102,15 @@
final AdsManager manager = createAdsManager(platformManager);
await manager.destroy();
});
+
+ test('adCuePoints', () async {
+ final TestAdsManager platformManager = TestAdsManager(
+ adCuePoints: const <Duration>[Duration(seconds: 5)],
+ );
+
+ final AdsManager manager = createAdsManager(platformManager);
+ expect(platformManager.adCuePoints, manager.adCuePoints);
+ });
}
AdsManager createAdsManager(PlatformAdsManager platformManager) {
diff --git a/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart b/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart
index eb56f04..da94b7f 100644
--- a/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart
+++ b/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart
@@ -434,6 +434,15 @@
/// See the documentation for Mockito's code generation for more information.
class MockAdsManager extends _i1.Mock implements _i2.AdsManager {
@override
+ List<double> get adCuePoints =>
+ (super.noSuchMethod(
+ Invocation.getter(#adCuePoints),
+ returnValue: <double>[],
+ returnValueForMissingStub: <double>[],
+ )
+ as List<double>);
+
+ @override
_i2.PigeonInstanceManager get pigeon_instanceManager =>
(super.noSuchMethod(
Invocation.getter(#pigeon_instanceManager),
@@ -476,17 +485,6 @@
as _i5.Future<void>);
@override
- _i5.Future<List<double>> getAdCuePoints() =>
- (super.noSuchMethod(
- Invocation.method(#getAdCuePoints, []),
- returnValue: _i5.Future<List<double>>.value(<double>[]),
- returnValueForMissingStub: _i5.Future<List<double>>.value(
- <double>[],
- ),
- )
- as _i5.Future<List<double>>);
-
- @override
_i5.Future<void> resume() =>
(super.noSuchMethod(
Invocation.method(#resume, []),
diff --git a/packages/interactive_media_ads/test/android/ads_manager_test.dart b/packages/interactive_media_ads/test/android/ads_manager_test.dart
index c134961..56aba17 100644
--- a/packages/interactive_media_ads/test/android/ads_manager_test.dart
+++ b/packages/interactive_media_ads/test/android/ads_manager_test.dart
@@ -197,5 +197,15 @@
when(mockErrorEvent.error).thenReturn(mockError);
onAdErrorCallback(MockAdErrorListener(), mockErrorEvent);
});
+
+ test('adCuePoints', () {
+ final MockAdsManager mockAdsManager = MockAdsManager();
+
+ final List<double> cuePoints = <double>[1.0];
+ when(mockAdsManager.adCuePoints).thenReturn(cuePoints);
+ final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager);
+
+ expect(adsManager.adCuePoints, <Duration>[const Duration(seconds: 1)]);
+ });
});
}
diff --git a/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart b/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart
index 92af7ae..8fd6d26 100644
--- a/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart
+++ b/packages/interactive_media_ads/test/android/ads_manager_test.mocks.dart
@@ -366,6 +366,15 @@
/// See the documentation for Mockito's code generation for more information.
class MockAdsManager extends _i1.Mock implements _i2.AdsManager {
@override
+ List<double> get adCuePoints =>
+ (super.noSuchMethod(
+ Invocation.getter(#adCuePoints),
+ returnValue: <double>[],
+ returnValueForMissingStub: <double>[],
+ )
+ as List<double>);
+
+ @override
_i2.PigeonInstanceManager get pigeon_instanceManager =>
(super.noSuchMethod(
Invocation.getter(#pigeon_instanceManager),
@@ -408,17 +417,6 @@
as _i4.Future<void>);
@override
- _i4.Future<List<double>> getAdCuePoints() =>
- (super.noSuchMethod(
- Invocation.method(#getAdCuePoints, []),
- returnValue: _i4.Future<List<double>>.value(<double>[]),
- returnValueForMissingStub: _i4.Future<List<double>>.value(
- <double>[],
- ),
- )
- as _i4.Future<List<double>>);
-
- @override
_i4.Future<void> resume() =>
(super.noSuchMethod(
Invocation.method(#resume, []),
diff --git a/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart b/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart
index a7d336d..0788ef0 100644
--- a/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart
+++ b/packages/interactive_media_ads/test/ios/ads_loader_test.mocks.dart
@@ -322,6 +322,15 @@
/// See the documentation for Mockito's code generation for more information.
class MockIMAAdsManager extends _i1.Mock implements _i2.IMAAdsManager {
@override
+ List<double> get adCuePoints =>
+ (super.noSuchMethod(
+ Invocation.getter(#adCuePoints),
+ returnValue: <double>[],
+ returnValueForMissingStub: <double>[],
+ )
+ as List<double>);
+
+ @override
_i2.PigeonInstanceManager get pigeon_instanceManager =>
(super.noSuchMethod(
Invocation.getter(#pigeon_instanceManager),
diff --git a/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart b/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart
index 0c26c65..ddf9d08 100644
--- a/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart
+++ b/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart
@@ -72,6 +72,7 @@
delegate,
ima.IMAAdsManager.pigeon_detached(
pigeon_instanceManager: instanceManager,
+ adCuePoints: const <double>[],
),
ima.IMAAdEvent.pigeon_detached(
type: ima.AdEventType.allAdsCompleted,
@@ -138,6 +139,7 @@
delegate,
ima.IMAAdsManager.pigeon_detached(
pigeon_instanceManager: instanceManager,
+ adCuePoints: const <double>[],
),
);
});
@@ -198,6 +200,7 @@
delegate,
ima.IMAAdsManager.pigeon_detached(
pigeon_instanceManager: instanceManager,
+ adCuePoints: const <double>[],
),
);
});
@@ -264,6 +267,7 @@
delegate,
ima.IMAAdsManager.pigeon_detached(
pigeon_instanceManager: instanceManager,
+ adCuePoints: const <double>[],
),
ima.IMAAdError.pigeon_detached(
type: ima.AdErrorType.loadingFailed,
diff --git a/packages/interactive_media_ads/test/ios/ads_manager_test.dart b/packages/interactive_media_ads/test/ios/ads_manager_test.dart
index cb0567a..2f8fdab 100644
--- a/packages/interactive_media_ads/test/ios/ads_manager_test.dart
+++ b/packages/interactive_media_ads/test/ios/ads_manager_test.dart
@@ -150,5 +150,15 @@
verify(mockAdsManager.setDelegate(delegate));
});
+
+ test('adCuePoints', () {
+ final MockIMAAdsManager mockAdsManager = MockIMAAdsManager();
+
+ final List<double> cuePoints = <double>[1.0];
+ when(mockAdsManager.adCuePoints).thenReturn(cuePoints);
+ final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager);
+
+ expect(adsManager.adCuePoints, <Duration>[const Duration(seconds: 1)]);
+ });
});
}
diff --git a/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart b/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart
index 6d1b4b9..6e10afb 100644
--- a/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart
+++ b/packages/interactive_media_ads/test/ios/ads_manager_test.mocks.dart
@@ -45,6 +45,15 @@
/// See the documentation for Mockito's code generation for more information.
class MockIMAAdsManager extends _i1.Mock implements _i2.IMAAdsManager {
@override
+ List<double> get adCuePoints =>
+ (super.noSuchMethod(
+ Invocation.getter(#adCuePoints),
+ returnValue: <double>[],
+ returnValueForMissingStub: <double>[],
+ )
+ as List<double>);
+
+ @override
_i2.PigeonInstanceManager get pigeon_instanceManager =>
(super.noSuchMethod(
Invocation.getter(#pigeon_instanceManager),
diff --git a/packages/interactive_media_ads/test/test_stubs.dart b/packages/interactive_media_ads/test/test_stubs.dart
index 45b91aa..60e319f 100644
--- a/packages/interactive_media_ads/test/test_stubs.dart
+++ b/packages/interactive_media_ads/test/test_stubs.dart
@@ -147,6 +147,7 @@
this.onPause,
this.onResume,
this.onSkip,
+ super.adCuePoints = const <Duration>[],
});
Future<void> Function({PlatformAdsRenderingSettings? settings})? onInit;