Skip to content

Commit 766ef91

Browse files
committed
Allow serving Custom ads in AdLoaderAd
Allow the `AdLoaderAd` instance to serve `Custom` ads, which are instances of: * `NativeCustomFormatAd` under Android, and * `GADCustomNativeAd` under iOS
1 parent e4c1a94 commit 766ef91

21 files changed

Lines changed: 691 additions & 18 deletions

packages/google_mobile_ads/android/src/main/java/io/flutter/plugins/googlemobileads/AdMessageCodec.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class AdMessageCodec extends StandardMessageCodec {
6767
private static final byte VALUE_COLOR = (byte) 153;
6868
private static final byte VALUE_AD_MANAGER_AD_VIEW_OPTIONS = (byte) 154;
6969
private static final byte VALUE_BANNER_PARAMETERS = (byte) 155;
70+
private static final byte VALUE_CUSTOM_PARAMETERS = (byte) 156;
7071

7172
@NonNull Context context;
7273
@NonNull final FlutterAdSize.AdSizeFactory adSizeFactory;
@@ -253,6 +254,11 @@ protected void writeValue(ByteArrayOutputStream stream, Object value) {
253254
FlutterBannerParameters bannerParameters = (FlutterBannerParameters) value;
254255
writeValue(stream, bannerParameters.sizes);
255256
writeValue(stream, bannerParameters.adManagerAdViewOptions);
257+
} else if (value instanceof FlutterCustomParameters) {
258+
stream.write(VALUE_CUSTOM_PARAMETERS);
259+
FlutterCustomParameters customParameters = (FlutterCustomParameters) value;
260+
writeValue(stream, customParameters.formatIds);
261+
writeValue(stream, customParameters.viewOptions);
256262
} else {
257263
super.writeValue(stream, value);
258264
}
@@ -419,6 +425,10 @@ protected Object readValueOfType(byte type, ByteBuffer buffer) {
419425
return new FlutterBannerParameters(
420426
(List<FlutterAdSize>) readValueOfType(buffer.get(), buffer),
421427
(FlutterAdManagerAdViewOptions) readValueOfType(buffer.get(), buffer));
428+
case VALUE_CUSTOM_PARAMETERS:
429+
return new FlutterCustomParameters(
430+
(List<String>) readValueOfType(buffer.get(), buffer),
431+
(Map<String, Object>) readValueOfType(buffer.get(), buffer));
422432
default:
423433
return super.readValueOfType(type, buffer);
424434
}

packages/google_mobile_ads/android/src/main/java/io/flutter/plugins/googlemobileads/FlutterAdListener.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.google.android.gms.ads.formats.OnAdManagerAdViewLoadedListener;
2121
import com.google.android.gms.ads.nativead.NativeAd;
2222
import com.google.android.gms.ads.nativead.NativeAd.OnNativeAdLoadedListener;
23+
import com.google.android.gms.ads.nativead.NativeCustomFormatAd;
24+
import com.google.android.gms.ads.nativead.NativeCustomFormatAd.OnCustomFormatAdLoadedListener;
2325
import java.lang.ref.WeakReference;
2426

2527
/** Callback type to notify when an ad successfully loads. */
@@ -137,3 +139,20 @@ public void onAdManagerAdViewLoaded(AdManagerAdView adView) {
137139
}
138140
}
139141
}
142+
143+
/** {@link OnCustomFormatAdLoadedListener} for custom ads. */
144+
class FlutterCustomFormatAdLoadedListener implements OnCustomFormatAdLoadedListener {
145+
146+
private final WeakReference<OnCustomFormatAdLoadedListener> reference;
147+
148+
FlutterCustomFormatAdLoadedListener(OnCustomFormatAdLoadedListener listener) {
149+
reference = new WeakReference<>(listener);
150+
}
151+
152+
@Override
153+
public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
154+
if (reference.get() != null) {
155+
reference.get().onCustomFormatAdLoaded(ad);
156+
}
157+
}
158+
}

packages/google_mobile_ads/android/src/main/java/io/flutter/plugins/googlemobileads/FlutterAdLoader.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,20 @@ public void loadAdLoaderAd(
146146
@NonNull String adUnitId,
147147
@NonNull AdListener adListener,
148148
@NonNull AdRequest request,
149-
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters) {
149+
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters,
150+
@Nullable FlutterAdLoaderAd.CustomParameters customParameters) {
150151
AdLoader.Builder builder = new AdLoader.Builder(context, adUnitId);
151152
if (bannerParameters != null) {
152153
builder = builder.forAdManagerAdView(bannerParameters.listener, bannerParameters.adSizes);
153154
if (bannerParameters.adManagerAdViewOptions != null) {
154155
builder.withAdManagerAdViewOptions(bannerParameters.adManagerAdViewOptions);
155156
}
156157
}
158+
if (customParameters != null) {
159+
for (String formatId : customParameters.factories.keySet()) {
160+
builder = builder.forCustomFormatAd(formatId, customParameters.listener, null);
161+
}
162+
}
157163
builder.withAdListener(adListener).build().loadAd(request);
158164
}
159165

@@ -162,14 +168,20 @@ public void loadAdManagerAdLoaderAd(
162168
@NonNull String adUnitId,
163169
@NonNull AdListener adListener,
164170
@NonNull AdManagerAdRequest adManagerAdRequest,
165-
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters) {
171+
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters,
172+
@Nullable FlutterAdLoaderAd.CustomParameters customParameters) {
166173
AdLoader.Builder builder = new AdLoader.Builder(context, adUnitId);
167174
if (bannerParameters != null) {
168175
builder = builder.forAdManagerAdView(bannerParameters.listener, bannerParameters.adSizes);
169176
if (bannerParameters.adManagerAdViewOptions != null) {
170177
builder.withAdManagerAdViewOptions(bannerParameters.adManagerAdViewOptions);
171178
}
172179
}
180+
if (customParameters != null) {
181+
for (String formatId : customParameters.factories.keySet()) {
182+
builder = builder.forCustomFormatAd(formatId, customParameters.listener, null);
183+
}
184+
}
173185
builder.withAdListener(adListener).build().loadAd(adManagerAdRequest);
174186
}
175187
}

packages/google_mobile_ads/android/src/main/java/io/flutter/plugins/googlemobileads/FlutterAdLoaderAd.java

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@
2424
import com.google.android.gms.ads.admanager.AdManagerAdView;
2525
import com.google.android.gms.ads.formats.AdManagerAdViewOptions;
2626
import com.google.android.gms.ads.formats.OnAdManagerAdViewLoadedListener;
27+
import com.google.android.gms.ads.nativead.NativeCustomFormatAd;
28+
import com.google.android.gms.ads.nativead.NativeCustomFormatAd.OnCustomFormatAdLoadedListener;
2729
import io.flutter.plugin.platform.PlatformView;
30+
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.CustomAdFactory;
31+
import java.util.Map;
2832

2933
/**
3034
* A central wrapper for {@link AdManagerAdView}, {@link NativeCustomFormatAd} and {@link NativeAd}
3135
* instances served for a single {@link AdRequest} or {@link AdManagerAdRequest}
3236
*/
33-
class FlutterAdLoaderAd extends FlutterAd implements OnAdManagerAdViewLoadedListener {
37+
class FlutterAdLoaderAd extends FlutterAd
38+
implements OnAdManagerAdViewLoadedListener, OnCustomFormatAdLoadedListener {
3439
private static final String TAG = "FlutterAdLoaderAd";
3540

3641
@NonNull private final AdInstanceManager manager;
@@ -42,6 +47,7 @@ class FlutterAdLoaderAd extends FlutterAd implements OnAdManagerAdViewLoadedList
4247
@Nullable private String formatId;
4348
@Nullable private View view;
4449
@Nullable protected BannerParameters bannerParameters;
50+
@Nullable protected CustomParameters customParameters;
4551

4652
static class Builder {
4753
@Nullable private AdInstanceManager manager;
@@ -51,6 +57,8 @@ static class Builder {
5157
@Nullable private Integer id;
5258
@Nullable private FlutterAdLoader adLoader;
5359
@Nullable private FlutterBannerParameters bannerParameters;
60+
@Nullable private FlutterCustomParameters customParameters;
61+
@Nullable private Map<String, CustomAdFactory> customFactories;
5462

5563
public Builder setId(int id) {
5664
this.id = id;
@@ -87,6 +95,17 @@ public Builder setBanner(@Nullable FlutterBannerParameters bannerParameters) {
8795
return this;
8896
}
8997

98+
public Builder setCustom(@Nullable FlutterCustomParameters customParameters) {
99+
this.customParameters = customParameters;
100+
return this;
101+
}
102+
103+
public Builder withAvailableCustomFactories(
104+
@NonNull Map<String, CustomAdFactory> customFactories) {
105+
this.customFactories = customFactories;
106+
return this;
107+
}
108+
90109
FlutterAdLoaderAd build() {
91110
if (manager == null) {
92111
throw new IllegalStateException("manager must be provided");
@@ -114,13 +133,20 @@ FlutterAdLoaderAd build() {
114133
new FlutterAdManagerAdViewLoadedListener(adLoaderAd));
115134
}
116135

136+
if (customParameters != null) {
137+
adLoaderAd.customParameters =
138+
customParameters.asCustomParameters(
139+
new FlutterCustomFormatAdLoadedListener(adLoaderAd), customFactories);
140+
}
141+
117142
return adLoaderAd;
118143
}
119144
}
120145

121146
enum AdLoaderAdType {
122147
UNKNOWN,
123148
BANNER,
149+
CUSTOM,
124150
}
125151

126152
static class BannerParameters {
@@ -138,6 +164,21 @@ static class BannerParameters {
138164
}
139165
}
140166

167+
static class CustomParameters {
168+
@NonNull final OnCustomFormatAdLoadedListener listener;
169+
@NonNull final Map<String, CustomAdFactory> factories;
170+
@Nullable final Map<String, Object> viewOptions;
171+
172+
CustomParameters(
173+
@NonNull OnCustomFormatAdLoadedListener listener,
174+
@NonNull Map<String, CustomAdFactory> factories,
175+
@Nullable Map<String, Object> viewOptions) {
176+
this.listener = listener;
177+
this.factories = factories;
178+
this.viewOptions = viewOptions;
179+
}
180+
}
181+
141182
protected FlutterAdLoaderAd(
142183
int adId,
143184
@NonNull AdInstanceManager manager,
@@ -179,13 +220,17 @@ void load() {
179220
// As of 20.0.0 of GMA, mockito is unable to mock AdLoader.
180221
if (request != null) {
181222
adLoader.loadAdLoaderAd(
182-
adUnitId, adListener, request.asAdRequest(adUnitId), bannerParameters);
223+
adUnitId, adListener, request.asAdRequest(adUnitId), bannerParameters, customParameters);
183224
return;
184225
}
185226

186227
if (adManagerRequest != null) {
187228
adLoader.loadAdManagerAdLoaderAd(
188-
adUnitId, adListener, adManagerRequest.asAdManagerAdRequest(adUnitId), bannerParameters);
229+
adUnitId,
230+
adListener,
231+
adManagerRequest.asAdManagerAdRequest(adUnitId),
232+
bannerParameters,
233+
customParameters);
189234
return;
190235
}
191236

@@ -227,6 +272,15 @@ public void onAdManagerAdViewLoaded(@NonNull AdManagerAdView adView) {
227272
manager.onAdLoaded(adId, adView.getResponseInfo());
228273
}
229274

275+
@Override
276+
public void onCustomFormatAdLoaded(@NonNull NativeCustomFormatAd ad) {
277+
formatId = ad.getCustomFormatId();
278+
view =
279+
customParameters.factories.get(formatId).createCustomAd(ad, customParameters.viewOptions);
280+
type = AdLoaderAdType.CUSTOM;
281+
manager.onAdLoaded(adId, null);
282+
}
283+
230284
@Override
231285
void dispose() {
232286
if (view == null) {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.flutter.plugins.googlemobileads;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
import com.google.android.gms.ads.nativead.NativeCustomFormatAd.OnCustomFormatAdLoadedListener;
6+
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.CustomAdFactory;
7+
import java.util.HashMap;
8+
import java.util.List;
9+
import java.util.Map;
10+
11+
class FlutterCustomParameters {
12+
@NonNull final List<String> formatIds;
13+
@Nullable final Map<String, Object> viewOptions;
14+
15+
FlutterCustomParameters(
16+
@NonNull List<String> formatIds, @Nullable Map<String, Object> viewOptions) {
17+
this.formatIds = formatIds;
18+
this.viewOptions = viewOptions;
19+
}
20+
21+
FlutterAdLoaderAd.CustomParameters asCustomParameters(
22+
@NonNull OnCustomFormatAdLoadedListener listener,
23+
@NonNull Map<String, CustomAdFactory> availableFactories) {
24+
Map<String, CustomAdFactory> factories = new HashMap<>();
25+
for (String formatId : formatIds) {
26+
factories.put(formatId, availableFactories.get(formatId));
27+
}
28+
return new FlutterAdLoaderAd.CustomParameters(listener, factories, viewOptions);
29+
}
30+
}

0 commit comments

Comments
 (0)