Last active
February 8, 2021 19:23
-
-
Save thomasmso/727e48212057d42fb9db34ed2de66107 to your computer and use it in GitHub Desktop.
MAX AdColony Adapter - Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.applovin.mediation.adapters; | |
import android.app.Activity; | |
import android.os.Bundle; | |
import android.text.TextUtils; | |
import com.adcolony.sdk.AdColony; | |
import com.adcolony.sdk.AdColonyAdSize; | |
import com.adcolony.sdk.AdColonyAdView; | |
import com.adcolony.sdk.AdColonyAdViewListener; | |
import com.adcolony.sdk.AdColonyAppOptions; | |
import com.adcolony.sdk.AdColonyInterstitial; | |
import com.adcolony.sdk.AdColonyInterstitialListener; | |
import com.adcolony.sdk.AdColonyReward; | |
import com.adcolony.sdk.AdColonyRewardListener; | |
import com.adcolony.sdk.AdColonyZone; | |
import com.applovin.mediation.MaxAdFormat; | |
import com.applovin.mediation.MaxReward; | |
import com.applovin.mediation.adapter.MaxAdViewAdapter; | |
import com.applovin.mediation.adapter.MaxAdapterError; | |
import com.applovin.mediation.adapter.MaxInterstitialAdapter; | |
import com.applovin.mediation.adapter.MaxRewardedAdapter; | |
import com.applovin.mediation.adapter.MaxSignalProvider; | |
import com.applovin.mediation.adapter.listeners.MaxAdViewAdapterListener; | |
import com.applovin.mediation.adapter.listeners.MaxInterstitialAdapterListener; | |
import com.applovin.mediation.adapter.listeners.MaxRewardedAdapterListener; | |
import com.applovin.mediation.adapter.listeners.MaxSignalCollectionListener; | |
import com.applovin.mediation.adapter.parameters.MaxAdapterInitializationParameters; | |
import com.applovin.mediation.adapter.parameters.MaxAdapterParameters; | |
import com.applovin.mediation.adapter.parameters.MaxAdapterResponseParameters; | |
import com.applovin.mediation.adapter.parameters.MaxAdapterSignalCollectionParameters; | |
import com.applovin.mediation.adapters.adcolony.BuildConfig; | |
import com.applovin.sdk.AppLovinSdk; | |
import com.applovin.sdk.AppLovinSdkConfiguration; | |
import java.lang.reflect.Method; | |
import java.util.List; | |
import java.util.concurrent.atomic.AtomicBoolean; | |
/** | |
* Created by Thomas So on February 16 2019 | |
*/ | |
public class AdColonyMediationAdapter | |
extends MediationAdapterBase | |
implements MaxSignalProvider, MaxInterstitialAdapter, MaxRewardedAdapter, MaxAdViewAdapter | |
{ | |
private static final AtomicBoolean INITIALIZED = new AtomicBoolean(); | |
private static InitializationStatus sStatus; | |
// Interstitial | |
private AdColonyInterstitial loadedInterstitialAd; | |
private InterstitialListener interstitialAdListener; | |
// Rewarded | |
private AdColonyInterstitial loadedRewardedAd; | |
private RewardedAdListener rewardedAdListener; | |
// Banner/MREC | |
private AdColonyAdView loadedAdViewAd; | |
private AdViewAdListener adViewAdListener; | |
// Explicit default constructor declaration | |
public AdColonyMediationAdapter(final AppLovinSdk sdk) { super( sdk ); } | |
@Override | |
public String getSdkVersion() | |
{ | |
// NOTE: AdColony returns an empty string if attempting to retrieve if not initialized | |
return AdColony.getSDKVersion(); | |
} | |
@Override | |
public String getAdapterVersion() | |
{ | |
return BuildConfig.VERSION_NAME; | |
} | |
@Override | |
public void onDestroy() | |
{ | |
loadedInterstitialAd = null; | |
interstitialAdListener = null; | |
loadedRewardedAd = null; | |
rewardedAdListener = null; | |
if ( loadedAdViewAd != null ) | |
{ | |
loadedAdViewAd.destroy(); | |
loadedAdViewAd = null; | |
adViewAdListener = null; | |
} | |
} | |
@Override | |
public void collectSignal(final MaxAdapterSignalCollectionParameters parameters, final Activity activity, final MaxSignalCollectionListener callback) | |
{ | |
log( "Collecting signal for " + parameters.getAdFormat() + " ad..." ); | |
String signal = AdColony.collectSignals(); | |
callback.onSignalCollected( signal ); | |
} | |
@Override | |
public void initialize(final MaxAdapterInitializationParameters parameters, final Activity activity, final OnCompletionListener onCompletionListener) | |
{ | |
if ( INITIALIZED.compareAndSet( false, true ) ) | |
{ | |
sStatus = InitializationStatus.INITIALIZING; | |
final String appId = parameters.getServerParameters().getString( "app_id" ); | |
log( "Initializing AdColony SDK with app id: " + appId + "..." ); | |
checkExistence( AdColony.class ); | |
final String[] zoneIds = getZoneIds( parameters ); | |
final AdColonyAppOptions options = getOptions( parameters ); | |
final boolean initialized = AdColony.configure( activity, options, appId, zoneIds ); | |
sStatus = initialized ? InitializationStatus.INITIALIZED_SUCCESS : InitializationStatus.INITIALIZED_FAILURE; | |
} | |
onCompletionListener.onCompletion( sStatus, null ); | |
} | |
@Override | |
public void loadInterstitialAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxInterstitialAdapterListener listener) | |
{ | |
final String zoneId = parameters.getThirdPartyAdPlacementId(); | |
final String bidResponse = parameters.getBidResponse(); | |
log( "Loading " + ( TextUtils.isEmpty( bidResponse ) ? "bidding " : "" ) + " interstitial ad for zone id " + zoneId + "..." ); | |
if ( !isAdColonyConfigured() ) | |
{ | |
log( "AdColony SDK is not initialized" ); | |
listener.onInterstitialAdLoadFailed( MaxAdapterError.NOT_INITIALIZED ); | |
return; | |
} | |
AdColony.setAppOptions( getOptions( parameters ) ); | |
interstitialAdListener = new InterstitialListener( listener ); | |
AdColony.requestInterstitial( zoneId, interstitialAdListener ); | |
} | |
@Override | |
public void showInterstitialAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxInterstitialAdapterListener listener) | |
{ | |
log( "Showing interstitial ad..." ); | |
if ( loadedInterstitialAd == null ) | |
{ | |
log( "Interstitial ad not ready" ); | |
listener.onInterstitialAdDisplayFailed( MaxAdapterError.UNSPECIFIED ); | |
return; | |
} | |
if ( loadedInterstitialAd.isExpired() ) | |
{ | |
log( "Interstitial ad is expired" ); | |
MaxAdapterError adapterError = MaxAdapterError.AD_EXPIRED; | |
listener.onInterstitialAdDisplayFailed( adapterError ); | |
return; | |
} | |
final boolean success = loadedInterstitialAd.show(); | |
if ( !success ) | |
{ | |
log( "Interstitial ad failed to display" ); | |
listener.onInterstitialAdDisplayFailed( MaxAdapterError.UNSPECIFIED ); | |
} | |
} | |
@Override | |
public void loadRewardedAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxRewardedAdapterListener listener) | |
{ | |
final String zoneId = parameters.getThirdPartyAdPlacementId(); | |
final String bidResponse = parameters.getBidResponse(); | |
log( "Loading " + ( TextUtils.isEmpty( bidResponse ) ? "bidding " : "" ) + " rewarded ad for zone id " + zoneId + "..." ); | |
if ( !isAdColonyConfigured() ) | |
{ | |
log( "AdColony SDK is not initialized" ); | |
listener.onRewardedAdLoadFailed( MaxAdapterError.NOT_INITIALIZED ); | |
return; | |
} | |
AdColony.setAppOptions( getOptions( parameters ) ); | |
rewardedAdListener = new RewardedAdListener( listener ); | |
AdColony.setRewardListener( rewardedAdListener ); | |
AdColony.requestInterstitial( zoneId, rewardedAdListener ); | |
} | |
@Override | |
public void showRewardedAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxRewardedAdapterListener listener) | |
{ | |
log( "Showing rewarded ad..." ); | |
if ( loadedRewardedAd == null ) | |
{ | |
log( "Rewarded ad not ready" ); | |
listener.onRewardedAdDisplayFailed( MaxAdapterError.UNSPECIFIED ); | |
return; | |
} | |
if ( loadedRewardedAd.isExpired() ) | |
{ | |
log( "Rewarded ad is expired" ); | |
MaxAdapterError adapterError = MaxAdapterError.AD_EXPIRED; | |
listener.onRewardedAdDisplayFailed( adapterError ); | |
return; | |
} | |
// Configure userReward from server. | |
configureReward( parameters ); | |
final boolean success = loadedRewardedAd.show(); | |
if ( !success ) | |
{ | |
log( "Rewarded ad failed to display" ); | |
listener.onRewardedAdDisplayFailed( MaxAdapterError.UNSPECIFIED ); | |
} | |
} | |
@Override | |
public void loadAdViewAd(final MaxAdapterResponseParameters parameters, final MaxAdFormat adFormat, final Activity activity, final MaxAdViewAdapterListener listener) | |
{ | |
final String zoneId = parameters.getThirdPartyAdPlacementId(); | |
final String bidResponse = parameters.getBidResponse(); | |
log( "Loading " + ( TextUtils.isEmpty( bidResponse ) ? "bidding " : "" ) + adFormat.getLabel() + " ad for zone id " + zoneId + "..." ); | |
if ( !isAdColonyConfigured() ) | |
{ | |
log( "AdColony SDK is not initialized" ); | |
listener.onAdViewAdLoadFailed( MaxAdapterError.NOT_INITIALIZED ); | |
return; | |
} | |
AdColony.setAppOptions( getOptions( parameters ) ); | |
adViewAdListener = new AdViewAdListener( adFormat, listener ); | |
AdColony.requestAdView( zoneId, adViewAdListener, sizeFromAdFormat( adFormat ) ); | |
} | |
//region Helper Methods | |
private boolean isAdColonyConfigured() | |
{ | |
return !AdColony.getSDKVersion().isEmpty(); | |
} | |
/** | |
* Gets a String array of zone ids from the server parameters. | |
* Note that the SDK converts string arrays into an ArrayList to be stored in the server parameters Bundle. | |
*/ | |
private String[] getZoneIds(MaxAdapterParameters parameters) | |
{ | |
final List<String> rawZoneIds = parameters.getServerParameters().getStringArrayList( "zone_ids" ); | |
if ( rawZoneIds == null || rawZoneIds.size() == 0 ) return new String[0]; | |
final String[] zoneIds = new String[rawZoneIds.size()]; | |
for ( int i = 0; i < rawZoneIds.size(); i++ ) | |
{ | |
zoneIds[i] = rawZoneIds.get( i ); | |
} | |
return zoneIds; | |
} | |
private AdColonyAppOptions getOptions(final MaxAdapterParameters parameters) | |
{ | |
final Bundle serverParameters = parameters.getServerParameters(); | |
final AdColonyAppOptions options = new AdColonyAppOptions(); | |
// | |
// Basic options | |
// | |
options.setTestModeEnabled( parameters.isTesting() ); | |
options.setMediationNetwork( "AppLovin", AppLovinSdk.VERSION ); | |
// | |
// GDPR options | |
// | |
// Set user consent state | |
if ( getWrappingSdk().getConfiguration().getConsentDialogState() == AppLovinSdkConfiguration.ConsentDialogState.APPLIES ) | |
{ | |
options.setPrivacyFrameworkRequired( AdColonyAppOptions.GDPR, true ); | |
Boolean hasUserConsent = getPrivacySetting( "hasUserConsent", parameters ); | |
if ( hasUserConsent != null ) | |
{ | |
options.setPrivacyConsentString( AdColonyAppOptions.GDPR, hasUserConsent ? "1" : "0" ); | |
} | |
} | |
else if ( getWrappingSdk().getConfiguration().getConsentDialogState() == AppLovinSdkConfiguration.ConsentDialogState.DOES_NOT_APPLY ) | |
{ | |
options.setPrivacyFrameworkRequired( AdColonyAppOptions.GDPR, false ); | |
} | |
// | |
// CCPA options | |
// | |
if ( AppLovinSdk.VERSION_CODE >= 61100 ) | |
{ | |
Boolean isDoNotSell = getPrivacySetting( "isDoNotSell", parameters ); | |
if ( isDoNotSell != null ) | |
{ | |
options.setPrivacyFrameworkRequired( AdColonyAppOptions.CCPA, true ); | |
options.setPrivacyConsentString( isDoNotSell ? "0" : "1", AdColonyAppOptions.CCPA ); // isDoNotSell means user has opted out of selling data. | |
} | |
else | |
{ | |
options.setPrivacyFrameworkRequired( AdColonyAppOptions.CCPA, false ); | |
} | |
} | |
// | |
// COPPA options | |
// | |
Boolean isAgeRestrictedUser = getPrivacySetting( "isAgeRestrictedUser", parameters ); | |
if ( isAgeRestrictedUser != null ) | |
{ | |
options.setPrivacyFrameworkRequired( AdColonyAppOptions.COPPA, isAgeRestrictedUser ); | |
options.setPrivacyConsentString( "", AdColonyAppOptions.COPPA ); // Setting empty string to clear any previously set values. | |
} | |
// | |
// Bidding options | |
// | |
// If AdColony wins the auction, network adapters need to send any .adm content via ad_options to the AdColony SDK when making the ad request | |
if ( parameters instanceof MaxAdapterResponseParameters ) | |
{ | |
final String bidResponse = ( (MaxAdapterResponseParameters) parameters ).getBidResponse(); | |
if ( !TextUtils.isEmpty( bidResponse ) ) | |
{ | |
options.setOption( "adm", bidResponse ); | |
} | |
} | |
// | |
// Other options | |
// | |
if ( serverParameters.containsKey( "app_orientation" ) ) | |
{ | |
// 0 = PORTRAIT, 1 = LANDSCAPE, 2 = ALL | |
options.setAppOrientation( serverParameters.getInt( "app_orientation" ) ); | |
} | |
if ( serverParameters.containsKey( "app_version" ) ) | |
{ | |
options.setAppVersion( serverParameters.getString( "app_version" ) ); | |
} | |
if ( serverParameters.containsKey( "keep_screen_on" ) ) | |
{ | |
options.setKeepScreenOn( serverParameters.getBoolean( "keep_screen_on" ) ); | |
} | |
if ( serverParameters.containsKey( "multi_window_enabled" ) ) | |
{ | |
options.setMultiWindowEnabled( serverParameters.getBoolean( "multi_window_enabled" ) ); | |
} | |
if ( serverParameters.containsKey( "origin_store" ) ) | |
{ | |
options.setOriginStore( serverParameters.getString( "origin_store" ) ); | |
} | |
if ( serverParameters.containsKey( "requested_ad_orientation" ) ) | |
{ | |
// 0 = PORTRAIT, 1 = LANDSCAPE, 2 = ALL | |
options.setRequestedAdOrientation( serverParameters.getInt( "requested_ad_orientation" ) ); | |
} | |
if ( serverParameters.containsKey( "plugin" ) && serverParameters.containsKey( "plugin_version" ) ) | |
{ | |
options.setPlugin( serverParameters.getString( "plugin" ), serverParameters.getString( "plugin_version" ) ); | |
} | |
if ( serverParameters.containsKey( "user_id" ) ) | |
{ | |
options.setUserID( serverParameters.getString( "user_id" ) ); | |
} | |
return options; | |
} | |
private AdColonyAdSize sizeFromAdFormat(final MaxAdFormat adFormat) | |
{ | |
if ( adFormat == MaxAdFormat.BANNER ) | |
{ | |
return AdColonyAdSize.BANNER; | |
} | |
else if ( adFormat == MaxAdFormat.LEADER ) | |
{ | |
return AdColonyAdSize.LEADERBOARD; | |
} | |
else if ( adFormat == MaxAdFormat.MREC ) | |
{ | |
return AdColonyAdSize.MEDIUM_RECTANGLE; | |
} | |
else | |
{ | |
throw new IllegalArgumentException( "Invalid ad format: " + adFormat ); | |
} | |
} | |
private Boolean getPrivacySetting(final String privacySetting, final MaxAdapterParameters parameters) | |
{ | |
try | |
{ | |
// Use reflection because compiled adapters have trouble fetching `boolean` from old SDKs and `Boolean` from new SDKs (above 9.14.0) | |
Class<?> parametersClass = parameters.getClass(); | |
Method privacyMethod = parametersClass.getMethod( privacySetting ); | |
return (Boolean) privacyMethod.invoke( parameters ); | |
} | |
catch ( Exception exception ) | |
{ | |
log( "Error getting privacy setting " + privacySetting + " with exception: ", exception ); | |
return ( AppLovinSdk.VERSION_CODE >= 9140000 ) ? null : false; | |
} | |
} | |
//endregion | |
private class InterstitialListener | |
extends AdColonyInterstitialListener | |
{ | |
private final MaxInterstitialAdapterListener listener; | |
InterstitialListener(final MaxInterstitialAdapterListener listener) | |
{ | |
this.listener = listener; | |
} | |
@Override | |
public void onRequestFilled(final AdColonyInterstitial adColonyInterstitial) | |
{ | |
log( "Interstitial loaded" ); | |
loadedInterstitialAd = adColonyInterstitial; | |
listener.onInterstitialAdLoaded(); | |
} | |
@Override | |
public void onRequestNotFilled(final AdColonyZone zone) | |
{ | |
log( "Interstitial failed to fill for zone: " + zone.getZoneID() ); | |
listener.onInterstitialAdLoadFailed( MaxAdapterError.NO_FILL ); | |
} | |
@Override | |
public void onOpened(final AdColonyInterstitial ad) | |
{ | |
log( "Interstitial shown" ); | |
listener.onInterstitialAdDisplayed(); | |
} | |
@Override | |
public void onClosed(final AdColonyInterstitial ad) | |
{ | |
log( "Interstitial hidden" ); | |
listener.onInterstitialAdHidden(); | |
} | |
@Override | |
public void onExpiring(final AdColonyInterstitial ad) | |
{ | |
log( "Interstitial expiring: " + ad.getZoneID() ); | |
} | |
@Override | |
public void onLeftApplication(final AdColonyInterstitial ad) | |
{ | |
log( "Interstitial left application" ); | |
} | |
@Override | |
public void onClicked(final AdColonyInterstitial ad) | |
{ | |
log( "Interstitial clicked" ); | |
listener.onInterstitialAdClicked(); | |
} | |
} | |
private class RewardedAdListener | |
extends AdColonyInterstitialListener | |
implements AdColonyRewardListener | |
{ | |
private final MaxRewardedAdapterListener listener; | |
private boolean hasGrantedReward; | |
RewardedAdListener(final MaxRewardedAdapterListener listener) | |
{ | |
this.listener = listener; | |
} | |
@Override | |
public void onReward(final AdColonyReward adColonyReward) | |
{ | |
log( "Rewarded ad granted reward" ); | |
hasGrantedReward = true; | |
} | |
@Override | |
public void onRequestFilled(final AdColonyInterstitial adColonyInterstitial) | |
{ | |
log( "Rewarded ad loaded" ); | |
loadedRewardedAd = adColonyInterstitial; | |
listener.onRewardedAdLoaded(); | |
} | |
@Override | |
public void onRequestNotFilled(final AdColonyZone zone) | |
{ | |
log( "Rewarded ad failed to fill for zone: " + zone.getZoneID() ); | |
listener.onRewardedAdLoadFailed( MaxAdapterError.NO_FILL ); | |
} | |
@Override | |
public void onOpened(final AdColonyInterstitial ad) | |
{ | |
log( "Rewarded ad shown" ); | |
listener.onRewardedAdDisplayed(); | |
listener.onRewardedAdVideoStarted(); | |
} | |
@Override | |
public void onClosed(final AdColonyInterstitial ad) | |
{ | |
listener.onRewardedAdVideoCompleted(); | |
if ( hasGrantedReward || shouldAlwaysRewardUser() ) | |
{ | |
final MaxReward reward = getReward(); | |
log( "Rewarded user with reward: " + reward ); | |
listener.onUserRewarded( reward ); | |
} | |
log( "Rewarded ad hidden" ); | |
listener.onRewardedAdHidden(); | |
} | |
@Override | |
public void onExpiring(final AdColonyInterstitial ad) | |
{ | |
log( "Rewarded ad expiring: " + ad.getZoneID() ); | |
} | |
@Override | |
public void onLeftApplication(final AdColonyInterstitial ad) | |
{ | |
log( "Rewarded ad left application" ); | |
} | |
@Override | |
public void onClicked(final AdColonyInterstitial ad) | |
{ | |
log( "Rewarded ad clicked" ); | |
listener.onRewardedAdClicked(); | |
} | |
} | |
private class AdViewAdListener | |
extends AdColonyAdViewListener | |
{ | |
private final MaxAdViewAdapterListener listener; | |
private final MaxAdFormat adFormat; | |
AdViewAdListener(final MaxAdFormat adFormat, final MaxAdViewAdapterListener listener) | |
{ | |
this.listener = listener; | |
this.adFormat = adFormat; | |
} | |
@Override | |
public void onRequestFilled(final AdColonyAdView adColonyAdView) | |
{ | |
log( adFormat.getLabel() + " ad loaded" ); | |
loadedAdViewAd = adColonyAdView; | |
listener.onAdViewAdLoaded( loadedAdViewAd ); | |
} | |
public void onLeftApplication(final AdColonyAdView ad) | |
{ | |
log( adFormat.getLabel() + " ad left application" ); | |
} | |
public void onClicked(final AdColonyAdView ad) | |
{ | |
log( adFormat.getLabel() + " ad clicked" ); | |
listener.onAdViewAdClicked(); | |
} | |
public void onRequestNotFilled(final AdColonyZone zone) | |
{ | |
log( adFormat.getLabel() + " ad failed to fill for zone: " + zone.getZoneID() ); | |
listener.onAdViewAdLoadFailed( MaxAdapterError.NO_FILL ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment