diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md index 9986455137b..ede0c745c5c 100644 --- a/packages/interactive_media_ads/CHANGELOG.md +++ b/packages/interactive_media_ads/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.3+6 + +* Adds internal wrapper for iOS native `IMAAdPodInfo`. + ## 0.2.3+5 * Bumps gradle-plugin to 2.1.0. 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 eb886b70af3..58418b5df99 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.3+5" + const val pluginVersion = "0.2.3+6" } override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) { diff --git a/packages/interactive_media_ads/example/ios/Runner.xcodeproj/project.pbxproj b/packages/interactive_media_ads/example/ios/Runner.xcodeproj/project.pbxproj index 06a08b5836d..ca9d6c51cf6 100644 --- a/packages/interactive_media_ads/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/interactive_media_ads/example/ios/Runner.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 8F599BBD2C332CFE0090A0DF /* ContentPlayheadTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F599BBC2C332CFE0090A0DF /* ContentPlayheadTests.swift */; }; 8F599BBF2C3335B40090A0DF /* ViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F599BBE2C3335B40090A0DF /* ViewControllerTests.swift */; }; 8F8382A32CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F8382A22CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift */; }; + 8F9035362D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F9035352D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift */; }; 8F977DCF2C2B99C600A90D4B /* AdDisplayContainerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F977DCE2C2B99C600A90D4B /* AdDisplayContainerTests.swift */; }; 8F977DD32C2BA15100A90D4B /* TestProxyApiRegistrar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F977DD22C2BA15100A90D4B /* TestProxyApiRegistrar.swift */; }; 8F977DD52C2C777600A90D4B /* AdErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F977DD42C2C777600A90D4B /* AdErrorTests.swift */; }; @@ -83,6 +84,7 @@ 8F599BBC2C332CFE0090A0DF /* ContentPlayheadTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentPlayheadTests.swift; sourceTree = ""; }; 8F599BBE2C3335B40090A0DF /* ViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerTests.swift; sourceTree = ""; }; 8F8382A22CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanionAdProxyApiTests.swift; sourceTree = ""; }; + 8F9035352D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdPodInfoProxyAPITests.swift; sourceTree = ""; }; 8F977DCE2C2B99C600A90D4B /* AdDisplayContainerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdDisplayContainerTests.swift; sourceTree = ""; }; 8F977DD22C2BA15100A90D4B /* TestProxyApiRegistrar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProxyApiRegistrar.swift; sourceTree = ""; }; 8F977DD42C2C777600A90D4B /* AdErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdErrorTests.swift; sourceTree = ""; }; @@ -144,6 +146,7 @@ 8F8382A22CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift */, 8FFF0C172CC1A7F300A7CB98 /* CompanionAdSlotProxyApiTests.swift */, 8FFF0C192CC1A97B00A7CB98 /* CompanionDelegateProxyApiTests.swift */, + 8F9035352D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift */, ); path = RunnerTests; sourceTree = ""; @@ -426,6 +429,7 @@ 8F599BB92C332A320090A0DF /* AdsRenderingSettingsTests.swift in Sources */, 8F977DD52C2C777600A90D4B /* AdErrorTests.swift in Sources */, 8F599BB12C2DD1FD0090A0DF /* AdsManagerTests.swift in Sources */, + 8F9035362D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift in Sources */, 8F977DDB2C2C8D2E00A90D4B /* AdsLoadedDataTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/packages/interactive_media_ads/example/ios/RunnerTests/AdPodInfoProxyAPITests.swift b/packages/interactive_media_ads/example/ios/RunnerTests/AdPodInfoProxyAPITests.swift new file mode 100644 index 00000000000..8b01d9b64f3 --- /dev/null +++ b/packages/interactive_media_ads/example/ios/RunnerTests/AdPodInfoProxyAPITests.swift @@ -0,0 +1,104 @@ +// 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 Flutter +import GoogleInteractiveMediaAds +import XCTest + +@testable import interactive_media_ads + +class AdPodInfoProxyAPITests: XCTestCase { + func testAdPosition() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar) + + let instance = TestAdPodInfo.customInit() + let value = try? api.pigeonDelegate.adPosition(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, Int64(instance.adPosition)) + } + + func testMaxDuration() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar) + + let instance = TestAdPodInfo.customInit() + let value = try? api.pigeonDelegate.maxDuration(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.maxDuration) + } + + func testPodIndex() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar) + + let instance = TestAdPodInfo.customInit() + let value = try? api.pigeonDelegate.podIndex(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, Int64(instance.podIndex)) + } + + func testTimeOffset() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar) + + let instance = TestAdPodInfo.customInit() + let value = try? api.pigeonDelegate.timeOffset(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.timeOffset) + } + + func testTotalAds() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar) + + let instance = TestAdPodInfo.customInit() + let value = try? api.pigeonDelegate.totalAds(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, Int64(instance.totalAds)) + } + + func testIsBumper() { + let registrar = TestProxyApiRegistrar() + let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar) + + let instance = TestAdPodInfo.customInit() + let value = try? api.pigeonDelegate.isBumper(pigeonApi: api, pigeonInstance: instance) + + XCTAssertEqual(value, instance.isBumper) + } +} + +class TestAdPodInfo: IMAAdPodInfo { + // Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE + static func customInit() -> TestAdPodInfo { + let instance = + TestAdPodInfo.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdPodInfo + return instance + } + + override var adPosition: Int { + return 5 + } + + override var maxDuration: TimeInterval { + return 2.0 + } + + override var podIndex: Int { + return 3 + } + + override var timeOffset: TimeInterval { + return 6.0 + } + + override var totalAds: Int { + return 7 + } + + override var isBumper: Bool { + return false + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdPodInfoProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdPodInfoProxyAPIDelegate.swift new file mode 100644 index 00000000000..dde216528f1 --- /dev/null +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdPodInfoProxyAPIDelegate.swift @@ -0,0 +1,37 @@ +// 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 Foundation +import GoogleInteractiveMediaAds + +/// ProxyApi implementation for `IMAAdPodInfo`. +/// +/// 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 AdPodInfoProxyAPIDelegate: PigeonApiDelegateIMAAdPodInfo { + func adPosition(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 { + return Int64(pigeonInstance.adPosition) + } + + func maxDuration(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double + { + return pigeonInstance.maxDuration + } + + func podIndex(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 { + return Int64(pigeonInstance.podIndex) + } + + func timeOffset(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double { + return pigeonInstance.timeOffset + } + + func totalAds(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 { + return Int64(pigeonInstance.totalAds) + } + + func isBumper(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Bool { + return pigeonInstance.isBumper + } +} 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 1707e13ffab..3da9bdd21e1 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.3+5" + static let pluginVersion = "0.2.3+6" func pigeonDefaultConstructor( pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer, diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift index 6c3ed9ddf27..5f5211ca0c1 100644 --- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift @@ -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.6.2), do not edit directly. +// Autogenerated from Pigeon (v22.7.2), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -457,6 +457,10 @@ protocol InteractiveMediaAdsLibraryPigeonProxyApiDelegate { /// `IMACompanionDelegate` to the Dart `InstanceManager` and make calls to Dart. func pigeonApiIMACompanionDelegate(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) -> PigeonApiIMACompanionDelegate + /// An implementation of [PigeonApiIMAAdPodInfo] used to add a new Dart instance of + /// `IMAAdPodInfo` to the Dart `InstanceManager` and make calls to Dart. + func pigeonApiIMAAdPodInfo(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdPodInfo } extension InteractiveMediaAdsLibraryPigeonProxyApiDelegate { @@ -844,6 +848,17 @@ private class InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter: return } + if let instance = value as? IMAAdPodInfo { + pigeonRegistrar.apiDelegate.pigeonApiIMAAdPodInfo(pigeonRegistrar).pigeonNewInstance( + pigeonInstance: instance + ) { _ in } + super.writeByte(128) + super.writeValue( + pigeonRegistrar.instanceManager.identifierWithStrongReference( + forInstance: instance as AnyObject)!) + return + } + if let instance = value as AnyObject?, pigeonRegistrar.instanceManager.containsInstance(instance) { @@ -3564,7 +3579,7 @@ final class PigeonApiIMACompanionAdSlot: PigeonApiProtocolIMACompanionAdSlot { pigeonDefaultConstructorChannel.setMessageHandler(nil) } let sizeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_defaultConstructor", + name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.size", binaryMessenger: binaryMessenger, codec: codec) if let api = api { sizeChannel.setMessageHandler { message, reply in @@ -3822,3 +3837,108 @@ final class PigeonApiIMACompanionDelegate: PigeonApiProtocolIMACompanionDelegate } } +protocol PigeonApiDelegateIMAAdPodInfo { + /// The position of this ad within an ad pod. + /// + /// Will be 1 for standalone ads. + func adPosition(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 + /// The maximum duration of the pod in seconds. + /// + /// For unknown duration, -1 is returned. + func maxDuration(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double + /// Returns the index of the ad pod. + /// + /// Client side: For a preroll pod, returns 0. For midrolls, returns 1, 2,…, + /// N. For a postroll pod, returns -1. Defaults to 0 if this ad is not part of + /// a pod, or this pod is not part of a playlist. + /// + /// DAI VOD: Returns the index of the ad pod. For a preroll pod, returns 0. + /// For midrolls, returns 1, 2,…,N. For a postroll pod, returns N+1…N+X. + /// Defaults to 0 if this ad is not part of a pod, or this pod is not part of + /// a playlist. + /// + /// DAI live stream: For a preroll pod, returns 0. For midrolls, returns the + /// break ID. Returns -2 if pod index cannot be determined (internal error). + func podIndex(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 + /// The position of the pod in the content in seconds. + /// + /// Pre-roll returns 0, post-roll returns -1 and mid-rolls return the + /// scheduled time of the pod. + func timeOffset(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double + /// Total number of ads in the pod this ad belongs to. + /// + /// Will be 1 for standalone ads. + func totalAds(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 + /// Specifies whether the ad is a bumper. + /// + /// Bumpers are short videos used to open and close ad breaks. + func isBumper(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Bool +} + +protocol PigeonApiProtocolIMAAdPodInfo { +} + +final class PigeonApiIMAAdPodInfo: PigeonApiProtocolIMAAdPodInfo { + unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar + let pigeonDelegate: PigeonApiDelegateIMAAdPodInfo + init( + pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar, + delegate: PigeonApiDelegateIMAAdPodInfo + ) { + self.pigeonRegistrar = pigeonRegistrar + self.pigeonDelegate = delegate + } + ///Creates a Dart instance of IMAAdPodInfo and attaches it to [pigeonInstance]. + func pigeonNewInstance( + pigeonInstance: IMAAdPodInfo, completion: @escaping (Result) -> Void + ) { + if pigeonRegistrar.ignoreCallsToDart { + completion( + .failure( + PigeonError( + code: "ignore-calls-error", + message: "Calls to Dart are being ignored.", details: ""))) + return + } + if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) { + completion(.success(Void())) + return + } + let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance( + pigeonInstance as AnyObject) + let adPositionArg = try! pigeonDelegate.adPosition( + pigeonApi: self, pigeonInstance: pigeonInstance) + let maxDurationArg = try! pigeonDelegate.maxDuration( + pigeonApi: self, pigeonInstance: pigeonInstance) + let podIndexArg = try! pigeonDelegate.podIndex(pigeonApi: self, pigeonInstance: pigeonInstance) + let timeOffsetArg = try! pigeonDelegate.timeOffset( + pigeonApi: self, pigeonInstance: pigeonInstance) + let totalAdsArg = try! pigeonDelegate.totalAds(pigeonApi: self, pigeonInstance: pigeonInstance) + let isBumperArg = try! pigeonDelegate.isBumper(pigeonApi: self, pigeonInstance: pigeonInstance) + let binaryMessenger = pigeonRegistrar.binaryMessenger + let codec = pigeonRegistrar.codec + let channelName: String = + "dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage( + [ + pigeonIdentifierArg, adPositionArg, maxDurationArg, podIndexArg, timeOffsetArg, totalAdsArg, + isBumperArg, + ] as [Any?] + ) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(PigeonError(code: code, message: message, details: details))) + } else { + completion(.success(Void())) + } + } + } +} diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift index 0475adf37ef..7bd4f6d9b43 100644 --- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift @@ -145,4 +145,10 @@ open class ProxyApiDelegate: InteractiveMediaAdsLibraryPigeonProxyApiDelegate { return PigeonApiIMACompanionDelegate( pigeonRegistrar: registrar, delegate: CompanionDelegateProxyAPIDelegate()) } + + func pigeonApiIMAAdPodInfo(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar) + -> PigeonApiIMAAdPodInfo + { + return PigeonApiIMAAdPodInfo(pigeonRegistrar: registrar, delegate: AdPodInfoProxyAPIDelegate()) + } } diff --git a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart index 5add90505e9..f37cfb166f9 100644 --- a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart +++ b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart @@ -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.6.2), do not edit directly. +// Autogenerated from Pigeon (v22.7.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 @@ -176,6 +176,8 @@ class PigeonInstanceManager { pigeon_instanceManager: instanceManager); IMACompanionDelegate.pigeon_setUpMessageHandlers( pigeon_instanceManager: instanceManager); + IMAAdPodInfo.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); return instanceManager; } @@ -4200,3 +4202,165 @@ class IMACompanionDelegate extends NSObject { ); } } + +/// Simple data object containing podding metadata. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdPodInfo.html. +class IMAAdPodInfo extends PigeonInternalProxyApiBaseClass { + /// Constructs [IMAAdPodInfo] 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 + IMAAdPodInfo.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.adPosition, + required this.maxDuration, + required this.podIndex, + required this.timeOffset, + required this.totalAds, + required this.isBumper, + }); + + /// The position of this ad within an ad pod. + /// + /// Will be 1 for standalone ads. + final int adPosition; + + /// The maximum duration of the pod in seconds. + /// + /// For unknown duration, -1 is returned. + final double maxDuration; + + /// Returns the index of the ad pod. + /// + /// Client side: For a preroll pod, returns 0. For midrolls, returns 1, 2,…, + /// N. For a postroll pod, returns -1. Defaults to 0 if this ad is not part of + /// a pod, or this pod is not part of a playlist. + /// + /// DAI VOD: Returns the index of the ad pod. For a preroll pod, returns 0. + /// For midrolls, returns 1, 2,…,N. For a postroll pod, returns N+1…N+X. + /// Defaults to 0 if this ad is not part of a pod, or this pod is not part of + /// a playlist. + /// + /// DAI live stream: For a preroll pod, returns 0. For midrolls, returns the + /// break ID. Returns -2 if pod index cannot be determined (internal error). + final int podIndex; + + /// The position of the pod in the content in seconds. + /// + /// Pre-roll returns 0, post-roll returns -1 and mid-rolls return the + /// scheduled time of the pod. + final double timeOffset; + + /// Total number of ads in the pod this ad belongs to. + /// + /// Will be 1 for standalone ads. + final int totalAds; + + /// Specifies whether the ad is a bumper. + /// + /// Bumpers are short videos used to open and close ad breaks. + final bool isBumper; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + IMAAdPodInfo Function( + int adPosition, + double maxDuration, + int podIndex, + double timeOffset, + int totalAds, + bool isBumper, + )? 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.IMAAdPodInfo.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.IMAAdPodInfo.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.IMAAdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final int? arg_adPosition = (args[1] as int?); + assert(arg_adPosition != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final double? arg_maxDuration = (args[2] as double?); + assert(arg_maxDuration != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance was null, expected non-null double.'); + final int? arg_podIndex = (args[3] as int?); + assert(arg_podIndex != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final double? arg_timeOffset = (args[4] as double?); + assert(arg_timeOffset != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance was null, expected non-null double.'); + final int? arg_totalAds = (args[5] as int?); + assert(arg_totalAds != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance was null, expected non-null int.'); + final bool? arg_isBumper = (args[6] as bool?); + assert(arg_isBumper != null, + 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance was null, expected non-null bool.'); + try { + (pigeon_instanceManager ?? PigeonInstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_adPosition!, + arg_maxDuration!, + arg_podIndex!, + arg_timeOffset!, + arg_totalAds!, + arg_isBumper!) ?? + IMAAdPodInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adPosition: arg_adPosition!, + maxDuration: arg_maxDuration!, + podIndex: arg_podIndex!, + timeOffset: arg_timeOffset!, + totalAds: arg_totalAds!, + isBumper: arg_isBumper!, + ), + 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 + IMAAdPodInfo pigeon_copy() { + return IMAAdPodInfo.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + adPosition: adPosition, + maxDuration: maxDuration, + podIndex: podIndex, + timeOffset: timeOffset, + totalAds: totalAds, + isBumper: isBumper, + ); + } +} diff --git a/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart b/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart index 445b87b4874..ef6a30f4ad3 100644 --- a/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart +++ b/packages/interactive_media_ads/pigeons/interactive_media_ads_ios.dart @@ -673,3 +673,52 @@ abstract class IMACompanionDelegate extends NSObject { /// navigate away. late void Function(IMACompanionAdSlot slot)? companionSlotWasClicked; } + +/// Simple data object containing podding metadata. +/// +/// See https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdPodInfo.html. +@ProxyApi( + swiftOptions: SwiftProxyApiOptions(import: 'GoogleInteractiveMediaAds'), +) +abstract class IMAAdPodInfo { + /// The position of this ad within an ad pod. + /// + /// Will be 1 for standalone ads. + late final int adPosition; + + /// The maximum duration of the pod in seconds. + /// + /// For unknown duration, -1 is returned. + late final double maxDuration; + + /// Returns the index of the ad pod. + /// + /// Client side: For a preroll pod, returns 0. For midrolls, returns 1, 2,…, + /// N. For a postroll pod, returns -1. Defaults to 0 if this ad is not part of + /// a pod, or this pod is not part of a playlist. + /// + /// DAI VOD: Returns the index of the ad pod. For a preroll pod, returns 0. + /// For midrolls, returns 1, 2,…,N. For a postroll pod, returns N+1…N+X. + /// Defaults to 0 if this ad is not part of a pod, or this pod is not part of + /// a playlist. + /// + /// DAI live stream: For a preroll pod, returns 0. For midrolls, returns the + /// break ID. Returns -2 if pod index cannot be determined (internal error). + late final int podIndex; + + /// The position of the pod in the content in seconds. + /// + /// Pre-roll returns 0, post-roll returns -1 and mid-rolls return the + /// scheduled time of the pod. + late final double timeOffset; + + /// Total number of ads in the pod this ad belongs to. + /// + /// Will be 1 for standalone ads. + late final int totalAds; + + /// Specifies whether the ad is a bumper. + /// + /// Bumpers are short videos used to open and close ad breaks. + late final bool isBumper; +} diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml index bcf59fdb963..2457ce393ff 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.3+5 # This must match the version in +version: 0.2.3+6 # 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.6.2 + pigeon: ^22.7.2 topics: - ads