Skip to content

Commit 28c35c6

Browse files
[interactive_media_ads]: Adds additional methods to configure ad requests (#9696)
## 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 1a72287 commit 28c35c6

File tree

13 files changed

+630
-40
lines changed

13 files changed

+630
-40
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.6
2+
3+
* Adds support to configure ad requests. See `AdsRequest`.
4+
15
## 0.2.5+1
26

37
* Adds remaining methods for internal wrapper of the Android native `AdsRequest`.

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.5+1"
24+
const val pluginVersion = "0.2.6"
2525
}
2626

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

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.5+1"
16+
static let pluginVersion = "0.2.6"
1717

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

packages/interactive_media_ads/lib/src/ads_request.dart

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,57 @@ import 'platform_interface/platform_interface.dart';
77

88
/// An object containing the data used to request ads from the server.
99
class AdsRequest {
10-
/// Creates an [AdsRequest].
10+
/// Creates an [AdsRequest] with the given ad tag URL.
1111
AdsRequest({
1212
required String adTagUrl,
1313
ContentProgressProvider? contentProgressProvider,
14+
bool? adWillAutoPlay,
15+
bool? adWillPlayMuted,
16+
bool? continuousPlayback,
17+
Duration? contentDuration,
18+
List<String>? contentKeywords,
19+
String? contentTitle,
20+
Duration? liveStreamPrefetchMaxWaitTime,
21+
Duration? vastLoadTimeout,
1422
}) : this.fromPlatform(
15-
PlatformAdsRequest(
23+
PlatformAdsRequest.withAdTagUrl(
1624
adTagUrl: adTagUrl,
1725
contentProgressProvider: contentProgressProvider?.platform,
26+
adWillAutoPlay: adWillAutoPlay,
27+
adWillPlayMuted: adWillPlayMuted,
28+
continuousPlayback: continuousPlayback,
29+
contentDuration: contentDuration,
30+
contentKeywords: contentKeywords,
31+
contentTitle: contentTitle,
32+
liveStreamPrefetchMaxWaitTime: liveStreamPrefetchMaxWaitTime,
33+
vastLoadTimeout: vastLoadTimeout,
34+
),
35+
);
36+
37+
/// Creates an [AdsRequest] with the given canned ads response.
38+
AdsRequest.withAdsResponse({
39+
required String adsResponse,
40+
ContentProgressProvider? contentProgressProvider,
41+
bool? adWillAutoPlay,
42+
bool? adWillPlayMuted,
43+
bool? continuousPlayback,
44+
Duration? contentDuration,
45+
List<String>? contentKeywords,
46+
String? contentTitle,
47+
Duration? liveStreamPrefetchMaxWaitTime,
48+
Duration? vastLoadTimeout,
49+
}) : this.fromPlatform(
50+
PlatformAdsRequest.withAdsResponse(
51+
adsResponse: adsResponse,
52+
contentProgressProvider: contentProgressProvider?.platform,
53+
adWillAutoPlay: adWillAutoPlay,
54+
adWillPlayMuted: adWillPlayMuted,
55+
continuousPlayback: continuousPlayback,
56+
contentDuration: contentDuration,
57+
contentKeywords: contentKeywords,
58+
contentTitle: contentTitle,
59+
liveStreamPrefetchMaxWaitTime: liveStreamPrefetchMaxWaitTime,
60+
vastLoadTimeout: vastLoadTimeout,
1861
),
1962
);
2063

@@ -25,7 +68,20 @@ class AdsRequest {
2568
final PlatformAdsRequest platform;
2669

2770
/// The URL from which ads will be requested.
28-
String get adTagUrl => platform.adTagUrl;
71+
String get adTagUrl => switch (platform) {
72+
final PlatformAdsRequestWithAdTagUrl request => request.adTagUrl,
73+
// TODO(bparrishMines): This returns an empty string rather than null
74+
// to prevent a breaking change. This should be updated to return null
75+
// on the next major release.
76+
PlatformAdsRequestWithAdsResponse() => '',
77+
};
78+
79+
/// Specifies a VAST, VMAP, or ad rules response to be used instead of making
80+
/// a request through an ad tag URL.
81+
String? get adsResponse => switch (platform) {
82+
final PlatformAdsRequestWithAdsResponse request => request.adsResponse,
83+
PlatformAdsRequestWithAdTagUrl() => null,
84+
};
2985

3086
/// A [ContentProgressProvider] instance to allow scheduling of ad breaks
3187
/// based on content progress (cue points).
@@ -34,4 +90,33 @@ class AdsRequest {
3490
null
3591
? ContentProgressProvider.fromPlatform(platform.contentProgressProvider!)
3692
: null;
93+
94+
/// Notifies the SDK whether the player intends to start the content and ad in
95+
/// response to a user action or whether it will be automatically played.
96+
bool? get adWillAutoPlay => platform.adWillAutoPlay;
97+
98+
/// Notifies the SDK whether the player intends to start the content and ad
99+
/// while muted.
100+
bool? get adWillPlayMuted => platform.adWillPlayMuted;
101+
102+
/// Notifies the SDK whether the player intends to continuously play the
103+
/// content videos one after another similar to TV broadcast.
104+
bool? get continuousPlayback => platform.continuousPlayback;
105+
106+
/// Specifies the duration of the content to be shown.
107+
Duration? get contentDuration => platform.contentDuration;
108+
109+
/// Specifies the keywords used to describe the content to be shown.
110+
List<String>? get contentKeywords => platform.contentKeywords;
111+
112+
/// Specifies the title of the content to be shown.
113+
String? get contentTitle => platform.contentTitle;
114+
115+
/// Specifies the maximum amount of time to wait, after calling requestAds,
116+
/// before requesting the ad tag URL.
117+
Duration? get liveStreamPrefetchMaxWaitTime =>
118+
platform.liveStreamPrefetchMaxWaitTime;
119+
120+
/// Specifies the VAST load timeout in milliseconds for a single wrapper.
121+
Duration? get vastLoadTimeout => platform.vastLoadTimeout;
37122
}

packages/interactive_media_ads/lib/src/android/android_ads_loader.dart

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,36 @@ base class AndroidAdsLoader extends PlatformAdsLoader {
8989
final ima.AdsRequest androidRequest = await _sdkFactory.createAdsRequest();
9090

9191
await Future.wait(<Future<void>>[
92-
androidRequest.setAdTagUrl(request.adTagUrl),
93-
if (request.contentProgressProvider != null)
92+
if (request case final PlatformAdsRequestWithAdTagUrl request)
93+
androidRequest.setAdTagUrl(request.adTagUrl),
94+
if (request case final PlatformAdsRequestWithAdsResponse request)
95+
androidRequest.setAdTagUrl(request.adsResponse),
96+
if (request.adWillAutoPlay case final bool adWillAutoPlay)
97+
androidRequest.setAdWillAutoPlay(adWillAutoPlay),
98+
if (request.adWillPlayMuted case final bool adWillPlayMuted)
99+
androidRequest.setAdWillPlayMuted(adWillPlayMuted),
100+
if (request.continuousPlayback case final bool continuousPlayback)
101+
androidRequest.setContinuousPlayback(continuousPlayback),
102+
if (request.contentDuration case final Duration contentDuration)
103+
androidRequest.setContentDuration(
104+
contentDuration.inMilliseconds / Duration.millisecondsPerSecond),
105+
if (request.contentKeywords case final List<String> contentKeywords)
106+
androidRequest.setContentKeywords(contentKeywords),
107+
if (request.contentTitle case final String contentTitle)
108+
androidRequest.setContentTitle(contentTitle),
109+
if (request.liveStreamPrefetchMaxWaitTime
110+
case final Duration liveStreamPrefetchMaxWaitTime)
111+
androidRequest.setLiveStreamPrefetchSeconds(
112+
liveStreamPrefetchMaxWaitTime.inMilliseconds /
113+
Duration.millisecondsPerSecond,
114+
),
115+
if (request.vastLoadTimeout case final Duration vastLoadTimeout)
116+
androidRequest
117+
.setVastLoadTimeout(vastLoadTimeout.inMilliseconds.toDouble()),
118+
if (request.contentProgressProvider
119+
case final PlatformContentProgressProvider contentProgressProvider)
94120
androidRequest.setContentProgressProvider(
95-
(request.contentProgressProvider! as AndroidContentProgressProvider)
121+
(contentProgressProvider as AndroidContentProgressProvider)
96122
.progressProvider,
97123
),
98124
adsLoader.requestAds(androidRequest),

packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,55 @@ base class IOSAdsLoader extends PlatformAdsLoader {
7373
}
7474

7575
@override
76-
Future<void> requestAds(PlatformAdsRequest request) async {
77-
return _adsLoader.requestAds(_iosParams._proxy.newIMAAdsRequest(
78-
adTagUrl: request.adTagUrl,
79-
adDisplayContainer:
80-
(_iosParams.container as IOSAdDisplayContainer).adDisplayContainer!,
81-
contentPlayhead: request.contentProgressProvider != null
82-
? (request.contentProgressProvider! as IOSContentProgressProvider)
83-
.contentPlayhead
84-
: null,
85-
));
76+
Future<void> requestAds(PlatformAdsRequest request) {
77+
final IMAAdDisplayContainer adDisplayContainer =
78+
(_iosParams.container as IOSAdDisplayContainer).adDisplayContainer!;
79+
final IMAContentPlayhead? contentProgressProvider =
80+
request.contentProgressProvider != null
81+
? (request.contentProgressProvider! as IOSContentProgressProvider)
82+
.contentPlayhead
83+
: null;
84+
85+
final IMAAdsRequest adsRequest = switch (request) {
86+
final PlatformAdsRequestWithAdTagUrl request => IMAAdsRequest(
87+
adTagUrl: request.adTagUrl,
88+
adDisplayContainer: adDisplayContainer,
89+
contentPlayhead: contentProgressProvider,
90+
),
91+
PlatformAdsRequestWithAdsResponse() => IMAAdsRequest.withAdsResponse(
92+
adsResponse: request.adsResponse,
93+
adDisplayContainer: adDisplayContainer,
94+
contentPlayhead: contentProgressProvider,
95+
),
96+
};
97+
98+
return Future.wait(<Future<void>>[
99+
if (request.adWillAutoPlay case final bool adWillAutoPlay)
100+
adsRequest.setAdWillAutoPlay(adWillAutoPlay),
101+
if (request.adWillPlayMuted case final bool adWillPlayMuted)
102+
adsRequest.setAdWillPlayMuted(adWillPlayMuted),
103+
if (request.continuousPlayback case final bool continuousPlayback)
104+
adsRequest.setContinuousPlayback(continuousPlayback),
105+
if (request.contentDuration case final Duration contentDuration)
106+
adsRequest.setContentDuration(
107+
contentDuration.inMilliseconds / Duration.millisecondsPerSecond,
108+
),
109+
if (request.contentKeywords case final List<String> contentKeywords)
110+
adsRequest.setContentKeywords(contentKeywords),
111+
if (request.contentTitle case final String contentTitle)
112+
adsRequest.setContentTitle(contentTitle),
113+
if (request.liveStreamPrefetchMaxWaitTime
114+
case final Duration liveStreamPrefetchMaxWaitTime)
115+
adsRequest.setLiveStreamPrefetchSeconds(
116+
liveStreamPrefetchMaxWaitTime.inMilliseconds /
117+
Duration.millisecondsPerSecond,
118+
),
119+
if (request.vastLoadTimeout case final Duration vastLoadTimeout)
120+
adsRequest.setVastLoadTimeout(
121+
vastLoadTimeout.inMilliseconds.toDouble(),
122+
),
123+
_adsLoader.requestAds(adsRequest),
124+
]);
86125
}
87126

88127
// This value is created in a static method because the callback methods for

packages/interactive_media_ads/lib/src/platform_interface/platform_ads_request.dart

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,143 @@
55
import 'platform_content_progress_provider.dart';
66

77
/// An object containing the data used to request ads from the server.
8-
class PlatformAdsRequest {
9-
/// Creates an [PlatformAdsRequest].
10-
PlatformAdsRequest({
11-
required this.adTagUrl,
8+
sealed class PlatformAdsRequest {
9+
PlatformAdsRequest._({
1210
this.contentProgressProvider,
11+
this.adWillAutoPlay,
12+
this.adWillPlayMuted,
13+
this.continuousPlayback,
14+
this.contentDuration,
15+
this.contentKeywords,
16+
this.contentTitle,
17+
this.liveStreamPrefetchMaxWaitTime,
18+
this.vastLoadTimeout,
1319
});
1420

15-
/// The URL from which ads will be requested.
16-
final String adTagUrl;
21+
/// Creates a [PlatformAdsRequest] with the given ad tag URL.
22+
factory PlatformAdsRequest.withAdTagUrl({
23+
required String adTagUrl,
24+
PlatformContentProgressProvider? contentProgressProvider,
25+
bool? adWillAutoPlay,
26+
bool? adWillPlayMuted,
27+
bool? continuousPlayback,
28+
Duration? contentDuration,
29+
List<String>? contentKeywords,
30+
String? contentTitle,
31+
Duration? liveStreamPrefetchMaxWaitTime,
32+
Duration? vastLoadTimeout,
33+
}) =>
34+
PlatformAdsRequestWithAdTagUrl._(
35+
adTagUrl: adTagUrl,
36+
contentProgressProvider: contentProgressProvider,
37+
adWillAutoPlay: adWillAutoPlay,
38+
adWillPlayMuted: adWillPlayMuted,
39+
continuousPlayback: continuousPlayback,
40+
contentDuration: contentDuration,
41+
contentKeywords: contentKeywords,
42+
contentTitle: contentTitle,
43+
liveStreamPrefetchMaxWaitTime: liveStreamPrefetchMaxWaitTime,
44+
vastLoadTimeout: vastLoadTimeout,
45+
);
46+
47+
/// Creates a [PlatformAdsRequest] with the given canned ads response.
48+
factory PlatformAdsRequest.withAdsResponse({
49+
required String adsResponse,
50+
PlatformContentProgressProvider? contentProgressProvider,
51+
bool? adWillAutoPlay,
52+
bool? adWillPlayMuted,
53+
bool? continuousPlayback,
54+
Duration? contentDuration,
55+
List<String>? contentKeywords,
56+
String? contentTitle,
57+
Duration? liveStreamPrefetchMaxWaitTime,
58+
Duration? vastLoadTimeout,
59+
}) =>
60+
PlatformAdsRequestWithAdsResponse._(
61+
adsResponse: adsResponse,
62+
contentProgressProvider: contentProgressProvider,
63+
adWillAutoPlay: adWillAutoPlay,
64+
adWillPlayMuted: adWillPlayMuted,
65+
continuousPlayback: continuousPlayback,
66+
contentDuration: contentDuration,
67+
contentKeywords: contentKeywords,
68+
contentTitle: contentTitle,
69+
liveStreamPrefetchMaxWaitTime: liveStreamPrefetchMaxWaitTime,
70+
vastLoadTimeout: vastLoadTimeout,
71+
);
1772

1873
/// A [PlatformContentProgressProvider] instance to allow scheduling of ad
1974
/// breaks based on content progress (cue points).
2075
final PlatformContentProgressProvider? contentProgressProvider;
76+
77+
/// Notifies the SDK whether the player intends to start the content and ad in
78+
/// response to a user action or whether it will be automatically played.
79+
final bool? adWillAutoPlay;
80+
81+
/// Notifies the SDK whether the player intends to start the content and ad
82+
/// while muted.
83+
final bool? adWillPlayMuted;
84+
85+
/// Notifies the SDK whether the player intends to continuously play the
86+
/// content videos one after another similar to TV broadcast.
87+
final bool? continuousPlayback;
88+
89+
/// Specifies the duration of the content to be shown.
90+
final Duration? contentDuration;
91+
92+
/// Specifies the keywords used to describe the content to be shown.
93+
final List<String>? contentKeywords;
94+
95+
/// Specifies the title of the content to be shown.
96+
final String? contentTitle;
97+
98+
/// Specifies the maximum amount of time to wait, after calling requestAds,
99+
/// before requesting the ad tag URL.
100+
final Duration? liveStreamPrefetchMaxWaitTime;
101+
102+
/// Specifies the VAST load timeout for a single wrapper.
103+
final Duration? vastLoadTimeout;
104+
}
105+
106+
/// An object containing the data used to request ads from the server with an
107+
/// ad tag URL.
108+
base class PlatformAdsRequestWithAdTagUrl extends PlatformAdsRequest {
109+
/// Constructs a [PlatformAdsRequestWithAdTagUrl].
110+
PlatformAdsRequestWithAdTagUrl._({
111+
required this.adTagUrl,
112+
super.contentProgressProvider,
113+
super.adWillAutoPlay,
114+
super.adWillPlayMuted,
115+
super.continuousPlayback,
116+
super.contentDuration,
117+
super.contentKeywords,
118+
super.contentTitle,
119+
super.liveStreamPrefetchMaxWaitTime,
120+
super.vastLoadTimeout,
121+
}) : super._();
122+
123+
/// The URL from which ads will be requested.
124+
final String adTagUrl;
125+
}
126+
127+
/// An object containing the data used to request ads from the server with an
128+
/// ad rules response.
129+
base class PlatformAdsRequestWithAdsResponse extends PlatformAdsRequest {
130+
/// Constructs a [PlatformAdsRequestWithAdsResponse].
131+
PlatformAdsRequestWithAdsResponse._({
132+
required this.adsResponse,
133+
super.contentProgressProvider,
134+
super.adWillAutoPlay,
135+
super.adWillPlayMuted,
136+
super.continuousPlayback,
137+
super.contentDuration,
138+
super.contentKeywords,
139+
super.contentTitle,
140+
super.liveStreamPrefetchMaxWaitTime,
141+
super.vastLoadTimeout,
142+
}) : super._();
143+
144+
/// Specifies a VAST, VMAP, or ad rules response to be used instead of making
145+
/// a request through an ad tag URL.
146+
final String adsResponse;
21147
}

0 commit comments

Comments
 (0)