diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md index cf488dd18cc..395994e1605 100644 --- a/packages/interactive_media_ads/CHANGELOG.md +++ b/packages/interactive_media_ads/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.3 + +* Adds parameters to control the rendering of ads. See `AdsManager.init`. + ## 0.2.2+15 * Adds remaining methods for internal wrapper of the Android native `BaseManager`. diff --git a/packages/interactive_media_ads/README.md b/packages/interactive_media_ads/README.md index d3e1817f09b..e558e0c8ba4 100644 --- a/packages/interactive_media_ads/README.md +++ b/packages/interactive_media_ads/README.md @@ -154,7 +154,7 @@ late final AdDisplayContainer _adDisplayContainer = AdDisplayContainer( }, )); - manager.init(); + manager.init(settings: AdsRenderingSettings(enablePreloading: true)); }, onAdsLoadError: (AdsLoadErrorData data) { debugPrint('OnAdsLoadError: ${data.error.message}'); 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 5d14b8a72db..eaed672c8f6 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 @@ class AdsRequestProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : * * This must match the version in pubspec.yaml. */ - const val pluginVersion = "0.2.2+15" + const val pluginVersion = "0.2.3" } 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/ImaSdkFactoryProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApi.kt index eaed1baabe2..00ee7a23e71 100644 --- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApi.kt +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApi.kt @@ -7,6 +7,7 @@ package dev.flutter.packages.interactive_media_ads import android.view.ViewGroup 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.ImaSdkFactory import com.google.ads.interactivemedia.v3.api.ImaSdkSettings @@ -46,4 +47,8 @@ class ImaSdkFactoryProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : override fun createAdsRequest(pigeon_instance: ImaSdkFactory): AdsRequest { return pigeon_instance.createAdsRequest() } + + override fun createAdsRenderingSettings(pigeon_instance: ImaSdkFactory): AdsRenderingSettings { + return pigeon_instance.createAdsRenderingSettings() + } } 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 b42ee9d2fd5..fc3198cd86c 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 @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v22.5.0), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass", "SyntheticAccessor") @@ -2236,6 +2236,14 @@ abstract class PigeonApiImaSdkFactory( pigeon_instance: com.google.ads.interactivemedia.v3.api.ImaSdkFactory ): com.google.ads.interactivemedia.v3.api.AdsRequest + /** + * Creates an `AdsRenderingSettings` object to give the AdsManager parameters that control the + * rendering of ads. + */ + abstract fun createAdsRenderingSettings( + pigeon_instance: com.google.ads.interactivemedia.v3.api.ImaSdkFactory + ): com.google.ads.interactivemedia.v3.api.AdsRenderingSettings + companion object { @Suppress("LocalVariableName") fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiImaSdkFactory?) { @@ -2355,6 +2363,28 @@ abstract class PigeonApiImaSdkFactory( channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdsRenderingSettings", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as com.google.ads.interactivemedia.v3.api.ImaSdkFactory + val wrapped: List = + try { + listOf(api.createAdsRenderingSettings(pigeon_instanceArg)) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } } } diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt index 600e5e41a09..092340d5b47 100644 --- a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/ImaSdkFactoryProxyApiTest.kt @@ -6,6 +6,7 @@ package dev.flutter.packages.interactive_media_ads 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.ImaSdkFactory import com.google.ads.interactivemedia.v3.api.ImaSdkSettings @@ -51,4 +52,15 @@ class ImaSdkFactoryProxyApiTest { assertEquals(mockRequest, api.createAdsRequest(instance)) } + + @Test + fun createAdsRenderingSettings() { + val api = TestProxyApiRegistrar().getPigeonApiImaSdkFactory() + + val instance = mock() + val mockSettings = mock() + whenever(instance.createAdsRenderingSettings()).thenReturn(mockSettings) + + assertEquals(mockSettings, api.createAdsRenderingSettings(instance)) + } } diff --git a/packages/interactive_media_ads/example/lib/main.dart b/packages/interactive_media_ads/example/lib/main.dart index 01cdb603dc0..49c080f7e54 100644 --- a/packages/interactive_media_ads/example/lib/main.dart +++ b/packages/interactive_media_ads/example/lib/main.dart @@ -100,7 +100,7 @@ class _AdExampleWidgetState extends State }, )); - manager.init(); + manager.init(settings: AdsRenderingSettings(enablePreloading: true)); }, onAdsLoadError: (AdsLoadErrorData data) { debugPrint('OnAdsLoadError: ${data.error.message}'); 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 de4a711123d..c2e45163cda 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 @@ class AdsRequestProxyAPIDelegate: PigeonApiDelegateIMAAdsRequest { /// The current version of the `interactive_media_ads` plugin. /// /// This must match the version in pubspec.yaml. - static let pluginVersion = "0.2.2+15" + static let pluginVersion = "0.2.3" func pigeonDefaultConstructor( pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer, diff --git a/packages/interactive_media_ads/lib/interactive_media_ads.dart b/packages/interactive_media_ads/lib/interactive_media_ads.dart index 06c18024841..f8355bba41c 100644 --- a/packages/interactive_media_ads/lib/interactive_media_ads.dart +++ b/packages/interactive_media_ads/lib/interactive_media_ads.dart @@ -5,6 +5,7 @@ export 'src/ad_display_container.dart'; export 'src/ads_loader.dart'; export 'src/ads_manager_delegate.dart'; +export 'src/ads_rendering_settings.dart'; export 'src/ads_request.dart'; export 'src/android/android_interactive_media_ads.dart' show AndroidInteractiveMediaAds; @@ -18,4 +19,5 @@ export 'src/platform_interface/platform_interface.dart' AdErrorType, AdEvent, AdEventType, + AdUIElement, AdsLoadErrorData; diff --git a/packages/interactive_media_ads/lib/src/ads_loader.dart b/packages/interactive_media_ads/lib/src/ads_loader.dart index 9863d4c0129..4d05b6db34d 100644 --- a/packages/interactive_media_ads/lib/src/ads_loader.dart +++ b/packages/interactive_media_ads/lib/src/ads_loader.dart @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; import 'ad_display_container.dart'; import 'ads_manager_delegate.dart'; +import 'ads_rendering_settings.dart'; import 'ads_request.dart'; import 'platform_interface/platform_interface.dart'; @@ -145,8 +146,8 @@ class AdsManager { final PlatformAdsManager platform; /// Initializes the ad experience using default rendering settings. - Future init() { - return platform.init(AdsManagerInitParams()); + Future init({AdsRenderingSettings? settings}) { + return platform.init(settings: settings?.platform); } /// Starts playing the ads. diff --git a/packages/interactive_media_ads/lib/src/ads_rendering_settings.dart b/packages/interactive_media_ads/lib/src/ads_rendering_settings.dart new file mode 100644 index 00000000000..ecae23f404a --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ads_rendering_settings.dart @@ -0,0 +1,85 @@ +// 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? mimeTypes, + Duration? playAdsAfterTime, + Set? 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. + /// + /// If null, the platform will decide the default value. + List? 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; + + /// The ad UI elements to be rendered by the IMA SDK. + /// + /// Some modifications to the uiElements list may have no effect for specific + /// ads. + /// + /// If null, the platform will decide the default value. + Set? get uiElements => platform.params.uiElements; +} 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 fbba105e4e2..ad1953bfc78 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 @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:meta/meta.dart'; import '../platform_interface/platform_interface.dart'; +import 'android_ads_rendering_settings.dart'; import 'enum_converter_utils.dart'; import 'interactive_media_ads.g.dart' as ima; import 'interactive_media_ads_proxy.dart'; @@ -32,8 +33,15 @@ class AndroidAdsManager extends PlatformAdsManager { } @override - Future init(AdsManagerInitParams params) { - return _manager.init(null); + Future init({PlatformAdsRenderingSettings? settings}) async { + ima.AdsRenderingSettings? nativeSettings; + if (settings != null) { + nativeSettings = settings is AndroidAdsRenderingSettings + ? await settings.nativeSettings + : await AndroidAdsRenderingSettings(settings.params).nativeSettings; + } + + await _manager.init(nativeSettings); } @override diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart b/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart new file mode 100644 index 00000000000..581ae3ff86c --- /dev/null +++ b/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart @@ -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. + final bool enableCustomTabs; +} + +/// Android implementation of [PlatformAdsRenderingSettings]. +base class AndroidAdsRenderingSettings extends PlatformAdsRenderingSettings { + /// Constructs an [AndroidAdsRenderingSettings]. + AndroidAdsRenderingSettings(super.params) : super.implementation() { + final Completer nativeSettingsCompleter = + Completer(); + nativeSettings = nativeSettingsCompleter.future; + + _androidParams._proxy + .instanceImaSdkFactory() + .createAdsRenderingSettings() + .then((ima.AdsRenderingSettings nativeSettings) async { + await Future.wait(>[ + 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 nativeSettings; + + late final AndroidAdsRenderingSettingsCreationParams _androidParams = + params is AndroidAdsRenderingSettingsCreationParams + ? params as AndroidAdsRenderingSettingsCreationParams + : AndroidAdsRenderingSettingsCreationParams + .fromPlatformAdsRenderingSettingsCreationParams( + params, + ); +} diff --git a/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart b/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart index 0f05362a691..8e77520a07f 100644 --- a/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart +++ b/packages/interactive_media_ads/lib/src/android/android_interactive_media_ads.dart @@ -6,10 +6,12 @@ import '../platform_interface/interactive_media_ads_platform.dart'; import '../platform_interface/platform_ad_display_container.dart'; import '../platform_interface/platform_ads_loader.dart'; import '../platform_interface/platform_ads_manager_delegate.dart'; +import '../platform_interface/platform_ads_rendering_settings.dart'; import '../platform_interface/platform_content_progress_provider.dart'; import 'android_ad_display_container.dart'; import 'android_ads_loader.dart'; import 'android_ads_manager_delegate.dart'; +import 'android_ads_rendering_settings.dart'; import 'android_content_progress_provider.dart'; /// Android implementation of [InteractiveMediaAdsPlatform]. @@ -46,4 +48,11 @@ final class AndroidInteractiveMediaAds extends InteractiveMediaAdsPlatform { ) { return AndroidContentProgressProvider(params); } + + @override + AndroidAdsRenderingSettings createPlatformAdsRenderingSettings( + PlatformAdsRenderingSettingsCreationParams params, + ) { + return AndroidAdsRenderingSettings(params); + } } 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 330cf444e2f..b519ac04475 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 @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v22.5.0), do not edit directly. +// Autogenerated from Pigeon (v22.6.0), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -2482,6 +2482,40 @@ class ImaSdkFactory extends PigeonInternalProxyApiBaseClass { } } + /// Creates an `AdsRenderingSettings` object to give the AdsManager parameters + /// that control the rendering of ads. + Future createAdsRenderingSettings() async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecImaSdkFactory; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.interactive_media_ads.ImaSdkFactory.createAdsRenderingSettings'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = + await pigeonVar_channel.send([this]) as List?; + 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 AdsRenderingSettings?)!; + } + } + @override ImaSdkFactory pigeon_copy() { return ImaSdkFactory.pigeon_detached( 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 0c51bf926f1..9d8c1c5ac4c 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 @@ -9,6 +9,7 @@ import 'package:meta/meta.dart'; import '../platform_interface/platform_interface.dart'; import 'interactive_media_ads.g.dart'; import 'ios_ads_manager_delegate.dart'; +import 'ios_ads_rendering_settings.dart'; /// Implementation of [PlatformAdsManager] for iOS. class IOSAdsManager extends PlatformAdsManager { @@ -30,8 +31,15 @@ class IOSAdsManager extends PlatformAdsManager { } @override - Future init(AdsManagerInitParams params) { - return _manager.initialize(null); + Future init({PlatformAdsRenderingSettings? settings}) { + IMAAdsRenderingSettings? nativeSettings; + if (settings != null) { + nativeSettings = settings is IOSAdsRenderingSettings + ? settings.nativeSettings + : IOSAdsRenderingSettings(settings.params).nativeSettings; + } + + return _manager.initialize(nativeSettings); } @override diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart new file mode 100644 index 00000000000..6ce5048ec82 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart @@ -0,0 +1,93 @@ +// 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 'package:meta/meta.dart'; + +import '../platform_interface/platform_interface.dart'; +import 'interactive_media_ads.g.dart'; +import 'interactive_media_ads_proxy.dart'; + +/// Implementation of [PlatformAdsRenderingSettingsCreationParams] for iOS. +final class IOSAdsRenderingSettingsCreationParams + extends PlatformAdsRenderingSettingsCreationParams { + /// Constructs an [IOSAdsRenderingSettingsCreationParams]. + const IOSAdsRenderingSettingsCreationParams({ + super.bitrate, + super.enablePreloading, + super.loadVideoTimeout, + super.mimeTypes, + super.playAdsAfterTime, + super.uiElements, + @visibleForTesting InteractiveMediaAdsProxy? proxy, + }) : _proxy = proxy ?? const InteractiveMediaAdsProxy(), + super(); + + /// Creates a [IOSAdsRenderingSettingsCreationParams] from an instance of + /// [PlatformAdsRenderingSettingsCreationParams]. + factory IOSAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( + PlatformAdsRenderingSettingsCreationParams params, + ) { + return IOSAdsRenderingSettingsCreationParams( + bitrate: params.bitrate, + enablePreloading: params.enablePreloading, + loadVideoTimeout: params.loadVideoTimeout, + mimeTypes: params.mimeTypes, + playAdsAfterTime: params.playAdsAfterTime, + uiElements: params.uiElements, + ); + } + + final InteractiveMediaAdsProxy _proxy; +} + +/// Implementation of [PlatformAdsRenderingSettings] for iOS. +base class IOSAdsRenderingSettings extends PlatformAdsRenderingSettings { + /// Constructs an [IOSAdsRenderingSettings]. + IOSAdsRenderingSettings(super.params) : super.implementation() { + if (_iosParams.bitrate != null) { + nativeSettings.setBitrate(params.bitrate!); + } + if (_iosParams.enablePreloading != null) { + nativeSettings.setEnablePreloading(_iosParams.enablePreloading!); + } + nativeSettings.setLoadVideoTimeout( + _iosParams.loadVideoTimeout.inMicroseconds / + Duration.microsecondsPerSecond, + ); + if (_iosParams.mimeTypes != null) { + nativeSettings.setMimeTypes(_iosParams.mimeTypes); + } + if (_iosParams.playAdsAfterTime != null) { + nativeSettings.setPlayAdsAfterTime( + _iosParams.playAdsAfterTime!.inMicroseconds / + Duration.microsecondsPerSecond, + ); + } + if (_iosParams.uiElements != null) { + nativeSettings.setUIElements( + _iosParams.uiElements!.map( + (AdUIElement element) { + return switch (element) { + AdUIElement.adAttribution => UIElementType.adAttribution, + AdUIElement.countdown => UIElementType.countdown, + }; + }, + ).toList(), + ); + } + } + + /// The native iOS IMAAdsRenderingSettings. + @internal + late final IMAAdsRenderingSettings nativeSettings = + _iosParams._proxy.newIMAAdsRenderingSettings(); + + late final IOSAdsRenderingSettingsCreationParams _iosParams = + params is IOSAdsRenderingSettingsCreationParams + ? params as IOSAdsRenderingSettingsCreationParams + : IOSAdsRenderingSettingsCreationParams + .fromPlatformAdsRenderingSettingsCreationParams( + params, + ); +} diff --git a/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart b/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart index ee55ecce0c9..b79928c57a0 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_interactive_media_ads.dart @@ -6,10 +6,12 @@ import '../platform_interface/interactive_media_ads_platform.dart'; import '../platform_interface/platform_ad_display_container.dart'; import '../platform_interface/platform_ads_loader.dart'; import '../platform_interface/platform_ads_manager_delegate.dart'; +import '../platform_interface/platform_ads_rendering_settings.dart'; import '../platform_interface/platform_content_progress_provider.dart'; import 'ios_ad_display_container.dart'; import 'ios_ads_loader.dart'; import 'ios_ads_manager_delegate.dart'; +import 'ios_ads_rendering_settings.dart'; import 'ios_content_progress_provider.dart'; /// Implementation of [InteractiveMediaAdsPlatform] for iOS. @@ -44,4 +46,11 @@ final class IOSInteractiveMediaAds extends InteractiveMediaAdsPlatform { ) { return IOSContentProgressProvider(params); } + + @override + IOSAdsRenderingSettings createPlatformAdsRenderingSettings( + PlatformAdsRenderingSettingsCreationParams params, + ) { + return IOSAdsRenderingSettings(params); + } } diff --git a/packages/interactive_media_ads/lib/src/platform_interface/ad_ui_element.dart b/packages/interactive_media_ads/lib/src/platform_interface/ad_ui_element.dart new file mode 100644 index 00000000000..3d7357f1ac0 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/platform_interface/ad_ui_element.dart @@ -0,0 +1,12 @@ +// 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. + +/// Describes an element of the ad UI, to be requested or rendered by the SDK. +enum AdUIElement { + /// The ad attribution UI element, for example, "Ad". + adAttribution, + + /// Ad attribution is required for a countdown timer to be displayed. + countdown, +} diff --git a/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart b/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart index fdb8593bdcb..15b898e462c 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/interactive_media_ads_platform.dart @@ -5,6 +5,7 @@ import 'platform_ad_display_container.dart'; import 'platform_ads_loader.dart'; import 'platform_ads_manager_delegate.dart'; +import 'platform_ads_rendering_settings.dart'; import 'platform_content_progress_provider.dart'; /// Interface for a platform implementation of the Interactive Media Ads SDKs. @@ -35,4 +36,9 @@ abstract base class InteractiveMediaAdsPlatform { PlatformContentProgressProvider createPlatformContentProgressProvider( PlatformContentProgressProviderCreationParams params, ); + + /// Creates a new [PlatformContentProgressProvider]. + PlatformAdsRenderingSettings createPlatformAdsRenderingSettings( + PlatformAdsRenderingSettingsCreationParams params, + ); } 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 0f3d7a7ea46..ea73ff7268e 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 @@ -5,9 +5,7 @@ import 'package:flutter/foundation.dart'; import 'platform_ads_manager_delegate.dart'; - -/// Additional parameter passed to an [PlatformAdsManager] on initialization. -base class AdsManagerInitParams {} +import 'platform_ads_rendering_settings.dart'; /// Additional parameter passed to an [PlatformAdsManager] when starting to play /// ads. @@ -20,7 +18,7 @@ abstract class PlatformAdsManager { PlatformAdsManager(); /// Initializes the ad experience using default rendering settings. - Future init(AdsManagerInitParams params); + Future init({PlatformAdsRenderingSettings? settings}); /// Starts playing the ads. Future start(AdsManagerStartParams params); diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_rendering_settings.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_rendering_settings.dart new file mode 100644 index 00000000000..882baa4e958 --- /dev/null +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_ads_rendering_settings.dart @@ -0,0 +1,139 @@ +// 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 'package:flutter/foundation.dart'; + +import 'ad_ui_element.dart'; +import 'interactive_media_ads_platform.dart'; + +/// Object specifying creation parameters for creating a +/// [PlatformAdsRenderingSettings]. +/// +/// Platform specific implementations can add additional fields by extending +/// this class. +/// +/// This example demonstrates how to extend the +/// [PlatformAdsRenderingSettingsCreationParams] to provide additional platform +/// specific parameters. +/// +/// When extending [PlatformAdsRenderingSettingsCreationParams], additional +/// parameters should always accept `null` or have a default value to prevent +/// breaking changes. +/// +/// ```dart +/// final class AndroidPlatformAdsRenderingSettingsCreationParams +/// extends PlatformAdsRenderingSettingsCreationParams { +/// const AndroidPlatformAdsRenderingSettingsCreationParams({ +/// super.bitrate, +/// this.enableCustomTabs, +/// }) : super(); +/// +/// factory AndroidPlatformAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( +/// PlatformAdsRenderingSettingsCreationParams params, { +/// bool? enableCustomTabs, +/// }) { +/// return AndroidPlatformAdsRenderingSettingsCreationParams( +/// bitrate: params.bitrate, +/// enableCustomTabs: enableCustomTabs, +/// ); +/// } +/// +/// final bool? enableCustomTabs; +/// } +/// ``` +@immutable +base class PlatformAdsRenderingSettingsCreationParams { + /// Used by the platform implementation to create a new + /// [PlatformAdsRenderingSettings]. + const PlatformAdsRenderingSettingsCreationParams({ + this.bitrate, + this.enablePreloading, + this.loadVideoTimeout = const Duration(seconds: 8), + this.mimeTypes, + this.playAdsAfterTime, + this.uiElements, + }); + + /// 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). + final int? bitrate; + + /// If set, the SDK will instruct the player to load the creative in response + /// initializing the ads manager. + /// + /// This allows the player to preload the ad at any point before starting the + /// ads manager. + /// + /// If null, the platform will decide the default value. + final bool? 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. + final Duration 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. + /// + /// If null, the platform will decide the default value. + final List? 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. + final Duration? playAdsAfterTime; + + /// Sets the ad UI elements to be rendered by the IMA SDK. + /// + /// Some modifications to the uiElements set may have no effect for specific + /// ads. + /// + /// If null, the platform will decide the default value. + final Set? uiElements; +} + +/// Defines parameters that control the rendering of ads. +abstract base class PlatformAdsRenderingSettings { + /// Creates a new [PlatformAdsRenderingSettings] + factory PlatformAdsRenderingSettings( + PlatformAdsRenderingSettingsCreationParams params, + ) { + assert( + InteractiveMediaAdsPlatform.instance != null, + 'A platform implementation for `interactive_media_ads` has not been set. ' + 'Please ensure that an implementation of `InteractiveMediaAdsPlatform` ' + 'has been set to `InteractiveMediaAdsPlatform.instance` before use. For ' + 'unit testing, `InteractiveMediaAdsPlatform.instance` can be set with ' + 'your own test implementation.', + ); + final PlatformAdsRenderingSettings implementation = + InteractiveMediaAdsPlatform.instance! + .createPlatformAdsRenderingSettings(params); + return implementation; + } + + /// Used by the platform implementation to create a new + /// [PlatformAdsRenderingSettings]. + /// + /// Should only be used by platform implementations because they can't extend + /// a class that only contains a factory constructor. + @protected + PlatformAdsRenderingSettings.implementation(this.params); + + /// The parameters used to initialize the [PlatformAdsRenderingSettings]. + final PlatformAdsRenderingSettingsCreationParams params; +} diff --git a/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart b/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart index fad06fe592f..f2b60b7618f 100644 --- a/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart +++ b/packages/interactive_media_ads/lib/src/platform_interface/platform_interface.dart @@ -4,10 +4,12 @@ export 'ad_error.dart'; export 'ad_event.dart'; +export 'ad_ui_element.dart'; export 'interactive_media_ads_platform.dart'; export 'platform_ad_display_container.dart'; export 'platform_ads_loader.dart'; export 'platform_ads_manager.dart'; export 'platform_ads_manager_delegate.dart'; +export 'platform_ads_rendering_settings.dart'; export 'platform_ads_request.dart'; export 'platform_content_progress_provider.dart'; 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 24318a2c6fc..61d5a0f05e5 100644 --- a/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart +++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart @@ -469,6 +469,10 @@ abstract class ImaSdkFactory { /// Creates an AdsRequest object to contain the data used to request ads. AdsRequest createAdsRequest(); + + /// Creates an `AdsRenderingSettings` object to give the AdsManager parameters + /// that control the rendering of ads. + AdsRenderingSettings createAdsRenderingSettings(); } /// Defines general SDK settings that are used when creating an `AdsLoader`. diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml index 88e8c6fc848..7c448913866 100644 --- a/packages/interactive_media_ads/pubspec.yaml +++ b/packages/interactive_media_ads/pubspec.yaml @@ -2,7 +2,7 @@ name: interactive_media_ads 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.2+15 # This must match the version in +version: 0.2.3 # 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` @@ -31,7 +31,7 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.4 - pigeon: ^22.5.0 + pigeon: ^22.6.0 topics: - ads diff --git a/packages/interactive_media_ads/test/ads_manager_test.dart b/packages/interactive_media_ads/test/ads_manager_test.dart index f27f37aa82c..38591913171 100644 --- a/packages/interactive_media_ads/test/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/ads_manager_test.dart @@ -2,6 +2,8 @@ // 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:flutter/cupertino.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:interactive_media_ads/interactive_media_ads.dart'; @@ -11,12 +13,25 @@ import 'test_stubs.dart'; void main() { test('init', () async { + final AdsRenderingSettings adsRenderingSettings = + AdsRenderingSettings.fromPlatform( + TestAdsRenderingSettings( + const PlatformAdsRenderingSettingsCreationParams(), + ), + ); + + final Completer settingsCompleter = + Completer(); + final TestAdsManager platformManager = TestAdsManager( - onInit: expectAsync1((_) async {}), + onInit: ({PlatformAdsRenderingSettings? settings}) async { + settingsCompleter.complete(settings); + }, ); final AdsManager manager = createAdsManager(platformManager); - await manager.init(); + await manager.init(settings: adsRenderingSettings); + expect(await settingsCompleter.future, adsRenderingSettings.platform); }); test('start', () async { 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 fc6fe08a400..d1d3d9f26a8 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 @@ -153,8 +153,9 @@ class _FakeImaSdkSettings_11 extends _i1.SmartFake ); } -class _FakeImaSdkFactory_12 extends _i1.SmartFake implements _i2.ImaSdkFactory { - _FakeImaSdkFactory_12( +class _FakeAdsRenderingSettings_12 extends _i1.SmartFake + implements _i2.AdsRenderingSettings { + _FakeAdsRenderingSettings_12( Object parent, Invocation parentInvocation, ) : super( @@ -163,8 +164,8 @@ class _FakeImaSdkFactory_12 extends _i1.SmartFake implements _i2.ImaSdkFactory { ); } -class _FakeVideoAdPlayer_13 extends _i1.SmartFake implements _i2.VideoAdPlayer { - _FakeVideoAdPlayer_13( +class _FakeImaSdkFactory_13 extends _i1.SmartFake implements _i2.ImaSdkFactory { + _FakeImaSdkFactory_13( Object parent, Invocation parentInvocation, ) : super( @@ -173,9 +174,19 @@ class _FakeVideoAdPlayer_13 extends _i1.SmartFake implements _i2.VideoAdPlayer { ); } -class _FakeVideoAdPlayerCallback_14 extends _i1.SmartFake +class _FakeVideoAdPlayer_14 extends _i1.SmartFake implements _i2.VideoAdPlayer { + _FakeVideoAdPlayer_14( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVideoAdPlayerCallback_15 extends _i1.SmartFake implements _i2.VideoAdPlayerCallback { - _FakeVideoAdPlayerCallback_14( + _FakeVideoAdPlayerCallback_15( Object parent, Invocation parentInvocation, ) : super( @@ -184,8 +195,8 @@ class _FakeVideoAdPlayerCallback_14 extends _i1.SmartFake ); } -class _FakeVideoView_15 extends _i1.SmartFake implements _i2.VideoView { - _FakeVideoView_15( +class _FakeVideoView_16 extends _i1.SmartFake implements _i2.VideoView { + _FakeVideoView_16( Object parent, Invocation parentInvocation, ) : super( @@ -194,8 +205,8 @@ class _FakeVideoView_15 extends _i1.SmartFake implements _i2.VideoView { ); } -class _FakeOffset_16 extends _i1.SmartFake implements _i3.Offset { - _FakeOffset_16( +class _FakeOffset_17 extends _i1.SmartFake implements _i3.Offset { + _FakeOffset_17( Object parent, Invocation parentInvocation, ) : super( @@ -204,8 +215,8 @@ class _FakeOffset_16 extends _i1.SmartFake implements _i3.Offset { ); } -class _FakeSize_17 extends _i1.SmartFake implements _i3.Size { - _FakeSize_17( +class _FakeSize_18 extends _i1.SmartFake implements _i3.Size { + _FakeSize_18( Object parent, Invocation parentInvocation, ) : super( @@ -214,9 +225,9 @@ class _FakeSize_17 extends _i1.SmartFake implements _i3.Size { ); } -class _FakeExpensiveAndroidViewController_18 extends _i1.SmartFake +class _FakeExpensiveAndroidViewController_19 extends _i1.SmartFake implements _i4.ExpensiveAndroidViewController { - _FakeExpensiveAndroidViewController_18( + _FakeExpensiveAndroidViewController_19( Object parent, Invocation parentInvocation, ) : super( @@ -225,9 +236,9 @@ class _FakeExpensiveAndroidViewController_18 extends _i1.SmartFake ); } -class _FakeSurfaceAndroidViewController_19 extends _i1.SmartFake +class _FakeSurfaceAndroidViewController_20 extends _i1.SmartFake implements _i4.SurfaceAndroidViewController { - _FakeSurfaceAndroidViewController_19( + _FakeSurfaceAndroidViewController_20( Object parent, Invocation parentInvocation, ) : super( @@ -1066,20 +1077,45 @@ class MockImaSdkFactory extends _i1.Mock implements _i2.ImaSdkFactory { )), ) as _i6.Future<_i2.AdsRequest>); + @override + _i6.Future<_i2.AdsRenderingSettings> createAdsRenderingSettings() => + (super.noSuchMethod( + Invocation.method( + #createAdsRenderingSettings, + [], + ), + returnValue: _i6.Future<_i2.AdsRenderingSettings>.value( + _FakeAdsRenderingSettings_12( + this, + Invocation.method( + #createAdsRenderingSettings, + [], + ), + )), + returnValueForMissingStub: _i6.Future<_i2.AdsRenderingSettings>.value( + _FakeAdsRenderingSettings_12( + this, + Invocation.method( + #createAdsRenderingSettings, + [], + ), + )), + ) as _i6.Future<_i2.AdsRenderingSettings>); + @override _i2.ImaSdkFactory pigeon_copy() => (super.noSuchMethod( Invocation.method( #pigeon_copy, [], ), - returnValue: _FakeImaSdkFactory_12( + returnValue: _FakeImaSdkFactory_13( this, Invocation.method( #pigeon_copy, [], ), ), - returnValueForMissingStub: _FakeImaSdkFactory_12( + returnValueForMissingStub: _FakeImaSdkFactory_13( this, Invocation.method( #pigeon_copy, @@ -1298,14 +1334,14 @@ class MockVideoAdPlayer extends _i1.Mock implements _i2.VideoAdPlayer { #pigeon_copy, [], ), - returnValue: _FakeVideoAdPlayer_13( + returnValue: _FakeVideoAdPlayer_14( this, Invocation.method( #pigeon_copy, [], ), ), - returnValueForMissingStub: _FakeVideoAdPlayer_13( + returnValueForMissingStub: _FakeVideoAdPlayer_14( this, Invocation.method( #pigeon_copy, @@ -1456,14 +1492,14 @@ class MockVideoAdPlayerCallback extends _i1.Mock #pigeon_copy, [], ), - returnValue: _FakeVideoAdPlayerCallback_14( + returnValue: _FakeVideoAdPlayerCallback_15( this, Invocation.method( #pigeon_copy, [], ), ), - returnValueForMissingStub: _FakeVideoAdPlayerCallback_14( + returnValueForMissingStub: _FakeVideoAdPlayerCallback_15( this, Invocation.method( #pigeon_copy, @@ -1543,14 +1579,14 @@ class MockVideoView extends _i1.Mock implements _i2.VideoView { #pigeon_copy, [], ), - returnValue: _FakeVideoView_15( + returnValue: _FakeVideoView_16( this, Invocation.method( #pigeon_copy, [], ), ), - returnValueForMissingStub: _FakeVideoView_15( + returnValueForMissingStub: _FakeVideoView_16( this, Invocation.method( #pigeon_copy, @@ -1589,11 +1625,11 @@ class MockSurfaceAndroidViewController extends _i1.Mock @override _i4.PointTransformer get pointTransformer => (super.noSuchMethod( Invocation.getter(#pointTransformer), - returnValue: (_i3.Offset position) => _FakeOffset_16( + returnValue: (_i3.Offset position) => _FakeOffset_17( this, Invocation.getter(#pointTransformer), ), - returnValueForMissingStub: (_i3.Offset position) => _FakeOffset_16( + returnValueForMissingStub: (_i3.Offset position) => _FakeOffset_17( this, Invocation.getter(#pointTransformer), ), @@ -1657,14 +1693,14 @@ class MockSurfaceAndroidViewController extends _i1.Mock #setSize, [size], ), - returnValue: _i6.Future<_i3.Size>.value(_FakeSize_17( + returnValue: _i6.Future<_i3.Size>.value(_FakeSize_18( this, Invocation.method( #setSize, [size], ), )), - returnValueForMissingStub: _i6.Future<_i3.Size>.value(_FakeSize_17( + returnValueForMissingStub: _i6.Future<_i3.Size>.value(_FakeSize_18( this, Invocation.method( #setSize, @@ -1777,7 +1813,7 @@ class MockPlatformViewsServiceProxy extends _i1.Mock #onFocus: onFocus, }, ), - returnValue: _FakeExpensiveAndroidViewController_18( + returnValue: _FakeExpensiveAndroidViewController_19( this, Invocation.method( #initExpensiveAndroidView, @@ -1792,7 +1828,7 @@ class MockPlatformViewsServiceProxy extends _i1.Mock }, ), ), - returnValueForMissingStub: _FakeExpensiveAndroidViewController_18( + returnValueForMissingStub: _FakeExpensiveAndroidViewController_19( this, Invocation.method( #initExpensiveAndroidView, @@ -1831,7 +1867,7 @@ class MockPlatformViewsServiceProxy extends _i1.Mock #onFocus: onFocus, }, ), - returnValue: _FakeSurfaceAndroidViewController_19( + returnValue: _FakeSurfaceAndroidViewController_20( this, Invocation.method( #initSurfaceAndroidView, @@ -1846,7 +1882,7 @@ class MockPlatformViewsServiceProxy extends _i1.Mock }, ), ), - returnValueForMissingStub: _FakeSurfaceAndroidViewController_19( + returnValueForMissingStub: _FakeSurfaceAndroidViewController_20( this, Invocation.method( #initSurfaceAndroidView, 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 0b94d6a7d75..90e2ed9ad5f 100644 --- a/packages/interactive_media_ads/test/android/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/android/ads_manager_test.dart @@ -5,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:interactive_media_ads/src/android/android_ads_manager.dart'; import 'package:interactive_media_ads/src/android/android_ads_manager_delegate.dart'; +import 'package:interactive_media_ads/src/android/android_ads_rendering_settings.dart'; import 'package:interactive_media_ads/src/android/interactive_media_ads.g.dart' as ima; import 'package:interactive_media_ads/src/android/interactive_media_ads_proxy.dart'; @@ -21,6 +22,8 @@ import 'ads_manager_test.mocks.dart'; MockSpec(), MockSpec(), MockSpec(), + MockSpec(), + MockSpec(), ]) void main() { group('AndroidAdsManager', () { @@ -32,12 +35,46 @@ void main() { verify(mockAdsManager.destroy()); }); - test('init', () { + test('init', () async { final MockAdsManager mockAdsManager = MockAdsManager(); + + final MockImaSdkFactory mockImaSdkFactory = MockImaSdkFactory(); + final MockAdsRenderingSettings mockAdsRenderingSettings = + MockAdsRenderingSettings(); + when(mockImaSdkFactory.createAdsRenderingSettings()).thenAnswer( + (_) => Future.value(mockAdsRenderingSettings), + ); + final AndroidAdsManager adsManager = AndroidAdsManager(mockAdsManager); - adsManager.init(AdsManagerInitParams()); - verify(mockAdsManager.init(null)); + final AndroidAdsRenderingSettings settings = AndroidAdsRenderingSettings( + AndroidAdsRenderingSettingsCreationParams( + bitrate: 1000, + enablePreloading: false, + loadVideoTimeout: const Duration(seconds: 2), + mimeTypes: const ['value'], + playAdsAfterTime: const Duration(seconds: 5), + uiElements: const {AdUIElement.countdown}, + enableCustomTabs: true, + proxy: InteractiveMediaAdsProxy( + instanceImaSdkFactory: () => mockImaSdkFactory, + ), + ), + ); + await adsManager.init(settings: settings); + + verifyInOrder(>[ + mockAdsRenderingSettings.setBitrateKbps(1000), + mockAdsRenderingSettings.setEnablePreloading(false), + mockAdsRenderingSettings.setLoadVideoTimeout(2000), + mockAdsRenderingSettings.setMimeTypes(['value']), + mockAdsRenderingSettings.setPlayAdsAfterTime(5.0), + mockAdsRenderingSettings.setUiElements( + [ima.UiElement.countdown], + ), + mockAdsRenderingSettings.setEnableCustomTabs(true), + mockAdsManager.init(mockAdsRenderingSettings), + ]); }); test('start', () { 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 6006ba48f18..4181bca8d7f 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 @@ -96,6 +96,58 @@ class _FakeAdsManager_6 extends _i1.SmartFake implements _i2.AdsManager { ); } +class _FakeAdsRenderingSettings_7 extends _i1.SmartFake + implements _i2.AdsRenderingSettings { + _FakeAdsRenderingSettings_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeImaSdkSettings_8 extends _i1.SmartFake + implements _i2.ImaSdkSettings { + _FakeImaSdkSettings_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsLoader_9 extends _i1.SmartFake implements _i2.AdsLoader { + _FakeAdsLoader_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAdsRequest_10 extends _i1.SmartFake implements _i2.AdsRequest { + _FakeAdsRequest_10( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeImaSdkFactory_11 extends _i1.SmartFake implements _i2.ImaSdkFactory { + _FakeImaSdkFactory_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [AdError]. /// /// See the documentation for Mockito's code generation for more information. @@ -583,3 +635,327 @@ class MockAdsManager extends _i1.Mock implements _i2.AdsManager { returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); } + +/// A class which mocks [AdsRenderingSettings]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAdsRenderingSettings extends _i1.Mock + implements _i2.AdsRenderingSettings { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i4.Future getBitrateKbps() => (super.noSuchMethod( + Invocation.method( + #getBitrateKbps, + [], + ), + returnValue: _i4.Future.value(0), + returnValueForMissingStub: _i4.Future.value(0), + ) as _i4.Future); + + @override + _i4.Future getEnableCustomTabs() => (super.noSuchMethod( + Invocation.method( + #getEnableCustomTabs, + [], + ), + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future getEnablePreloading() => (super.noSuchMethod( + Invocation.method( + #getEnablePreloading, + [], + ), + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future getFocusSkipButtonWhenAvailable() => (super.noSuchMethod( + Invocation.method( + #getFocusSkipButtonWhenAvailable, + [], + ), + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future> getMimeTypes() => (super.noSuchMethod( + Invocation.method( + #getMimeTypes, + [], + ), + returnValue: _i4.Future>.value([]), + returnValueForMissingStub: _i4.Future>.value([]), + ) as _i4.Future>); + + @override + _i4.Future setBitrateKbps(int? bitrate) => (super.noSuchMethod( + Invocation.method( + #setBitrateKbps, + [bitrate], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setEnableCustomTabs(bool? enableCustomTabs) => + (super.noSuchMethod( + Invocation.method( + #setEnableCustomTabs, + [enableCustomTabs], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setEnablePreloading(bool? enablePreloading) => + (super.noSuchMethod( + Invocation.method( + #setEnablePreloading, + [enablePreloading], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setFocusSkipButtonWhenAvailable( + bool? enableFocusSkipButton) => + (super.noSuchMethod( + Invocation.method( + #setFocusSkipButtonWhenAvailable, + [enableFocusSkipButton], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setLoadVideoTimeout(int? loadVideoTimeout) => + (super.noSuchMethod( + Invocation.method( + #setLoadVideoTimeout, + [loadVideoTimeout], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setMimeTypes(List? mimeTypes) => (super.noSuchMethod( + Invocation.method( + #setMimeTypes, + [mimeTypes], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setPlayAdsAfterTime(double? time) => (super.noSuchMethod( + Invocation.method( + #setPlayAdsAfterTime, + [time], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setUiElements(List<_i2.UiElement>? uiElements) => + (super.noSuchMethod( + Invocation.method( + #setUiElements, + [uiElements], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i2.AdsRenderingSettings pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeAdsRenderingSettings_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeAdsRenderingSettings_7( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.AdsRenderingSettings); +} + +/// A class which mocks [ImaSdkFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockImaSdkFactory extends _i1.Mock implements _i2.ImaSdkFactory { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i4.Future<_i2.ImaSdkSettings> createImaSdkSettings() => (super.noSuchMethod( + Invocation.method( + #createImaSdkSettings, + [], + ), + returnValue: _i4.Future<_i2.ImaSdkSettings>.value(_FakeImaSdkSettings_8( + this, + Invocation.method( + #createImaSdkSettings, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i2.ImaSdkSettings>.value(_FakeImaSdkSettings_8( + this, + Invocation.method( + #createImaSdkSettings, + [], + ), + )), + ) as _i4.Future<_i2.ImaSdkSettings>); + + @override + _i4.Future<_i2.AdsLoader> createAdsLoader( + _i2.ImaSdkSettings? settings, + _i2.AdDisplayContainer? container, + ) => + (super.noSuchMethod( + Invocation.method( + #createAdsLoader, + [ + settings, + container, + ], + ), + returnValue: _i4.Future<_i2.AdsLoader>.value(_FakeAdsLoader_9( + this, + Invocation.method( + #createAdsLoader, + [ + settings, + container, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i2.AdsLoader>.value(_FakeAdsLoader_9( + this, + Invocation.method( + #createAdsLoader, + [ + settings, + container, + ], + ), + )), + ) as _i4.Future<_i2.AdsLoader>); + + @override + _i4.Future<_i2.AdsRequest> createAdsRequest() => (super.noSuchMethod( + Invocation.method( + #createAdsRequest, + [], + ), + returnValue: _i4.Future<_i2.AdsRequest>.value(_FakeAdsRequest_10( + this, + Invocation.method( + #createAdsRequest, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i2.AdsRequest>.value(_FakeAdsRequest_10( + this, + Invocation.method( + #createAdsRequest, + [], + ), + )), + ) as _i4.Future<_i2.AdsRequest>); + + @override + _i4.Future<_i2.AdsRenderingSettings> createAdsRenderingSettings() => + (super.noSuchMethod( + Invocation.method( + #createAdsRenderingSettings, + [], + ), + returnValue: _i4.Future<_i2.AdsRenderingSettings>.value( + _FakeAdsRenderingSettings_7( + this, + Invocation.method( + #createAdsRenderingSettings, + [], + ), + )), + returnValueForMissingStub: _i4.Future<_i2.AdsRenderingSettings>.value( + _FakeAdsRenderingSettings_7( + this, + Invocation.method( + #createAdsRenderingSettings, + [], + ), + )), + ) as _i4.Future<_i2.AdsRenderingSettings>); + + @override + _i2.ImaSdkFactory pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeImaSdkFactory_11( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeImaSdkFactory_11( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.ImaSdkFactory); +} 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 06d1e1dab51..ff4094bc804 100644 --- a/packages/interactive_media_ads/test/ios/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/ios/ads_manager_test.dart @@ -8,13 +8,17 @@ import 'package:interactive_media_ads/src/ios/interactive_media_ads.g.dart' import 'package:interactive_media_ads/src/ios/interactive_media_ads_proxy.dart'; import 'package:interactive_media_ads/src/ios/ios_ads_manager.dart'; import 'package:interactive_media_ads/src/ios/ios_ads_manager_delegate.dart'; +import 'package:interactive_media_ads/src/ios/ios_ads_rendering_settings.dart'; import 'package:interactive_media_ads/src/platform_interface/platform_interface.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'ads_manager_test.mocks.dart'; -@GenerateNiceMocks(>[MockSpec()]) +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), +]) void main() { group('IOSAdsManager', () { test('destroy', () { @@ -25,12 +29,40 @@ void main() { verify(mockAdsManager.destroy()); }); - test('init', () { + test('init', () async { final MockIMAAdsManager mockAdsManager = MockIMAAdsManager(); + + final MockIMAAdsRenderingSettings mockAdsRenderingSettings = + MockIMAAdsRenderingSettings(); + final IOSAdsManager adsManager = IOSAdsManager(mockAdsManager); - adsManager.init(AdsManagerInitParams()); - verify(mockAdsManager.initialize(null)); + final IOSAdsRenderingSettings settings = IOSAdsRenderingSettings( + IOSAdsRenderingSettingsCreationParams( + bitrate: 1000, + enablePreloading: false, + loadVideoTimeout: const Duration(seconds: 9), + mimeTypes: const ['value'], + playAdsAfterTime: const Duration(seconds: 5), + uiElements: const {AdUIElement.countdown}, + proxy: InteractiveMediaAdsProxy( + newIMAAdsRenderingSettings: () => mockAdsRenderingSettings, + ), + ), + ); + await adsManager.init(settings: settings); + + verifyInOrder(>[ + mockAdsRenderingSettings.setBitrate(1000), + mockAdsRenderingSettings.setEnablePreloading(false), + mockAdsRenderingSettings.setLoadVideoTimeout(9.0), + mockAdsRenderingSettings.setMimeTypes(['value']), + mockAdsRenderingSettings.setPlayAdsAfterTime(5.0), + mockAdsRenderingSettings.setUIElements( + [ima.UIElementType.countdown], + ), + mockAdsManager.initialize(mockAdsRenderingSettings), + ]); }); test('start', () { 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 9e891eb299f..7214de1d0a5 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 @@ -43,6 +43,17 @@ class _FakeIMAAdsManager_1 extends _i1.SmartFake implements _i2.IMAAdsManager { ); } +class _FakeIMAAdsRenderingSettings_2 extends _i1.SmartFake + implements _i2.IMAAdsRenderingSettings { + _FakeIMAAdsRenderingSettings_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [IMAAdsManager]. /// /// See the documentation for Mockito's code generation for more information. @@ -165,3 +176,117 @@ class MockIMAAdsManager extends _i1.Mock implements _i2.IMAAdsManager { ), ) as _i2.IMAAdsManager); } + +/// A class which mocks [IMAAdsRenderingSettings]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIMAAdsRenderingSettings extends _i1.Mock + implements _i2.IMAAdsRenderingSettings { + @override + _i2.PigeonInstanceManager get pigeon_instanceManager => (super.noSuchMethod( + Invocation.getter(#pigeon_instanceManager), + returnValue: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + returnValueForMissingStub: _FakePigeonInstanceManager_0( + this, + Invocation.getter(#pigeon_instanceManager), + ), + ) as _i2.PigeonInstanceManager); + + @override + _i3.Future setMimeTypes(List? types) => (super.noSuchMethod( + Invocation.method( + #setMimeTypes, + [types], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setBitrate(int? bitrate) => (super.noSuchMethod( + Invocation.method( + #setBitrate, + [bitrate], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setLoadVideoTimeout(double? seconds) => (super.noSuchMethod( + Invocation.method( + #setLoadVideoTimeout, + [seconds], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setPlayAdsAfterTime(double? seconds) => (super.noSuchMethod( + Invocation.method( + #setPlayAdsAfterTime, + [seconds], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setUIElements(List<_i2.UIElementType>? types) => + (super.noSuchMethod( + Invocation.method( + #setUIElements, + [types], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setEnablePreloading(bool? enable) => (super.noSuchMethod( + Invocation.method( + #setEnablePreloading, + [enable], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future setLinkOpenerPresentingController( + _i2.UIViewController? controller) => + (super.noSuchMethod( + Invocation.method( + #setLinkOpenerPresentingController, + [controller], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i2.IMAAdsRenderingSettings pigeon_copy() => (super.noSuchMethod( + Invocation.method( + #pigeon_copy, + [], + ), + returnValue: _FakeIMAAdsRenderingSettings_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + returnValueForMissingStub: _FakeIMAAdsRenderingSettings_2( + this, + Invocation.method( + #pigeon_copy, + [], + ), + ), + ) as _i2.IMAAdsRenderingSettings); +} diff --git a/packages/interactive_media_ads/test/test_stubs.dart b/packages/interactive_media_ads/test/test_stubs.dart index 328f58f4699..ff3ae451215 100644 --- a/packages/interactive_media_ads/test/test_stubs.dart +++ b/packages/interactive_media_ads/test/test_stubs.dart @@ -12,6 +12,7 @@ final class TestInteractiveMediaAdsPlatform required this.onCreatePlatformAdsManagerDelegate, required this.onCreatePlatformAdDisplayContainer, required this.onCreatePlatformContentProgressProvider, + this.onCreatePlatformAdsRenderingSettings, }); PlatformAdsLoader Function(PlatformAdsLoaderCreationParams params) @@ -29,6 +30,10 @@ final class TestInteractiveMediaAdsPlatform PlatformContentProgressProviderCreationParams params, ) onCreatePlatformContentProgressProvider; + PlatformAdsRenderingSettings Function( + PlatformAdsRenderingSettingsCreationParams params, + )? onCreatePlatformAdsRenderingSettings; + @override PlatformAdsLoader createPlatformAdsLoader( PlatformAdsLoaderCreationParams params, @@ -56,6 +61,14 @@ final class TestInteractiveMediaAdsPlatform ) { return onCreatePlatformContentProgressProvider(params); } + + @override + PlatformAdsRenderingSettings createPlatformAdsRenderingSettings( + PlatformAdsRenderingSettingsCreationParams params, + ) { + return onCreatePlatformAdsRenderingSettings?.call(params) ?? + TestAdsRenderingSettings(params); + } } final class TestPlatformAdDisplayContainer extends PlatformAdDisplayContainer { @@ -110,7 +123,7 @@ class TestAdsManager extends PlatformAdsManager { this.onSkip, }); - Future Function(AdsManagerInitParams params)? onInit; + Future Function({PlatformAdsRenderingSettings? settings})? onInit; Future Function(PlatformAdsManagerDelegate delegate)? onSetAdsManagerDelegate; @@ -128,8 +141,8 @@ class TestAdsManager extends PlatformAdsManager { Future Function()? onDestroy; @override - Future init(AdsManagerInitParams params) async { - return onInit?.call(params); + Future init({PlatformAdsRenderingSettings? settings}) async { + return onInit?.call(settings: settings); } @override @@ -189,3 +202,7 @@ class TestContentProgressProvider extends PlatformContentProgressProvider { return onSetProgress?.call(progress: progress, duration: duration); } } + +final class TestAdsRenderingSettings extends PlatformAdsRenderingSettings { + TestAdsRenderingSettings(super.params) : super.implementation(); +}