Skip to content

Commit

Permalink
Allow serving Custom ads in AdLoaderAd
Browse files Browse the repository at this point in the history
Allow the `AdLoaderAd` instance to serve `Custom` ads, which are
instances of:

  * `NativeCustomFormatAd` under Android, and
  * `GADCustomNativeAd` under iOS
  • Loading branch information
msbit committed Feb 28, 2023
1 parent 96ea967 commit a0b4533
Show file tree
Hide file tree
Showing 21 changed files with 670 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class AdMessageCodec extends StandardMessageCodec {
private static final byte VALUE_COLOR = (byte) 153;
private static final byte VALUE_AD_MANAGER_AD_VIEW_OPTIONS = (byte) 154;
private static final byte VALUE_BANNER_PARAMETERS = (byte) 155;
private static final byte VALUE_CUSTOM_PARAMETERS = (byte) 156;

@NonNull Context context;
@NonNull final FlutterAdSize.AdSizeFactory adSizeFactory;
Expand Down Expand Up @@ -253,6 +254,11 @@ protected void writeValue(ByteArrayOutputStream stream, Object value) {
FlutterBannerParameters bannerParameters = (FlutterBannerParameters) value;
writeValue(stream, bannerParameters.sizes);
writeValue(stream, bannerParameters.adManagerAdViewOptions);
} else if (value instanceof FlutterCustomParameters) {
stream.write(VALUE_CUSTOM_PARAMETERS);
FlutterCustomParameters customParameters = (FlutterCustomParameters) value;
writeValue(stream, customParameters.formatIds);
writeValue(stream, customParameters.viewOptions);
} else {
super.writeValue(stream, value);
}
Expand Down Expand Up @@ -419,6 +425,10 @@ protected Object readValueOfType(byte type, ByteBuffer buffer) {
return new FlutterBannerParameters(
(List<FlutterAdSize>) readValueOfType(buffer.get(), buffer),
(FlutterAdManagerAdViewOptions) readValueOfType(buffer.get(), buffer));
case VALUE_CUSTOM_PARAMETERS:
return new FlutterCustomParameters(
(List<String>) readValueOfType(buffer.get(), buffer),
(Map<String, Object>) readValueOfType(buffer.get(), buffer));
default:
return super.readValueOfType(type, buffer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.google.android.gms.ads.formats.OnAdManagerAdViewLoadedListener;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAd.OnNativeAdLoadedListener;
import com.google.android.gms.ads.nativead.NativeCustomFormatAd;
import com.google.android.gms.ads.nativead.NativeCustomFormatAd.OnCustomFormatAdLoadedListener;
import java.lang.ref.WeakReference;

/** Callback type to notify when an ad successfully loads. */
Expand Down Expand Up @@ -137,3 +139,20 @@ public void onAdManagerAdViewLoaded(AdManagerAdView adView) {
}
}
}

/** {@link OnCustomFormatAdLoadedListener} for custom ads. */
class FlutterCustomFormatAdLoadedListener implements OnCustomFormatAdLoadedListener {

private final WeakReference<OnCustomFormatAdLoadedListener> reference;

FlutterCustomFormatAdLoadedListener(OnCustomFormatAdLoadedListener listener) {
reference = new WeakReference<>(listener);
}

@Override
public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
if (reference.get() != null) {
reference.get().onCustomFormatAdLoaded(ad);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,20 @@ public void loadAdLoaderAd(
@NonNull String adUnitId,
@NonNull AdListener adListener,
@NonNull AdRequest request,
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters) {
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters,
@Nullable FlutterAdLoaderAd.CustomParameters customParameters) {
AdLoader.Builder builder = new AdLoader.Builder(context, adUnitId);
if (bannerParameters != null) {
builder = builder.forAdManagerAdView(bannerParameters.listener, bannerParameters.adSizes);
if (bannerParameters.adManagerAdViewOptions != null) {
builder.withAdManagerAdViewOptions(bannerParameters.adManagerAdViewOptions);
}
}
if (customParameters != null) {
for (String formatId : customParameters.factories.keySet()) {
builder = builder.forCustomFormatAd(formatId, customParameters.listener, null);
}
}
builder.withAdListener(adListener).build().loadAd(request);
}

Expand All @@ -162,14 +168,20 @@ public void loadAdManagerAdLoaderAd(
@NonNull String adUnitId,
@NonNull AdListener adListener,
@NonNull AdManagerAdRequest adManagerAdRequest,
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters) {
@Nullable FlutterAdLoaderAd.BannerParameters bannerParameters,
@Nullable FlutterAdLoaderAd.CustomParameters customParameters) {
AdLoader.Builder builder = new AdLoader.Builder(context, adUnitId);
if (bannerParameters != null) {
builder = builder.forAdManagerAdView(bannerParameters.listener, bannerParameters.adSizes);
if (bannerParameters.adManagerAdViewOptions != null) {
builder.withAdManagerAdViewOptions(bannerParameters.adManagerAdViewOptions);
}
}
if (customParameters != null) {
for (String formatId : customParameters.factories.keySet()) {
builder = builder.forCustomFormatAd(formatId, customParameters.listener, null);
}
}
builder.withAdListener(adListener).build().loadAd(adManagerAdRequest);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@
import com.google.android.gms.ads.admanager.AdManagerAdView;
import com.google.android.gms.ads.formats.AdManagerAdViewOptions;
import com.google.android.gms.ads.formats.OnAdManagerAdViewLoadedListener;
import com.google.android.gms.ads.nativead.NativeCustomFormatAd;
import com.google.android.gms.ads.nativead.NativeCustomFormatAd.OnCustomFormatAdLoadedListener;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.CustomAdFactory;
import java.util.Map;

/**
* A central wrapper for {@link AdManagerAdView}, {@link NativeCustomFormatAd} and {@link NativeAd}
* instances served for a single {@link AdRequest} or {@link AdManagerAdRequest}
*/
class FlutterAdLoaderAd extends FlutterAd implements OnAdManagerAdViewLoadedListener {
class FlutterAdLoaderAd extends FlutterAd
implements OnAdManagerAdViewLoadedListener, OnCustomFormatAdLoadedListener {
private static final String TAG = "FlutterAdLoaderAd";

@NonNull private final AdInstanceManager manager;
Expand All @@ -40,6 +45,7 @@ class FlutterAdLoaderAd extends FlutterAd implements OnAdManagerAdViewLoadedList
@Nullable private FlutterAdManagerAdRequest adManagerRequest;
@Nullable private View view;
@Nullable protected BannerParameters bannerParameters;
@Nullable protected CustomParameters customParameters;

static class Builder {
@Nullable private AdInstanceManager manager;
Expand All @@ -49,6 +55,8 @@ static class Builder {
@Nullable private Integer id;
@Nullable private FlutterAdLoader adLoader;
@Nullable private FlutterBannerParameters bannerParameters;
@Nullable private FlutterCustomParameters customParameters;
@Nullable private Map<String, CustomAdFactory> customFactories;

public Builder setId(int id) {
this.id = id;
Expand Down Expand Up @@ -85,6 +93,17 @@ public Builder setBanner(@Nullable FlutterBannerParameters bannerParameters) {
return this;
}

public Builder setCustom(@Nullable FlutterCustomParameters customParameters) {
this.customParameters = customParameters;
return this;
}

public Builder withAvailableCustomFactories(
@NonNull Map<String, CustomAdFactory> customFactories) {
this.customFactories = customFactories;
return this;
}

FlutterAdLoaderAd build() {
if (manager == null) {
throw new IllegalStateException("manager must be provided");
Expand Down Expand Up @@ -112,6 +131,12 @@ FlutterAdLoaderAd build() {
new FlutterAdManagerAdViewLoadedListener(adLoaderAd));
}

if (customParameters != null) {
adLoaderAd.customParameters =
customParameters.asCustomParameters(
new FlutterCustomFormatAdLoadedListener(adLoaderAd), customFactories);
}

return adLoaderAd;
}
}
Expand All @@ -131,6 +156,21 @@ static class BannerParameters {
}
}

static class CustomParameters {
@NonNull final OnCustomFormatAdLoadedListener listener;
@NonNull final Map<String, CustomAdFactory> factories;
@Nullable final Map<String, Object> viewOptions;

CustomParameters(
@NonNull OnCustomFormatAdLoadedListener listener,
@NonNull Map<String, CustomAdFactory> factories,
@Nullable Map<String, Object> viewOptions) {
this.listener = listener;
this.factories = factories;
this.viewOptions = viewOptions;
}
}

protected FlutterAdLoaderAd(
int adId,
@NonNull AdInstanceManager manager,
Expand Down Expand Up @@ -164,13 +204,17 @@ void load() {
// As of 20.0.0 of GMA, mockito is unable to mock AdLoader.
if (request != null) {
adLoader.loadAdLoaderAd(
adUnitId, adListener, request.asAdRequest(adUnitId), bannerParameters);
adUnitId, adListener, request.asAdRequest(adUnitId), bannerParameters, customParameters);
return;
}

if (adManagerRequest != null) {
adLoader.loadAdManagerAdLoaderAd(
adUnitId, adListener, adManagerRequest.asAdManagerAdRequest(adUnitId), bannerParameters);
adUnitId,
adListener,
adManagerRequest.asAdManagerAdRequest(adUnitId),
bannerParameters,
customParameters);
return;
}

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

@Override
public void onCustomFormatAdLoaded(@NonNull NativeCustomFormatAd ad) {
String formatId = ad.getCustomFormatId();
view =
customParameters.factories.get(formatId).createCustomAd(ad, customParameters.viewOptions);
manager.onAdLoaded(adId, null);
}

@Override
void dispose() {
if (view == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.flutter.plugins.googlemobileads;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.ads.nativead.NativeCustomFormatAd.OnCustomFormatAdLoadedListener;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.CustomAdFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class FlutterCustomParameters {
@NonNull final List<String> formatIds;
@Nullable final Map<String, Object> viewOptions;

FlutterCustomParameters(
@NonNull List<String> formatIds, @Nullable Map<String, Object> viewOptions) {
this.formatIds = formatIds;
this.viewOptions = viewOptions;
}

FlutterAdLoaderAd.CustomParameters asCustomParameters(
@NonNull OnCustomFormatAdLoadedListener listener,
@NonNull Map<String, CustomAdFactory> availableFactories) {
Map<String, CustomAdFactory> factories = new HashMap<>();
for (String formatId : formatIds) {
factories.put(formatId, availableFactories.get(formatId));
}
return new FlutterAdLoaderAd.CustomParameters(listener, factories, viewOptions);
}
}
Loading

0 comments on commit a0b4533

Please sign in to comment.