Skip to content

Commit 1d6c266

Browse files
[interactive_media_ads] Adds support for accessing data for an Ad (#9972)
## Pre-Review Checklist **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 16f88c3 commit 1d6c266

25 files changed

+1568
-37
lines changed

packages/interactive_media_ads/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.2.8
2+
3+
* Adds support for accessing data for an ad. See `AdEvent.ad`.
4+
15
## 0.2.7
26

37
* Adds support to retrieve content time offsets at which ad breaks are scheduled. See

packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class AdsRequestProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) :
2121
*
2222
* This must match the version in pubspec.yaml.
2323
*/
24-
const val pluginVersion = "0.2.7"
24+
const val pluginVersion = "0.2.8"
2525
}
2626

2727
override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {

packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/InteractiveMediaAdsLibrary.g.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5839,7 +5839,7 @@ abstract class PigeonApiCompanionAd(
58395839
/** The URL for the static resource of this companion. */
58405840
abstract fun resourceValue(
58415841
pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd
5842-
): String
5842+
): String?
58435843

58445844
/**
58455845
* The width of the companion in pixels.

packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class AdsRequestProxyAPIDelegate: PigeonApiDelegateIMAAdsRequest {
1313
/// The current version of the `interactive_media_ads` plugin.
1414
///
1515
/// This must match the version in pubspec.yaml.
16-
static let pluginVersion = "0.2.7"
16+
static let pluginVersion = "0.2.8"
1717

1818
func pigeonDefaultConstructor(
1919
pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer,

packages/interactive_media_ads/lib/interactive_media_ads.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
export 'src/ad.dart';
56
export 'src/ad_display_container.dart';
67
export 'src/ads_loader.dart';
78
export 'src/ads_manager_delegate.dart';
@@ -19,7 +20,6 @@ export 'src/platform_interface/platform_interface.dart'
1920
AdErrorCode,
2021
AdErrorEvent,
2122
AdErrorType,
22-
AdEvent,
2323
AdEventType,
2424
AdUIElement,
2525
AdsLoadErrorData,
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Copyright 2013 The Flutter Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'platform_interface/platform_interface.dart';
6+
7+
/// Data object representing a single ad.
8+
class Ad {
9+
/// Constructs an [Ad] from a specific platform implementation.
10+
Ad.fromPlatform(this.platform);
11+
12+
/// Implementation of [PlatformAd] for the current platform.
13+
final PlatformAd platform;
14+
15+
/// The ad ID as specified in the VAST response.
16+
String get adId => platform.adId;
17+
18+
/// The pod metadata object.
19+
AdPodInfo get adPodInfo => AdPodInfo.fromPlatform(platform.adPodInfo);
20+
21+
/// The ad system as specified in the VAST response.
22+
String get adSystem => platform.adSystem;
23+
24+
/// The IDs of the ads' creatives, starting with the first wrapper ad.
25+
List<String> get wrapperCreativeIds => platform.wrapperCreativeIds;
26+
27+
/// The wrapper ad IDs as specified in the VAST response.
28+
List<String> get wrapperIds => platform.wrapperIds;
29+
30+
/// The wrapper ad systems as specified in the VAST response.
31+
List<String> get wrapperSystems => platform.wrapperSystems;
32+
33+
/// The advertiser name as defined by the serving party.
34+
String get advertiserName => platform.advertiserName;
35+
36+
/// The companions for the current ad while using DAI.
37+
///
38+
/// Returns an empty list in any other scenario.
39+
List<CompanionAd> get companionAds => List<CompanionAd>.unmodifiable(
40+
platform.companionAds.map(CompanionAd.fromPlatform),
41+
);
42+
43+
/// The content type of the currently selected creative, or null if no
44+
/// creative is selected or the content type is unavailable.
45+
String? get contentType => platform.contentType;
46+
47+
/// The ISCI (Industry Standard Commercial Identifier) code for an ad.
48+
String get creativeAdId => platform.creativeAdId;
49+
50+
/// The ID of the selected creative for the ad,
51+
String get creativeId => platform.creativeId;
52+
53+
/// The first deal ID present in the wrapper chain for the current ad,
54+
/// starting from the top.
55+
String get dealId => platform.dealId;
56+
57+
/// The description of this ad from the VAST response.
58+
String? get description => platform.description;
59+
60+
/// The duration of the ad.
61+
Duration? get duration => platform.duration;
62+
63+
/// The width of the selected creative if non-linear, else returns 0.
64+
int get width => platform.width;
65+
66+
/// The height of the selected creative if non-linear, else returns 0.
67+
int get height => platform.height;
68+
69+
/// The playback time before the ad becomes skippable.
70+
///
71+
/// The value is null for non-skippable ads, or if the value is unavailable.
72+
Duration? get skipTimeOffset => platform.skipTimeOffset;
73+
74+
/// The URL associated with the survey for the given ad.
75+
String? get surveyUrl => platform.surveyUrl;
76+
77+
/// The title of this ad from the VAST response.
78+
String? get title => platform.title;
79+
80+
/// The custom parameters associated with the ad at the time of ad
81+
/// trafficking.
82+
String get traffickingParameters => platform.traffickingParameters;
83+
84+
/// The set of ad UI elements rendered by the IMA SDK for this ad.
85+
Set<AdUIElement> get uiElements => platform.uiElements;
86+
87+
/// The list of all universal ad IDs for this ad.
88+
List<UniversalAdId> get universalAdIds => List<UniversalAdId>.unmodifiable(
89+
platform.universalAdIds.map(UniversalAdId.fromPlatform),
90+
);
91+
92+
/// The VAST bitrate in Kbps of the selected creative.
93+
int get vastMediaBitrate => platform.vastMediaBitrate;
94+
95+
/// The VAST media height in pixels of the selected creative.
96+
int get vastMediaHeight => platform.vastMediaHeight;
97+
98+
/// The VAST media width in pixels of the selected creative.
99+
int get vastMediaWidth => platform.vastMediaWidth;
100+
101+
/// Indicates whether the ad’s current mode of operation is linear or
102+
/// non-linear.
103+
bool get isLinear => platform.isLinear;
104+
105+
/// Indicates whether the ad can be skipped by the user.
106+
bool get isSkippable => platform.isSkippable;
107+
}
108+
109+
/// Simple data object containing podding metadata.
110+
class AdPodInfo {
111+
/// Constructs an [AdPodInfo] from a specific platform implementation.
112+
AdPodInfo.fromPlatform(this.platform);
113+
114+
/// Implementation of [PlatformAdPodInfo] for the current platform.
115+
final PlatformAdPodInfo platform;
116+
117+
/// The position of the ad within the pod.
118+
///
119+
/// The value returned is one-based, for example, 1 of 2, 2 of 2, etc. If the
120+
/// ad is not part of a pod, this will return 1.
121+
int get adPosition => platform.adPosition;
122+
123+
/// The maximum duration of the pod.
124+
///
125+
/// For unknown duration, null.
126+
Duration? get maxDuration => platform.maxDuration;
127+
128+
/// Returns the index of the ad pod.
129+
///
130+
/// Client side: For a preroll pod, returns 0. For midrolls, returns 1, 2,…,
131+
/// N. For a postroll pod, returns -1. Defaults to 0 if this ad is not part of
132+
/// a pod, or this pod is not part of a playlist.
133+
///
134+
/// DAI VOD: Returns the index of the ad pod. For a preroll pod, returns 0.
135+
/// For midrolls, returns 1, 2,…,N. For a postroll pod, returns N+1…N+X.
136+
/// Defaults to 0 if this ad is not part of a pod, or this pod is not part of
137+
/// a playlist.
138+
///
139+
/// DAI live stream: For a preroll pod, returns 0. For midrolls, returns the
140+
/// break ID. Returns -2 if pod index cannot be determined (internal error).
141+
int get podIndex => platform.podIndex;
142+
143+
/// The content time offset at which the current ad pod was scheduled.
144+
///
145+
/// For preroll pod, 0 is returned. For midrolls, the scheduled time is
146+
/// returned. For postroll, -1 is returned. Defaults to 0 if this ad is not
147+
/// part of a pod, or the pod is not part of an ad playlist.
148+
Duration get timeOffset => platform.timeOffset;
149+
150+
/// Total number of ads in the pod this ad belongs to, including bumpers.
151+
///
152+
/// Will be 1 for standalone ads.
153+
int get totalAds => platform.totalAds;
154+
155+
/// Specifies whether the ad is a bumper.
156+
///
157+
/// Bumpers are short videos used to open and close ad breaks.
158+
bool get isBumper => platform.isBumper;
159+
}
160+
161+
/// An object that holds data corresponding to the companion Ad.
162+
class CompanionAd {
163+
/// Constructs a [CompanionAd] from a specific platform implementation.
164+
CompanionAd.fromPlatform(this.platform);
165+
166+
/// Implementation of [PlatformCompanionAd] for the current platform.
167+
final PlatformCompanionAd platform;
168+
169+
/// The width of the companion in pixels.
170+
///
171+
/// `null` if unavailable.
172+
int? get width => platform.width;
173+
174+
/// The height of the companion in pixels.
175+
///
176+
/// `null` if unavailable.
177+
int? get height => platform.height;
178+
179+
/// The API needed to execute this ad, or null if unavailable.
180+
String? get apiFramework => platform.apiFramework;
181+
182+
/// The URL for the static resource of this companion.
183+
String? get resourceValue => platform.resourceValue;
184+
}
185+
186+
/// Simple data object containing universal ad ID information.
187+
class UniversalAdId {
188+
/// Constructs an [UniversalAdId] from a specific platform implementation.
189+
UniversalAdId.fromPlatform(this.platform);
190+
191+
/// Implementation of [PlatformUniversalAdId] for the current platform.
192+
final PlatformUniversalAdId platform;
193+
194+
/// The universal ad ID value.
195+
///
196+
/// This will be null if it isn’t defined by the ad.
197+
String? get adIdValue => platform.adIdValue;
198+
199+
/// The universal ad ID registry with which the value is registered.
200+
///
201+
/// This will be null if it isn’t defined by the ad.
202+
String? get adIdRegistry => platform.adIdRegistry;
203+
}

packages/interactive_media_ads/lib/src/ads_manager_delegate.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'ad.dart';
56
import 'platform_interface/platform_interface.dart';
67

78
/// Delegate for ad events or errors that occur during ad or stream
@@ -37,7 +38,9 @@ class AdsManagerDelegate {
3738
void Function(AdErrorEvent event)? onAdErrorEvent,
3839
}) : this.fromPlatformCreationParams(
3940
PlatformAdsManagerDelegateCreationParams(
40-
onAdEvent: onAdEvent,
41+
onAdEvent:
42+
(PlatformAdEvent event) =>
43+
onAdEvent?.call(AdEvent._fromPlatform(event)),
4144
onAdErrorEvent: onAdErrorEvent,
4245
),
4346
);
@@ -80,10 +83,28 @@ class AdsManagerDelegate {
8083
final PlatformAdsManagerDelegate platform;
8184

8285
/// Invoked when there is an [AdEvent].
83-
void Function(AdEvent event)? get onAdEvent => platform.params.onAdEvent;
86+
void Function(AdEvent event)? get onAdEvent =>
87+
(AdEvent event) => platform.params.onAdEvent?.call(event.platform);
8488

8589
/// Invoked when there was an error playing the ad. Log the error and resume
8690
/// playing content.
8791
void Function(AdErrorEvent event)? get onAdErrorEvent =>
8892
platform.params.onAdErrorEvent;
8993
}
94+
95+
/// Simple data class used to transport ad playback information.
96+
class AdEvent {
97+
AdEvent._fromPlatform(this.platform);
98+
99+
/// Implementation of [PlatformAdEvent] for the current platform.
100+
final PlatformAdEvent platform;
101+
102+
/// The type of event that occurred.
103+
AdEventType get type => platform.type;
104+
105+
/// The ad with which this event is associated.
106+
Ad? get ad => platform.ad != null ? Ad.fromPlatform(platform.ad!) : null;
107+
108+
/// A map containing any extra ad data for the event, if needed.
109+
Map<String, String> get adData => platform.adData;
110+
}

0 commit comments

Comments
 (0)