From 9d00fb1a8e508d651c6792a2945f116419a827e0 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:20:16 -0600 Subject: [PATCH] [interactive_media_ads] Adds internal wrapper for Android native `CompanionAd` (#7823) --- packages/interactive_media_ads/CHANGELOG.md | 4 + .../AdsRequestProxyApi.kt | 2 +- .../CompanionAdProxyApi.kt | 32 +++++ .../InteractiveMediaAdsLibrary.g.kt | 85 ++++++++++++- .../ProxyApiRegistrar.kt | 4 + .../CompanionAdProxyApiTest.kt | 57 +++++++++ .../AdsRequestProxyAPIDelegate.swift | 2 +- .../src/android/interactive_media_ads.g.dart | 120 +++++++++++++++++- .../interactive_media_ads_android.dart | 26 ++++ packages/interactive_media_ads/pubspec.yaml | 4 +- 10 files changed, 330 insertions(+), 6 deletions(-) create mode 100644 packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApi.kt create mode 100644 packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md index b02b9f73ce42..124b1ee3d0be 100644 --- a/packages/interactive_media_ads/CHANGELOG.md +++ b/packages/interactive_media_ads/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.2+9 + +* Adds internal wrapper for Android native `CompanionAd`. + ## 0.2.2+8 * Adds remaining methods for internal wrapper of the iOS native `IMAAdsRenderingSettings`. 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 a15b427afda6..c033cf214319 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+8" + const val pluginVersion = "0.2.2+9" } 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/CompanionAdProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApi.kt new file mode 100644 index 000000000000..06b805c840f5 --- /dev/null +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApi.kt @@ -0,0 +1,32 @@ +// 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.CompanionAd + +/** + * ProxyApi implementation for [CompanionAd]. + * + *

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 CompanionAdProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : + PigeonApiCompanionAd(pigeonRegistrar) { + override fun apiFramework(pigeon_instance: CompanionAd): String? { + return pigeon_instance.apiFramework + } + + override fun height(pigeon_instance: CompanionAd): Long { + return pigeon_instance.height.toLong() + } + + override fun resourceValue(pigeon_instance: CompanionAd): String { + return pigeon_instance.resourceValue + } + + override fun width(pigeon_instance: CompanionAd): Long { + return pigeon_instance.width.toLong() + } +} 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 798bb41f20a3..fcbb577a38b9 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.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass", "SyntheticAccessor") @@ -549,6 +549,12 @@ abstract class InteractiveMediaAdsLibraryPigeonProxyApiRegistrar( */ abstract fun getPigeonApiAdProgressInfo(): PigeonApiAdProgressInfo + /** + * An implementation of [PigeonApiCompanionAd] used to add a new Dart instance of `CompanionAd` to + * the Dart `InstanceManager`. + */ + abstract fun getPigeonApiCompanionAd(): PigeonApiCompanionAd + fun setUp() { InteractiveMediaAdsLibraryPigeonInstanceManagerApi.setUpMessageHandlers( binaryMessenger, instanceManager) @@ -689,6 +695,8 @@ private class InteractiveMediaAdsLibraryPigeonProxyApiBaseCodec( registrar.getPigeonApiAdsRenderingSettings().pigeon_newInstance(value) {} } else if (value is com.google.ads.interactivemedia.v3.api.AdProgressInfo) { registrar.getPigeonApiAdProgressInfo().pigeon_newInstance(value) {} + } else if (value is com.google.ads.interactivemedia.v3.api.CompanionAd) { + registrar.getPigeonApiCompanionAd().pigeon_newInstance(value) {} } when { @@ -4718,3 +4726,78 @@ abstract class PigeonApiAdProgressInfo( } } } +/** + * An object that holds data corresponding to the companion Ad. + * + * See + * https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/CompanionAd.html. + */ +@Suppress("UNCHECKED_CAST") +abstract class PigeonApiCompanionAd( + open val pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar +) { + /** The API needed to execute this ad, or null if unavailable. */ + abstract fun apiFramework( + pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd + ): String? + + /** + * The height of the companion in pixels. + * + * 0 if unavailable. + */ + abstract fun height(pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd): Long + + /** The URL for the static resource of this companion. */ + abstract fun resourceValue( + pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd + ): String + + /** + * The width of the companion in pixels. + * + * 0 if unavailable. + */ + abstract fun width(pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd): Long + + @Suppress("LocalVariableName", "FunctionName") + /** Creates a Dart instance of CompanionAd and attaches it to [pigeon_instanceArg]. */ + fun pigeon_newInstance( + pigeon_instanceArg: com.google.ads.interactivemedia.v3.api.CompanionAd, + 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 apiFrameworkArg = apiFramework(pigeon_instanceArg) + val heightArg = height(pigeon_instanceArg) + val resourceValueArg = resourceValue(pigeon_instanceArg) + val widthArg = width(pigeon_instanceArg) + val binaryMessenger = pigeonRegistrar.binaryMessenger + val codec = pigeonRegistrar.codec + val channelName = "dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send( + listOf(pigeon_identifierArg, apiFrameworkArg, heightArg, resourceValueArg, widthArg)) { + 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 61707d049bc7..b6000f36f0b1 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 @@ -133,4 +133,8 @@ open class ProxyApiRegistrar(binaryMessenger: BinaryMessenger, var context: Cont override fun getPigeonApiAdProgressInfo(): PigeonApiAdProgressInfo { return AdProgressInfoProxyApi(this) } + + override fun getPigeonApiCompanionAd(): PigeonApiCompanionAd { + return CompanionAdProxyApi(this) + } } diff --git a/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt new file mode 100644 index 000000000000..dbc6aaf1e7c2 --- /dev/null +++ b/packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/CompanionAdProxyApiTest.kt @@ -0,0 +1,57 @@ +// 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.CompanionAd +import kotlin.test.Test +import kotlin.test.assertEquals +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class CompanionAdProxyApiTest { + @Test + fun apiFramework() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = "myString" + whenever(instance.apiFramework).thenReturn(value) + + assertEquals(value, api.apiFramework(instance)) + } + + @Test + fun height() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = 0 + whenever(instance.height).thenReturn(value) + + assertEquals(value.toLong(), api.height(instance)) + } + + @Test + fun resourceValue() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = "myString" + whenever(instance.resourceValue).thenReturn(value) + + assertEquals(value, api.resourceValue(instance)) + } + + @Test + fun width() { + val api = TestProxyApiRegistrar().getPigeonApiCompanionAd() + + val instance = mock() + val value = 0 + whenever(instance.width).thenReturn(value) + + assertEquals(value.toLong(), api.width(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 44a6ba7b8e80..ffd5259f7a2e 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+8" + static let pluginVersion = "0.2.2+9" 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 168114afa669..1d5532becd2f 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.0), do not edit directly. +// Autogenerated from Pigeon (v22.4.2), 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 @@ -193,6 +193,8 @@ class PigeonInstanceManager { pigeon_instanceManager: instanceManager); AdProgressInfo.pigeon_setUpMessageHandlers( pigeon_instanceManager: instanceManager); + CompanionAd.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); return instanceManager; } @@ -5631,3 +5633,119 @@ class AdProgressInfo extends PigeonInternalProxyApiBaseClass { ); } } + +/// An object that holds data corresponding to the companion Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/CompanionAd.html. +class CompanionAd extends PigeonInternalProxyApiBaseClass { + /// Constructs [CompanionAd] 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 + CompanionAd.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.apiFramework, + required this.height, + required this.resourceValue, + required this.width, + }); + + /// The API needed to execute this ad, or null if unavailable. + final String? apiFramework; + + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + final int height; + + /// The URL for the static resource of this companion. + final String resourceValue; + + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + final int width; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + CompanionAd Function( + String? apiFramework, + int height, + String resourceValue, + int width, + )? pigeon_newInstance, + }) { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _PigeonInternalProxyApiBaseCodec( + pigeon_instanceManager ?? PigeonInstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel< + Object?> pigeonVar_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.interactive_media_ads.CompanionAd.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.CompanionAd.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.CompanionAd.pigeon_newInstance was null, expected non-null int.'); + final String? arg_apiFramework = (args[1] as String?); + final int? arg_height = (args[2] as int?); + assert(arg_height != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null int.'); + final String? arg_resourceValue = (args[3] as String?); + assert(arg_resourceValue != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null String.'); + final int? arg_width = (args[4] as int?); + assert(arg_width != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.CompanionAd.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call(arg_apiFramework, arg_height!, + arg_resourceValue!, arg_width!) ?? + CompanionAd.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + apiFramework: arg_apiFramework, + height: arg_height!, + resourceValue: arg_resourceValue!, + width: arg_width!, + ), + 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 + CompanionAd pigeon_copy() { + return CompanionAd.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + apiFramework: apiFramework, + height: height, + resourceValue: resourceValue, + width: width, + ); + } +} 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 fd1adb24e2b4..314187f90888 100644 --- a/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart +++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_android.dart @@ -862,3 +862,29 @@ abstract class AdProgressInfo { /// The total number of ads in this ad break. late final int totalAds; } + +/// An object that holds data corresponding to the companion Ad. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/CompanionAd.html. +@ProxyApi( + kotlinOptions: KotlinProxyApiOptions( + fullClassName: 'com.google.ads.interactivemedia.v3.api.CompanionAd', + ), +) +abstract class CompanionAd { + /// The API needed to execute this ad, or null if unavailable. + late final String? apiFramework; + + /// The height of the companion in pixels. + /// + /// 0 if unavailable. + late final int height; + + /// The URL for the static resource of this companion. + late final String resourceValue; + + /// The width of the companion in pixels. + /// + /// 0 if unavailable. + late final int width; +} diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml index 09ace13b720b..aa10d145f2c5 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+8 # This must match the version in +version: 0.2.2+9 # 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.2.0 + pigeon: ^22.4.2 topics: - ads