Skip to content

Commit 4df017e

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 08231cb commit 4df017e

21 files changed

Lines changed: 670 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
@@ -56,6 +56,7 @@ class AdMessageCodec extends StandardMessageCodec {
5656
private static final byte VALUE_REQUEST_CONFIGURATION_PARAMS = (byte) 148;
5757
private static final byte VALUE_AD_MANAGER_AD_VIEW_OPTIONS = (byte) 149;
5858
private static final byte VALUE_BANNER_PARAMETERS = (byte) 150;
59+
private static final byte VALUE_CUSTOM_PARAMETERS = (byte) 151;
5960

6061
@NonNull Context context;
6162
@NonNull final FlutterAdSize.AdSizeFactory adSizeFactory;
@@ -213,6 +214,11 @@ protected void writeValue(ByteArrayOutputStream stream, Object value) {
213214
FlutterBannerParameters bannerParameters = (FlutterBannerParameters) value;
214215
writeValue(stream, bannerParameters.sizes);
215216
writeValue(stream, bannerParameters.adManagerAdViewOptions);
217+
} else if (value instanceof FlutterCustomParameters) {
218+
stream.write(VALUE_CUSTOM_PARAMETERS);
219+
FlutterCustomParameters customParameters = (FlutterCustomParameters) value;
220+
writeValue(stream, customParameters.formatIds);
221+
writeValue(stream, customParameters.viewOptions);
216222
} else {
217223
super.writeValue(stream, value);
218224
}
@@ -353,6 +359,10 @@ protected Object readValueOfType(byte type, ByteBuffer buffer) {
353359
return new FlutterBannerParameters(
354360
(List<FlutterAdSize>) readValueOfType(buffer.get(), buffer),
355361
(FlutterAdManagerAdViewOptions) readValueOfType(buffer.get(), buffer));
362+
case VALUE_CUSTOM_PARAMETERS:
363+
return new FlutterCustomParameters(
364+
(List<String>) readValueOfType(buffer.get(), buffer),
365+
(Map<String, Object>) readValueOfType(buffer.get(), buffer));
356366
default:
357367
return super.readValueOfType(type, buffer);
358368
}

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: 55 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;
@@ -40,6 +45,7 @@ class FlutterAdLoaderAd extends FlutterAd implements OnAdManagerAdViewLoadedList
4045
@Nullable private FlutterAdManagerAdRequest adManagerRequest;
4146
@Nullable private View view;
4247
@Nullable protected BannerParameters bannerParameters;
48+
@Nullable protected CustomParameters customParameters;
4349

4450
static class Builder {
4551
@Nullable private AdInstanceManager manager;
@@ -49,6 +55,8 @@ static class Builder {
4955
@Nullable private Integer id;
5056
@Nullable private FlutterAdLoader adLoader;
5157
@Nullable private FlutterBannerParameters bannerParameters;
58+
@Nullable private FlutterCustomParameters customParameters;
59+
@Nullable private Map<String, CustomAdFactory> customFactories;
5260

5361
public Builder setId(int id) {
5462
this.id = id;
@@ -85,6 +93,17 @@ public Builder setBanner(@Nullable FlutterBannerParameters bannerParameters) {
8593
return this;
8694
}
8795

96+
public Builder setCustom(@Nullable FlutterCustomParameters customParameters) {
97+
this.customParameters = customParameters;
98+
return this;
99+
}
100+
101+
public Builder withAvailableCustomFactories(
102+
@NonNull Map<String, CustomAdFactory> customFactories) {
103+
this.customFactories = customFactories;
104+
return this;
105+
}
106+
88107
FlutterAdLoaderAd build() {
89108
if (manager == null) {
90109
throw new IllegalStateException("manager must be provided");
@@ -112,6 +131,12 @@ FlutterAdLoaderAd build() {
112131
new FlutterAdManagerAdViewLoadedListener(adLoaderAd));
113132
}
114133

134+
if (customParameters != null) {
135+
adLoaderAd.customParameters =
136+
customParameters.asCustomParameters(
137+
new FlutterCustomFormatAdLoadedListener(adLoaderAd), customFactories);
138+
}
139+
115140
return adLoaderAd;
116141
}
117142
}
@@ -131,6 +156,21 @@ static class BannerParameters {
131156
}
132157
}
133158

159+
static class CustomParameters {
160+
@NonNull final OnCustomFormatAdLoadedListener listener;
161+
@NonNull final Map<String, CustomAdFactory> factories;
162+
@Nullable final Map<String, Object> viewOptions;
163+
164+
CustomParameters(
165+
@NonNull OnCustomFormatAdLoadedListener listener,
166+
@NonNull Map<String, CustomAdFactory> factories,
167+
@Nullable Map<String, Object> viewOptions) {
168+
this.listener = listener;
169+
this.factories = factories;
170+
this.viewOptions = viewOptions;
171+
}
172+
}
173+
134174
protected FlutterAdLoaderAd(
135175
int adId,
136176
@NonNull AdInstanceManager manager,
@@ -164,13 +204,17 @@ void load() {
164204
// As of 20.0.0 of GMA, mockito is unable to mock AdLoader.
165205
if (request != null) {
166206
adLoader.loadAdLoaderAd(
167-
adUnitId, adListener, request.asAdRequest(adUnitId), bannerParameters);
207+
adUnitId, adListener, request.asAdRequest(adUnitId), bannerParameters, customParameters);
168208
return;
169209
}
170210

171211
if (adManagerRequest != null) {
172212
adLoader.loadAdManagerAdLoaderAd(
173-
adUnitId, adListener, adManagerRequest.asAdManagerAdRequest(adUnitId), bannerParameters);
213+
adUnitId,
214+
adListener,
215+
adManagerRequest.asAdManagerAdRequest(adUnitId),
216+
bannerParameters,
217+
customParameters);
174218
return;
175219
}
176220

@@ -193,6 +237,14 @@ public void onAdManagerAdViewLoaded(@NonNull AdManagerAdView adView) {
193237
manager.onAdLoaded(adId, adView.getResponseInfo());
194238
}
195239

240+
@Override
241+
public void onCustomFormatAdLoaded(@NonNull NativeCustomFormatAd ad) {
242+
String formatId = ad.getCustomFormatId();
243+
view =
244+
customParameters.factories.get(formatId).createCustomAd(ad, customParameters.viewOptions);
245+
manager.onAdLoaded(adId, null);
246+
}
247+
196248
@Override
197249
void dispose() {
198250
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)