From 3b7ee860b1f960657a5816f633bd1dea062ec739 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:34:55 -0600 Subject: [PATCH] [interactive_media_ads] Adds internal wrapper for Android native `Ad` (#7880) --- packages/interactive_media_ads/CHANGELOG.md | 4 + .../interactive_media_ads/AdProxyApi.kt | 132 ++++++ .../AdsRequestProxyApi.kt | 2 +- .../InteractiveMediaAdsLibrary.g.kt | 216 +++++++++- .../ProxyApiRegistrar.kt | 4 + .../interactive_media_ads/AdProxyApiTest.kt | 316 +++++++++++++++ .../AdsRequestProxyAPIDelegate.swift | 2 +- .../src/android/interactive_media_ads.g.dart | 376 +++++++++++++++++- .../interactive_media_ads_android.dart | 97 +++++ packages/interactive_media_ads/pubspec.yaml | 2 +- 10 files changed, 1146 insertions(+), 5 deletions(-) create mode 100644 packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt create mode 100644 packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md index 51ff5131a3fa..7bfcc2e6e164 100644 --- a/packages/interactive_media_ads/CHANGELOG.md +++ b/packages/interactive_media_ads/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.2+13 + +* Adds internal wrapper for Android native `Ad`. + ## 0.2.2+12 * Adds internal wrapper for iOS native `IMACompanionAd`. diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt new file mode 100644 index 000000000000..11c77bce8750 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApi.kt @@ -0,0 +1,132 @@ +// 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. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.Ad +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import com.google.ads.interactivemedia.v3.api.CompanionAd +import com.google.ads.interactivemedia.v3.api.UniversalAdId + +/** + * ProxyApi implementation for [Ad]. + * + *

This class may handle instantiating native object instances that are attached to a Dart + * instance or handle method calls on the associated native class or an instance of that class. + */ +class AdProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : PigeonApiAd(pigeonRegistrar) { + override fun adId(pigeon_instance: Ad): String { + return pigeon_instance.adId + } + + override fun adPodInfo(pigeon_instance: Ad): AdPodInfo { + return pigeon_instance.adPodInfo + } + + override fun adSystem(pigeon_instance: Ad): String { + return pigeon_instance.adSystem + } + + override fun adWrapperCreativeIds(pigeon_instance: Ad): List { + return pigeon_instance.adWrapperCreativeIds.asList() + } + + override fun adWrapperIds(pigeon_instance: Ad): List { + return pigeon_instance.adWrapperIds.asList() + } + + override fun adWrapperSystems(pigeon_instance: Ad): List { + return pigeon_instance.adWrapperSystems.asList() + } + + override fun advertiserName(pigeon_instance: Ad): String { + return pigeon_instance.advertiserName + } + + override fun companionAds(pigeon_instance: Ad): List { + return pigeon_instance.companionAds + } + + override fun contentType(pigeon_instance: Ad): String? { + return pigeon_instance.contentType + } + + override fun creativeAdId(pigeon_instance: Ad): String { + return pigeon_instance.creativeAdId + } + + override fun creativeId(pigeon_instance: Ad): String { + return pigeon_instance.creativeId + } + + override fun dealId(pigeon_instance: Ad): String { + return pigeon_instance.dealId + } + + override fun description(pigeon_instance: Ad): String? { + return pigeon_instance.description + } + + override fun duration(pigeon_instance: Ad): Double { + return pigeon_instance.duration + } + + override fun height(pigeon_instance: Ad): Long { + return pigeon_instance.height.toLong() + } + + override fun skipTimeOffset(pigeon_instance: Ad): Double { + return pigeon_instance.skipTimeOffset + } + + override fun surveyUrl(pigeon_instance: Ad): String? { + return pigeon_instance.surveyUrl + } + + override fun title(pigeon_instance: Ad): String? { + return pigeon_instance.title + } + + override fun traffickingParameters(pigeon_instance: Ad): String { + return pigeon_instance.traffickingParameters + } + + override fun uiElements(pigeon_instance: Ad): List { + return pigeon_instance.uiElements.map { + when (it) { + com.google.ads.interactivemedia.v3.api.UiElement.AD_ATTRIBUTION -> UiElement.AD_ATTRIBUTION + com.google.ads.interactivemedia.v3.api.UiElement.COUNTDOWN -> UiElement.COUNTDOWN + else -> UiElement.UNKNOWN + } + } + } + + override fun universalAdIds(pigeon_instance: Ad): List { + return pigeon_instance.universalAdIds.toList() + } + + override fun vastMediaBitrate(pigeon_instance: Ad): Long { + return pigeon_instance.vastMediaBitrate.toLong() + } + + override fun vastMediaHeight(pigeon_instance: Ad): Long { + return pigeon_instance.vastMediaHeight.toLong() + } + + override fun vastMediaWidth(pigeon_instance: Ad): Long { + return pigeon_instance.vastMediaWidth.toLong() + } + + override fun width(pigeon_instance: Ad): Long { + return pigeon_instance.width.toLong() + } + + override fun isLinear(pigeon_instance: Ad): Boolean { + return pigeon_instance.isLinear + } + + override fun isSkippable(pigeon_instance: Ad): Boolean { + return pigeon_instance.isSkippable + } +} 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 89de44c76daf..469848956ca2 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+12" + const val pluginVersion = "0.2.2+13" } 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 9442652f4fc9..5547ada0db20 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.4.2), do not edit directly. +// Autogenerated from Pigeon (v22.5.0), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass", "SyntheticAccessor") @@ -561,6 +561,12 @@ abstract class InteractiveMediaAdsLibraryPigeonProxyApiRegistrar( */ abstract fun getPigeonApiUniversalAdId(): PigeonApiUniversalAdId + /** + * An implementation of [PigeonApiAd] used to add a new Dart instance of `Ad` to the Dart + * `InstanceManager`. + */ + abstract fun getPigeonApiAd(): PigeonApiAd + fun setUp() { InteractiveMediaAdsLibraryPigeonInstanceManagerApi.setUpMessageHandlers( binaryMessenger, instanceManager) @@ -705,6 +711,8 @@ private class InteractiveMediaAdsLibraryPigeonProxyApiBaseCodec( registrar.getPigeonApiCompanionAd().pigeon_newInstance(value) {} } else if (value is com.google.ads.interactivemedia.v3.api.UniversalAdId) { registrar.getPigeonApiUniversalAdId().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.Ad) { + registrar.getPigeonApiAd().pigeon_newInstance(value) {} } when { @@ -4905,3 +4913,209 @@ abstract class PigeonApiUniversalAdId( } } } +/** + * An object that holds data corresponding to the main Ad. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/Ad.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiAd( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The ad ID as specified in the VAST response. */ + abstract fun adId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The pod metadata object. */ + abstract fun adPodInfo( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): com.google.ads.interactivemedia.v3.api.AdPodInfo + + /** The ad system as specified in the VAST response. */ + abstract fun adSystem(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The IDs of the ads' creatives, starting with the first wrapper ad. */ + abstract fun adWrapperCreativeIds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The wrapper ad IDs as specified in the VAST response. */ + abstract fun adWrapperIds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The wrapper ad systems as specified in the VAST response. */ + abstract fun adWrapperSystems( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The advertiser name as defined by the serving party. */ + abstract fun advertiserName(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** + * The companions for the current ad while using DAI. + * + * Returns an empty list in any other scenario. + */ + abstract fun companionAds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** + * The content type of the currently selected creative, or null if no creative is selected or the + * content type is unavailable. + */ + abstract fun contentType(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The ISCI (Industry Standard Commercial Identifier) code for an ad. */ + abstract fun creativeAdId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The ID of the selected creative for the ad, */ + abstract fun creativeId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The first deal ID present in the wrapper chain for the current ad, starting from the top. */ + abstract fun dealId(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String + + /** The description of this ad from the VAST response. */ + abstract fun description(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The duration of the ad in seconds, -1 if not available. */ + abstract fun duration(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Double + + /** The height of the selected creative if non-linear, else returns 0. */ + abstract fun height(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The number of seconds of playback before the ad becomes skippable. */ + abstract fun skipTimeOffset(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Double + + /** The URL associated with the survey for the given ad. */ + abstract fun surveyUrl(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The title of this ad from the VAST response. */ + abstract fun title(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): String? + + /** The custom parameters associated with the ad at the time of ad trafficking. */ + abstract fun traffickingParameters( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): String + + /** Te set of ad UI elements rendered by the IMA SDK for this ad. */ + abstract fun uiElements( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The list of all universal ad IDs for this ad. */ + abstract fun universalAdIds( + pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad + ): List + + /** The VAST bitrate in Kbps of the selected creative. */ + abstract fun vastMediaBitrate(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The VAST media height in pixels of the selected creative. */ + abstract fun vastMediaHeight(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The VAST media width in pixels of the selected creative. */ + abstract fun vastMediaWidth(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** The width of the selected creative if non-linear, else returns 0. */ + abstract fun width(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Long + + /** Indicates whether the ad’s current mode of operation is linear or non-linear. */ + abstract fun isLinear(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Boolean + + /** Indicates whether the ad can be skipped by the user. */ + abstract fun isSkippable(pigeon_instance: com.google.ads.interactivemedia.v3.api.Ad): Boolean + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of Ad and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.Ad, + callback: (Result) -> Unit + ) { + if (pigeonRegistrar.ignoreCallsToDart) { + callback( + Result.failure( + FlutterError("ignore-calls-error", "Calls to Dart are being ignored.", ""))) + return + } + if (pigeonRegistrar.instanceManager.containsInstance(pigeon_instanceArg)) { + Result.success(Unit) + return + } + val pigeon_identifierArg = + pigeonRegistrar.instanceManager.addHostCreatedInstance(pigeon_instanceArg) + val adIdArg = adId(pigeon_instanceArg) + val adPodInfoArg = adPodInfo(pigeon_instanceArg) + val adSystemArg = adSystem(pigeon_instanceArg) + val adWrapperCreativeIdsArg = adWrapperCreativeIds(pigeon_instanceArg) + val adWrapperIdsArg = adWrapperIds(pigeon_instanceArg) + val adWrapperSystemsArg = adWrapperSystems(pigeon_instanceArg) + val advertiserNameArg = advertiserName(pigeon_instanceArg) + val companionAdsArg = companionAds(pigeon_instanceArg) + val contentTypeArg = contentType(pigeon_instanceArg) + val creativeAdIdArg = creativeAdId(pigeon_instanceArg) + val creativeIdArg = creativeId(pigeon_instanceArg) + val dealIdArg = dealId(pigeon_instanceArg) + val descriptionArg = description(pigeon_instanceArg) + val durationArg = duration(pigeon_instanceArg) + val heightArg = height(pigeon_instanceArg) + val skipTimeOffsetArg = skipTimeOffset(pigeon_instanceArg) + val surveyUrlArg = surveyUrl(pigeon_instanceArg) + val titleArg = title(pigeon_instanceArg) + val traffickingParametersArg = traffickingParameters(pigeon_instanceArg) + val uiElementsArg = uiElements(pigeon_instanceArg) + val universalAdIdsArg = universalAdIds(pigeon_instanceArg) + val vastMediaBitrateArg = vastMediaBitrate(pigeon_instanceArg) + val vastMediaHeightArg = vastMediaHeight(pigeon_instanceArg) + val vastMediaWidthArg = vastMediaWidth(pigeon_instanceArg) + val widthArg = width(pigeon_instanceArg) + val isLinearArg = isLinear(pigeon_instanceArg) + val isSkippableArg = isSkippable(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf( + pigeon_identifierArg, + adIdArg, + adPodInfoArg, + adSystemArg, + adWrapperCreativeIdsArg, + adWrapperIdsArg, + adWrapperSystemsArg, + advertiserNameArg, + companionAdsArg, + contentTypeArg, + creativeAdIdArg, + creativeIdArg, + dealIdArg, + descriptionArg, + durationArg, + heightArg, + skipTimeOffsetArg, + surveyUrlArg, + titleArg, + traffickingParametersArg, + uiElementsArg, + universalAdIdsArg, + vastMediaBitrateArg, + vastMediaHeightArg, + vastMediaWidthArg, + widthArg, + isLinearArg, + isSkippableArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback( + Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } +} diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt index 5bc4dd399a20..d1cfda322bea 100644 --- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/ProxyApiRegistrar.kt @@ -141,4 +141,8 @@ open class ProxyApiRegistrar(binaryMessenger: BinaryMessenger, var context: Cont override fun getPigeonApiUniversalAdId(): PigeonApiUniversalAdId { return UniversalAdIdProxyApi(this) } + + override fun getPigeonApiAd(): PigeonApiAd { + return AdProxyApi(this) + } } diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt new file mode 100644 index 000000000000..65e498f18c91 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdProxyApiTest.kt @@ -0,0 +1,316 @@ +// 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. + +package dev.flutter.packages.interactive_media_ads + +import com.google.ads.interactivemedia.v3.api.Ad +import com.google.ads.interactivemedia.v3.api.AdPodInfo +import com.google.ads.interactivemedia.v3.api.CompanionAd +import com.google.ads.interactivemedia.v3.api.UiElement +import com.google.ads.interactivemedia.v3.api.UniversalAdId +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class AdProxyApiTest { + @Test + fun adId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.adId).thenReturn(value) + + assertEquals(value, api.adId(instance)) + } + + @Test + fun adPodInfo() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = mock() + whenever(instance.adPodInfo).thenReturn(value) + + assertEquals(value, api.adPodInfo(instance)) + } + + @Test + fun adSystem() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.adSystem).thenReturn(value) + + assertEquals(value, api.adSystem(instance)) + } + + @Test + fun adWrapperCreativeIds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf("myString") + whenever(instance.adWrapperCreativeIds).thenReturn(arrayOf("myString")) + + assertEquals(value, api.adWrapperCreativeIds(instance)) + } + + @Test + fun adWrapperIds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf("myString") + whenever(instance.adWrapperIds).thenReturn(arrayOf("myString")) + + assertEquals(value, api.adWrapperIds(instance)) + } + + @Test + fun adWrapperSystems() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf("myString") + whenever(instance.adWrapperSystems).thenReturn(arrayOf("myString")) + + assertEquals(value, api.adWrapperSystems(instance)) + } + + @Test + fun advertiserName() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.advertiserName).thenReturn(value) + + assertEquals(value, api.advertiserName(instance)) + } + + @Test + fun companionAds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf(mock()) + whenever(instance.companionAds).thenReturn(value) + + assertEquals(value, api.companionAds(instance)) + } + + @Test + fun contentType() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.contentType).thenReturn(value) + + assertEquals(value, api.contentType(instance)) + } + + @Test + fun creativeAdId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.creativeAdId).thenReturn(value) + + assertEquals(value, api.creativeAdId(instance)) + } + + @Test + fun creativeId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.creativeId).thenReturn(value) + + assertEquals(value, api.creativeId(instance)) + } + + @Test + fun dealId() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.dealId).thenReturn(value) + + assertEquals(value, api.dealId(instance)) + } + + @Test + fun description() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.description).thenReturn(value) + + assertEquals(value, api.description(instance)) + } + + @Test + fun duration() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 1.0 + whenever(instance.duration).thenReturn(value) + + assertEquals(value, api.duration(instance)) + } + + @Test + fun height() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.height).thenReturn(value) + + assertEquals(value.toLong(), api.height(instance)) + } + + @Test + fun skipTimeOffset() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 1.0 + whenever(instance.skipTimeOffset).thenReturn(value) + + assertEquals(value, api.skipTimeOffset(instance)) + } + + @Test + fun surveyUrl() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.surveyUrl).thenReturn(value) + + assertEquals(value, api.surveyUrl(instance)) + } + + @Test + fun title() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.title).thenReturn(value) + + assertEquals(value, api.title(instance)) + } + + @Test + fun traffickingParameters() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = "myString" + whenever(instance.traffickingParameters).thenReturn(value) + + assertEquals(value, api.traffickingParameters(instance)) + } + + @Test + fun uiElements() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf(UiElement.AD_ATTRIBUTION) + whenever(instance.uiElements).thenReturn(value.toSet()) + + assertEquals( + listOf(dev.flutter.packages.interactive_media_ads.UiElement.AD_ATTRIBUTION), + api.uiElements(instance)) + } + + @Test + fun universalAdIds() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = listOf(mock()) + whenever(instance.universalAdIds).thenReturn(value.toTypedArray()) + + assertEquals(value, api.universalAdIds(instance)) + } + + @Test + fun vastMediaBitrate() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.vastMediaBitrate).thenReturn(value) + + assertEquals(value.toLong(), api.vastMediaBitrate(instance)) + } + + @Test + fun vastMediaHeight() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.vastMediaHeight).thenReturn(value) + + assertEquals(value.toLong(), api.vastMediaHeight(instance)) + } + + @Test + fun vastMediaWidth() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.vastMediaWidth).thenReturn(value) + + assertEquals(value.toLong(), api.vastMediaWidth(instance)) + } + + @Test + fun width() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = 0 + whenever(instance.width).thenReturn(value) + + assertEquals(value.toLong(), api.width(instance)) + } + + @Test + fun isLinear() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = true + whenever(instance.isLinear).thenReturn(value) + + assertEquals(value, api.isLinear(instance)) + } + + @Test + fun isSkippable() { + val api = TestProxyApiRegistrar().getPigeonApiAd() + + val instance = mock() + val value = true + whenever(instance.isSkippable).thenReturn(value) + + assertEquals(value, api.isSkippable(instance)) + } +} 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 2fc5186bd403..c451d574ab23 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+12" + static let pluginVersion = "0.2.2+13" func pigeonDefaultConstructor( pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer, 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 c28dd5f477b0..be8cd0fadb28 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.4.2), do not edit directly. +// Autogenerated from Pigeon (v22.5.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 @@ -197,6 +197,7 @@ class PigeonInstanceManager { pigeon_instanceManager: instanceManager); UniversalAdId.pigeon_setUpMessageHandlers( pigeon_instanceManager: instanceManager); + Ad.pigeon_setUpMessageHandlers(pigeon_instanceManager: instanceManager); return instanceManager; } @@ -5879,3 +5880,376 @@ class UniversalAdId extends PigeonInternalProxyApiBaseClass { ); } } + +/// An object that holds data corresponding to the main Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/Ad.html. +class Ad extends PigeonInternalProxyApiBaseClass { + /// Constructs [Ad] without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies for an [PigeonInstanceManager]. + @protected + Ad.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adId, + required this.adPodInfo, + required this.adSystem, + required this.adWrapperCreativeIds, + required this.adWrapperIds, + required this.adWrapperSystems, + required this.advertiserName, + required this.companionAds, + this.contentType, + required this.creativeAdId, + required this.creativeId, + required this.dealId, + this.description, + required this.duration, + required this.height, + required this.skipTimeOffset, + this.surveyUrl, + this.title, + required this.traffickingParameters, + required this.uiElements, + required this.universalAdIds, + required this.vastMediaBitrate, + required this.vastMediaHeight, + required this.vastMediaWidth, + required this.width, + required this.isLinear, + required this.isSkippable, + }); + + /// The ad ID as specified in the VAST response. + final String adId; + + /// The pod metadata object. + final AdPodInfo adPodInfo; + + /// The ad system as specified in the VAST response. + final String adSystem; + + /// The IDs of the ads' creatives, starting with the first wrapper ad. + final List adWrapperCreativeIds; + + /// The wrapper ad IDs as specified in the VAST response. + final List adWrapperIds; + + /// The wrapper ad systems as specified in the VAST response. + final List adWrapperSystems; + + /// The advertiser name as defined by the serving party. + final String advertiserName; + + /// The companions for the current ad while using DAI. + /// + /// Returns an empty list in any other scenario. + final List companionAds; + + /// The content type of the currently selected creative, or null if no + /// creative is selected or the content type is unavailable. + final String? contentType; + + /// The ISCI (Industry Standard Commercial Identifier) code for an ad. + final String creativeAdId; + + /// The ID of the selected creative for the ad, + final String creativeId; + + /// The first deal ID present in the wrapper chain for the current ad, + /// starting from the top. + final String dealId; + + /// The description of this ad from the VAST response. + final String? description; + + /// The duration of the ad in seconds, -1 if not available. + final double duration; + + /// The height of the selected creative if non-linear, else returns 0. + final int height; + + /// The number of seconds of playback before the ad becomes skippable. + final double skipTimeOffset; + + /// The URL associated with the survey for the given ad. + final String? surveyUrl; + + /// The title of this ad from the VAST response. + final String? title; + + /// The custom parameters associated with the ad at the time of ad + /// trafficking. + final String traffickingParameters; + + /// Te set of ad UI elements rendered by the IMA SDK for this ad. + final List uiElements; + + /// The list of all universal ad IDs for this ad. + final List universalAdIds; + + /// The VAST bitrate in Kbps of the selected creative. + final int vastMediaBitrate; + + /// The VAST media height in pixels of the selected creative. + final int vastMediaHeight; + + /// The VAST media width in pixels of the selected creative. + final int vastMediaWidth; + + /// The width of the selected creative if non-linear, else returns 0. + final int width; + + /// Indicates whether the ad’s current mode of operation is linear or + /// non-linear. + final bool isLinear; + + /// Indicates whether the ad can be skipped by the user. + final bool isSkippable; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + Ad Function( + String adId, + AdPodInfo adPodInfo, + String adSystem, + List adWrapperCreativeIds, + List adWrapperIds, + List adWrapperSystems, + String advertiserName, + List companionAds, + String? contentType, + String creativeAdId, + String creativeId, + String dealId, + String? description, + double duration, + int height, + double skipTimeOffset, + String? surveyUrl, + String? title, + String traffickingParameters, + List uiElements, + List universalAdIds, + int vastMediaBitrate, + int vastMediaHeight, + int vastMediaWidth, + int width, + bool isLinear, + bool isSkippable, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + 'dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + pigeonVar_channel.setMessageHandler(null); + } else { + pigeonVar_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final String? arg_adId = (args[1] as String?); + assert(arg_adId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final AdPodInfo? arg_adPodInfo = (args[2] as AdPodInfo?); + assert(arg_adPodInfo != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null AdPodInfo.'); + final String? arg_adSystem = (args[3] as String?); + assert(arg_adSystem != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final List? arg_adWrapperCreativeIds = + (args[4] as List?)?.cast(); + assert(arg_adWrapperCreativeIds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final List? arg_adWrapperIds = + (args[5] as List?)?.cast(); + assert(arg_adWrapperIds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final List? arg_adWrapperSystems = + (args[6] as List?)?.cast(); + assert(arg_adWrapperSystems != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final String? arg_advertiserName = (args[7] as String?); + assert(arg_advertiserName != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final List? arg_companionAds = + (args[8] as List?)?.cast(); + assert(arg_companionAds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final String? arg_contentType = (args[9] as String?); + final String? arg_creativeAdId = (args[10] as String?); + assert(arg_creativeAdId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final String? arg_creativeId = (args[11] as String?); + assert(arg_creativeId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final String? arg_dealId = (args[12] as String?); + assert(arg_dealId != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final String? arg_description = (args[13] as String?); + final double? arg_duration = (args[14] as double?); + assert(arg_duration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null double.'); + final int? arg_height = (args[15] as int?); + assert(arg_height != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final double? arg_skipTimeOffset = (args[16] as double?); + assert(arg_skipTimeOffset != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null double.'); + final String? arg_surveyUrl = (args[17] as String?); + final String? arg_title = (args[18] as String?); + final String? arg_traffickingParameters = (args[19] as String?); + assert(arg_traffickingParameters != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.'); + final List? arg_uiElements = + (args[20] as List?)?.cast(); + assert(arg_uiElements != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final List? arg_universalAdIds = + (args[21] as List?)?.cast(); + assert(arg_universalAdIds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.'); + final int? arg_vastMediaBitrate = (args[22] as int?); + assert(arg_vastMediaBitrate != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final int? arg_vastMediaHeight = (args[23] as int?); + assert(arg_vastMediaHeight != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final int? arg_vastMediaWidth = (args[24] as int?); + assert(arg_vastMediaWidth != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final int? arg_width = (args[25] as int?); + assert(arg_width != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null int.'); + final bool? arg_isLinear = (args[26] as bool?); + assert(arg_isLinear != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null bool.'); + final bool? arg_isSkippable = (args[27] as bool?); + assert(arg_isSkippable != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null bool.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_adId!, + arg_adPodInfo!, + arg_adSystem!, + arg_adWrapperCreativeIds!, + arg_adWrapperIds!, + arg_adWrapperSystems!, + arg_advertiserName!, + arg_companionAds!, + arg_contentType, + arg_creativeAdId!, + arg_creativeId!, + arg_dealId!, + arg_description, + arg_duration!, + arg_height!, + arg_skipTimeOffset!, + arg_surveyUrl, + arg_title, + arg_traffickingParameters!, + arg_uiElements!, + arg_universalAdIds!, + arg_vastMediaBitrate!, + arg_vastMediaHeight!, + arg_vastMediaWidth!, + arg_width!, + arg_isLinear!, + arg_isSkippable!) ?? + Ad.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adId: arg_adId!, + adPodInfo: arg_adPodInfo!, + adSystem: arg_adSystem!, + adWrapperCreativeIds: arg_adWrapperCreativeIds!, + adWrapperIds: arg_adWrapperIds!, + adWrapperSystems: arg_adWrapperSystems!, + advertiserName: arg_advertiserName!, + companionAds: arg_companionAds!, + contentType: arg_contentType, + creativeAdId: arg_creativeAdId!, + creativeId: arg_creativeId!, + dealId: arg_dealId!, + description: arg_description, + duration: arg_duration!, + height: arg_height!, + skipTimeOffset: arg_skipTimeOffset!, + surveyUrl: arg_surveyUrl, + title: arg_title, + traffickingParameters: arg_traffickingParameters!, + uiElements: arg_uiElements!, + universalAdIds: arg_universalAdIds!, + vastMediaBitrate: arg_vastMediaBitrate!, + vastMediaHeight: arg_vastMediaHeight!, + vastMediaWidth: arg_vastMediaWidth!, + width: arg_width!, + isLinear: arg_isLinear!, + isSkippable: arg_isSkippable!, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + Ad pigeon_copy() { + return Ad.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adId: adId, + adPodInfo: adPodInfo, + adSystem: adSystem, + adWrapperCreativeIds: adWrapperCreativeIds, + adWrapperIds: adWrapperIds, + adWrapperSystems: adWrapperSystems, + advertiserName: advertiserName, + companionAds: companionAds, + contentType: contentType, + creativeAdId: creativeAdId, + creativeId: creativeId, + dealId: dealId, + description: description, + duration: duration, + height: height, + skipTimeOffset: skipTimeOffset, + surveyUrl: surveyUrl, + title: title, + traffickingParameters: traffickingParameters, + uiElements: uiElements, + universalAdIds: universalAdIds, + vastMediaBitrate: vastMediaBitrate, + vastMediaHeight: vastMediaHeight, + vastMediaWidth: vastMediaWidth, + width: width, + isLinear: isLinear, + isSkippable: isSkippable, + ); + } +} 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 101d482eaa0d..0d3aa77b5342 100644 --- a/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart +++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart @@ -914,3 +914,100 @@ abstract class UniversalAdId { /// Returns "unknown" if the value is not known. late final String adIdValue; } + +/// An object that holds data corresponding to the main Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/Ad.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.Ad', + ), +) +abstract class Ad { + /// The ad ID as specified in the VAST response. + late final String adId; + + /// The pod metadata object. + late final AdPodInfo adPodInfo; + + /// The ad system as specified in the VAST response. + late final String adSystem; + + /// The IDs of the ads' creatives, starting with the first wrapper ad. + late final List adWrapperCreativeIds; + + /// The wrapper ad IDs as specified in the VAST response. + late final List adWrapperIds; + + /// The wrapper ad systems as specified in the VAST response. + late final List adWrapperSystems; + + /// The advertiser name as defined by the serving party. + late final String advertiserName; + + /// The companions for the current ad while using DAI. + /// + /// Returns an empty list in any other scenario. + late final List companionAds; + + /// The content type of the currently selected creative, or null if no + /// creative is selected or the content type is unavailable. + late final String? contentType; + + /// The ISCI (Industry Standard Commercial Identifier) code for an ad. + late final String creativeAdId; + + /// The ID of the selected creative for the ad, + late final String creativeId; + + /// The first deal ID present in the wrapper chain for the current ad, + /// starting from the top. + late final String dealId; + + /// The description of this ad from the VAST response. + late final String? description; + + /// The duration of the ad in seconds, -1 if not available. + late final double duration; + + /// The height of the selected creative if non-linear, else returns 0. + late final int height; + + /// The number of seconds of playback before the ad becomes skippable. + late final double skipTimeOffset; + + /// The URL associated with the survey for the given ad. + late final String? surveyUrl; + + /// The title of this ad from the VAST response. + late final String? title; + + /// The custom parameters associated with the ad at the time of ad + /// trafficking. + late final String traffickingParameters; + + /// Te set of ad UI elements rendered by the IMA SDK for this ad. + late final List uiElements; + + /// The list of all universal ad IDs for this ad. + late final List universalAdIds; + + /// The VAST bitrate in Kbps of the selected creative. + late final int vastMediaBitrate; + + /// The VAST media height in pixels of the selected creative. + late final int vastMediaHeight; + + /// The VAST media width in pixels of the selected creative. + late final int vastMediaWidth; + + /// The width of the selected creative if non-linear, else returns 0. + late final int width; + + /// Indicates whether the ad’s current mode of operation is linear or + /// non-linear. + late final bool isLinear; + + /// Indicates whether the ad can be skipped by the user. + late final bool isSkippable; +} diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml index c67417b80cda..d3101f0322d7 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+12 # This must match the version in +version: 0.2.2+13 # 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`