Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AppLovin/internal advanced bidding #2

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,4 @@ public void userRewardVerified(AppLovinAd ad, Map<String, String> response) {
ApplovinAdapter.log(DEBUG, "Rewarded " + amount + " " + currency);
mRewardItem = new AppLovinRewardItem(amount, currency);
}

/**
* Reward item wrapper class.
*/
private static final class AppLovinRewardItem
implements RewardItem {
private final int mAmount;
private final String mType;

private AppLovinRewardItem(int amount, final String type) {
mAmount = amount;
mType = type;
}

@Override
public String getType() {
return mType;
}

@Override
public int getAmount() {
return mAmount;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.applovin.mediation;

import com.google.android.gms.ads.reward.RewardItem;

/**
* Created by Thomas So on July 17 2018
*/
public final class AppLovinRewardItem
implements RewardItem
{
private final int mAmount;
private final String mType;

public AppLovinRewardItem(int amount, String type)
{
mAmount = amount;
mType = type;
}

@Override
public String getType()
{
return mType;
}

@Override
public int getAmount()
{
return mAmount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@
import android.os.Bundle;
import android.text.TextUtils;

import com.applovin.sdk.AppLovinAdSize;
import com.applovin.sdk.AppLovinErrorCodes;
import com.applovin.sdk.AppLovinMediationProvider;
import com.applovin.sdk.AppLovinSdk;
import com.applovin.sdk.AppLovinSdkSettings;
import com.applovin.sdk.BuildConfig;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;

/*
* A helper class used by {@link AppLovinAdapter}.
*/
class AppLovinUtils {
public class AppLovinUtils
{
private static final String DEFAULT_ZONE = "";

private static final int BANNER_STANDARD_HEIGHT = 50;
private static final int BANNER_HEIGHT_OFFSET_TOLERANCE = 10;

/**
* Keys for retrieving values from the server parameters.
*/
Expand All @@ -29,8 +36,9 @@ private static class ServerParameterKeys {
* Retrieves the appropriate instance of AppLovin's SDK from the SDK key given in the server
* parameters, or Android Manifest.
*/
static AppLovinSdk retrieveSdk(Bundle serverParameters, Context context) {
final String sdkKey = serverParameters.getString(ServerParameterKeys.SDK_KEY);
public static AppLovinSdk retrieveSdk(Bundle serverParameters, Context context)
{
final String sdkKey = (serverParameters != null) ? serverParameters.getString( ServerParameterKeys.SDK_KEY ) : null;
final AppLovinSdk sdk;

if (!TextUtils.isEmpty(sdkKey)) {
Expand Down Expand Up @@ -73,14 +81,16 @@ static String retrieveZoneId(Bundle serverParameters) {
/**
* Retrieves whether or not to mute the ad that is about to be rendered.
*/
static boolean shouldMuteAudio(Bundle networkExtras) {
return networkExtras != null && networkExtras.getBoolean(AppLovinExtras.Keys.MUTE_AUDIO);
public static boolean shouldMuteAudio(Bundle networkExtras)
{
return networkExtras != null && networkExtras.getBoolean( AppLovinExtras.Keys.MUTE_AUDIO );
}

/**
* Convert the given AppLovin SDK error code into the appropriate AdMob error code.
*/
static int toAdMobErrorCode(int applovinErrorCode) {
public static int toAdMobErrorCode(int applovinErrorCode)
{
//
// TODO: Be more exhaustive
//
Expand All @@ -93,4 +103,35 @@ static int toAdMobErrorCode(int applovinErrorCode) {
return AdRequest.ERROR_CODE_INTERNAL_ERROR;
}
}

/**
* Get the {@link AppLovinAdSize} from a given {@link AdSize} from AdMob.
*/
public static AppLovinAdSize appLovinAdSizeFromAdMobAdSize(AdSize adSize)
{
final boolean isSmartBanner = ( adSize.getWidth() == AdSize.FULL_WIDTH ) &&
( adSize.getHeight() == AdSize.AUTO_HEIGHT );

if ( AdSize.BANNER.equals( adSize ) || AdSize.LARGE_BANNER.equals( adSize ) || isSmartBanner )
{
return AppLovinAdSize.BANNER;
}
else if ( AdSize.MEDIUM_RECTANGLE.equals( adSize ) )
{
return AppLovinAdSize.MREC;
}
else if ( AdSize.LEADERBOARD.equals( adSize ) )
{
return AppLovinAdSize.LEADER;
}

// Assume fluid width, and check for height with offset tolerance
final int offset = Math.abs( BANNER_STANDARD_HEIGHT - adSize.getHeight() );
if ( offset <= BANNER_HEIGHT_OFFSET_TOLERANCE )
{
return AppLovinAdSize.BANNER;
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ public class ApplovinAdapter
implements MediationBannerAdapter, MediationInterstitialAdapter,
MediationRewardedVideoAdAdapter, OnContextChangedListener {
private static final boolean LOGGING_ENABLED = true;
private static final String DEFAULT_ZONE = "";

private static final int BANNER_STANDARD_HEIGHT = 50;
private static final int BANNER_HEIGHT_OFFSET_TOLERANCE = 10;
private static final String DEFAULT_ZONE = "";

// Interstitial globals.
private static final HashMap<String, Queue<AppLovinAd>> INTERSTITIAL_AD_QUEUES =
Expand Down Expand Up @@ -338,9 +335,10 @@ public void requestBannerAd(Context context,
+ mZoneId + " and placement: " + mPlacement);

// Convert requested size to AppLovin Ad Size.
final AppLovinAdSize appLovinAdSize = appLovinAdSizeFromAdMobAdSize(adSize);
if (appLovinAdSize != null) {
mAdView = new AppLovinAdView(mSdk, appLovinAdSize, context);
final AppLovinAdSize appLovinAdSize = AppLovinUtils.appLovinAdSizeFromAdMobAdSize( adSize );
if ( appLovinAdSize != null )
{
mAdView = new AppLovinAdView( mSdk, appLovinAdSize, context );

final AppLovinBannerAdListener listener = new AppLovinBannerAdListener(
mZoneId, mPlacement, mAdView, this, mediationBannerListener);
Expand Down Expand Up @@ -372,27 +370,6 @@ public View getBannerView() {
}
//endregion

private AppLovinAdSize appLovinAdSizeFromAdMobAdSize(AdSize adSize) {
final boolean isSmartBanner = (adSize.getWidth() == AdSize.FULL_WIDTH) &&
(adSize.getHeight() == AdSize.AUTO_HEIGHT);

if (AdSize.BANNER.equals(adSize) || AdSize.LARGE_BANNER.equals(adSize) || isSmartBanner) {
return AppLovinAdSize.BANNER;
} else if (AdSize.MEDIUM_RECTANGLE.equals(adSize)) {
return AppLovinAdSize.MREC;
} else if (AdSize.LEADERBOARD.equals(adSize)) {
return AppLovinAdSize.LEADER;
}

// Assume fluid width, and check for height with offset tolerance
final int offset = Math.abs( BANNER_STANDARD_HEIGHT - adSize.getHeight() );
if (offset <= BANNER_HEIGHT_OFFSET_TOLERANCE) {
return AppLovinAdSize.BANNER;
}

return null;
}

//region MediationAdapter.
@Override
public void onPause() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package com.applovin.mediation.rtb;

import android.app.Application;
import android.text.TextUtils;
import android.util.Log;

import com.applovin.mediation.AppLovinUtils;
import com.applovin.sdk.AppLovinSdk;
import com.google.ads.mediation.sample.adapter.BuildConfig;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.mediation.rtb.AdRenderingCallback;
import com.google.android.gms.ads.mediation.rtb.BannerAd;
import com.google.android.gms.ads.mediation.rtb.BannerEventListener;
import com.google.android.gms.ads.mediation.rtb.InterstitialAd;
import com.google.android.gms.ads.mediation.rtb.InterstitialEventListener;
import com.google.android.gms.ads.mediation.rtb.RewardedAd;
import com.google.android.gms.ads.mediation.rtb.RewardedEventListener;
import com.google.android.gms.ads.mediation.rtb.RtbAdConfiguration;
import com.google.android.gms.ads.mediation.rtb.RtbAdapter;
import com.google.android.gms.ads.mediation.rtb.RtbConfiguration;
import com.google.android.gms.ads.mediation.rtb.RtbSignalData;
import com.google.android.gms.ads.mediation.rtb.SignalCallbacks;
import com.google.android.gms.ads.mediation.rtb.VersionInfo;

import java.util.List;

/**
* Created by Thomas So on July 17 2018
*/
public class AppLovinRtbAdapter
extends RtbAdapter
{
private static final String TAG = "AppLovinRtbAdapter";

// TODO: Why is this not in the base adapter?!
// @Override
// public void setUp()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this method in RtbAdapter in the latest version of the GMA SDK. I'm guessing that this method may have been dropped in favor of initialize()

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:/ inconsistent with iOS - we are going to figure out what's up.

// {
// AppLovinSdk.getInstance( new Application() ).initializeSdk();
// }

@Override
public void initialize()
{
AppLovinSdk.getInstance( new Application() ).initializeSdk();
}

@Override
public void updateConfiguration(final List<RtbConfiguration> list)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: Waiting on AdMob for action on this.

{
super.updateConfiguration( list );
}

@Override
public VersionInfo getSdkVersion()
{
String versionString = AppLovinSdk.VERSION;
String splits[] = versionString.split( "\\." );
int major = Integer.parseInt( splits[0] );
int minor = Integer.parseInt( splits[1] );
int patch = Integer.parseInt( splits[2] );

return new VersionInfo( major, minor, patch );
}

@Override
public VersionInfo getAdapterVersion()
{
String versionString = BuildConfig.VERSION_NAME;
String splits[] = versionString.split( "\\." );
int major = Integer.parseInt( splits[0] );
int minor = Integer.parseInt( splits[1] );
// Adapter versions have 2 patch versions. Multiply the first patch by 100.
int micro = Integer.parseInt( splits[2] ) * 100 + Integer.parseInt( splits[3] );

return new VersionInfo( major, minor, micro );
}

@Override
public void collectSignals(RtbSignalData rtbSignalData, SignalCallbacks signalCallbacks)
{
// TODO: I hope that we do not use the SDK Key and Context from here to initialize SDK / get bid token with...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we would be initializing the SDK here. We initialize it in either initialize() or setUp().
According to AdMob's docs:

collectSignals() is called on a background thread, and has a timeout of 1 second.

So, we should not be doing any heavy duty work here and try to callback with a bid token ASAP.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but we can't initialize our SDK in initialize() or setUp()(wherever that method is) b/c there is no Context parameter in those methods :/.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, makes sense. Didn't notice that they were not providing Context there.

// Check if the publisher provided extra parameters
if ( rtbSignalData.extras != null )
{
Log.i( TAG, "Extras for signal collection: " + rtbSignalData.extras );
}

AppLovinSdk sdk = AppLovinUtils.retrieveSdk( rtbSignalData.extras, rtbSignalData.context );
String bidToken = sdk.getAdService().getBidToken();

if ( !TextUtils.isEmpty( bidToken ) )
{
Log.i( TAG, "Generated bid token: " + bidToken );
signalCallbacks.onSuccess( bidToken );
}
else
{
String errorMessage = "Failed to generate bid token";
Log.e( TAG, errorMessage );
signalCallbacks.onFailure( errorMessage );
}
}

@Override
public void renderBannerAd(RtbAdConfiguration adConfiguration, AdSize adSize, AdRenderingCallback<BannerAd, BannerEventListener> callback)
{
AppLovinRtbBannerRenderer bannerRenderer = new AppLovinRtbBannerRenderer( adConfiguration, adSize, callback );
bannerRenderer.loadAd();
}

@Override
public void renderInterstitialAd(RtbAdConfiguration adConfiguration, AdRenderingCallback<InterstitialAd, InterstitialEventListener> callback)
{
AppLovinRtbInterstitialRenderer interstitialRenderer = new AppLovinRtbInterstitialRenderer( adConfiguration, callback );
interstitialRenderer.loadAd();
}

@Override
public void renderRewardedAd(RtbAdConfiguration adConfiguration, AdRenderingCallback<RewardedAd, RewardedEventListener> callback)
{
AppLovinRtbRewardedRenderer rewardedRenderer = new AppLovinRtbRewardedRenderer( adConfiguration, callback );
rewardedRenderer.loadAd();
}
}
Loading