Skip to content

Commit 7a58770

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 35e5520 commit 7a58770

21 files changed

Lines changed: 681 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;
@@ -41,6 +46,7 @@ class FlutterAdLoaderAd extends FlutterAd implements OnAdManagerAdViewLoadedList
4146
@Nullable private AdLoaderAdType type;
4247
@Nullable private View view;
4348
@Nullable protected BannerParameters bannerParameters;
49+
@Nullable protected CustomParameters customParameters;
4450

4551
static class Builder {
4652
@Nullable private AdInstanceManager manager;
@@ -50,6 +56,8 @@ static class Builder {
5056
@Nullable private Integer id;
5157
@Nullable private FlutterAdLoader adLoader;
5258
@Nullable private FlutterBannerParameters bannerParameters;
59+
@Nullable private FlutterCustomParameters customParameters;
60+
@Nullable private Map<String, CustomAdFactory> customFactories;
5361

5462
public Builder setId(int id) {
5563
this.id = id;
@@ -86,6 +94,17 @@ public Builder setBanner(@Nullable FlutterBannerParameters bannerParameters) {
8694
return this;
8795
}
8896

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

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

120145
enum AdLoaderAdType {
121146
UNKNOWN,
122147
BANNER,
148+
CUSTOM,
123149
}
124150

125151
static class BannerParameters {
@@ -137,6 +163,21 @@ static class BannerParameters {
137163
}
138164
}
139165

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

183224
if (adManagerRequest != null) {
184225
adLoader.loadAdManagerAdLoaderAd(
185-
adUnitId, adListener, adManagerRequest.asAdManagerAdRequest(adUnitId), bannerParameters);
226+
adUnitId,
227+
adListener,
228+
adManagerRequest.asAdManagerAdRequest(adUnitId),
229+
bannerParameters,
230+
customParameters);
186231
return;
187232
}
188233

@@ -219,6 +264,15 @@ public void onAdManagerAdViewLoaded(@NonNull AdManagerAdView adView) {
219264
manager.onAdLoaded(adId, adView.getResponseInfo());
220265
}
221266

267+
@Override
268+
public void onCustomFormatAdLoaded(@NonNull NativeCustomFormatAd ad) {
269+
String formatId = ad.getCustomFormatId();
270+
view =
271+
customParameters.factories.get(formatId).createCustomAd(ad, customParameters.viewOptions);
272+
type = AdLoaderAdType.CUSTOM;
273+
manager.onAdLoaded(adId, null);
274+
}
275+
222276
@Override
223277
void dispose() {
224278
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)