diff --git a/extras/src/com/mopub/mobileads/AdColonyInterstitial.java b/extras/src/com/mopub/mobileads/AdColonyInterstitial.java index 6e42be9c2..3312cc45b 100644 --- a/extras/src/com/mopub/mobileads/AdColonyInterstitial.java +++ b/extras/src/com/mopub/mobileads/AdColonyInterstitial.java @@ -5,26 +5,22 @@ import android.os.Handler; import android.util.Log; -import com.jirbo.adcolony.AdColony; -import com.jirbo.adcolony.AdColonyAd; -import com.jirbo.adcolony.AdColonyAdListener; -import com.jirbo.adcolony.AdColonyVideoAd; +import com.adcolony.sdk.AdColony; +import com.adcolony.sdk.AdColonyAppOptions; +import com.adcolony.sdk.AdColonyInterstitialListener; +import com.adcolony.sdk.AdColonyZone; import com.mopub.common.util.Json; import java.util.Map; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -/* - * Tested with AdColony SDK 2.0.3. - */ -public class AdColonyInterstitial extends CustomEventInterstitial implements AdColonyAdListener { +public class AdColonyInterstitial extends CustomEventInterstitial { + private static final String TAG = "AdColonyInterstitial"; /* * We recommend passing the AdColony client options, app ID, all zone IDs, and current zone ID * in the serverExtras Map by specifying Custom Event Data in MoPub's web interface. * * Please see AdColony's documentation for more information: - * https://github.com/AdColony/AdColony-Android-SDK/wiki/API-Details#configure-activity-activity-string-client_options-string-app_id-string-zone_ids- + * https://github.com/AdColony/AdColony-Android-SDK-3 */ private static final String DEFAULT_CLIENT_OPTIONS = "version=YOUR_APP_VERSION_HERE,store:google"; private static final String DEFAULT_APP_ID = "YOUR_AD_COLONY_APP_ID_HERE"; @@ -39,16 +35,12 @@ public class AdColonyInterstitial extends CustomEventInterstitial implements AdC public static final String ALL_ZONE_IDS_KEY = "allZoneIds"; public static final String ZONE_ID_KEY = "zoneId"; - private static boolean isAdColonyConfigured = false; - private CustomEventInterstitialListener mCustomEventInterstitialListener; + private AdColonyInterstitialListener mAdColonyInterstitialListener; private final Handler mHandler; - private AdColonyVideoAd mAdColonyVideoAd; - private final ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor; - private boolean mIsLoading; + private com.adcolony.sdk.AdColonyInterstitial mAdColonyInterstitial; public AdColonyInterstitial() { - mScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); mHandler = new Handler(); } @@ -76,111 +68,167 @@ protected void loadInterstitial(Context context, zoneId = serverExtras.get(ZONE_ID_KEY); } - if (!isAdColonyConfigured) { - AdColony.configure((Activity)context, clientOptions, appId, allZoneIds); - isAdColonyConfigured = true; + mAdColonyInterstitialListener = getAdColonyInterstitialListener(); + if (!isAdColonyConfigured()) { + AdColony.configure((Activity) context, getAppOptions(clientOptions), appId, allZoneIds); } - mAdColonyVideoAd = new AdColonyVideoAd(zoneId); - mAdColonyVideoAd.withListener(this); - - scheduleOnInterstitialLoaded(); + AdColony.requestInterstitial(zoneId, mAdColonyInterstitialListener); } @Override protected void showInterstitial() { - if (mAdColonyVideoAd.isReady()) { - mAdColonyVideoAd.show(); + if (mAdColonyInterstitial == null || mAdColonyInterstitial.isExpired()) { + Log.e(TAG, "AdColony interstitial ad is null or has expired"); + mHandler.post(new Runnable() { + @Override + public void run() { + mCustomEventInterstitialListener.onInterstitialFailed(MoPubErrorCode.VIDEO_PLAYBACK_ERROR); + } + }); } else { - Log.d("MoPub", "Tried to show a AdColony interstitial ad before it finished loading. Please try again."); + mAdColonyInterstitial.show(); } } @Override protected void onInvalidate() { - if (mAdColonyVideoAd != null) { - mAdColonyVideoAd.withListener(null); + if (mAdColonyInterstitial != null) { + mAdColonyInterstitialListener = null; + mAdColonyInterstitial.setListener(null); + mAdColonyInterstitial.destroy(); + mAdColonyInterstitial = null; + } + } + + private AdColonyAppOptions getAppOptions(String clientOptions) { + if (clientOptions == null || clientOptions.isEmpty()) { + return null; + } + AdColonyAppOptions adColonyAppOptions = new AdColonyAppOptions(); + String[] allOptions = clientOptions.split(","); + for (String option : allOptions) { + String optionNameAndValue[] = option.split(":"); + if (optionNameAndValue.length == 2) { + switch (optionNameAndValue[0]) { + case "store": + adColonyAppOptions.setOriginStore(optionNameAndValue[1]); + break; + case "version": + adColonyAppOptions.setAppVersion(optionNameAndValue[1]); + break; + default: + Log.e(TAG, "AdColony client options in wrong format - please check your MoPub dashboard"); + return null; + } + } else { + Log.e(TAG, "AdColony client options in wrong format - please check your MoPub dashboard"); + return null; + } } - mScheduledThreadPoolExecutor.shutdownNow(); - mIsLoading = false; + return adColonyAppOptions; } - private boolean extrasAreValid(Map extras) { - return extras.containsKey(CLIENT_OPTIONS_KEY) - && extras.containsKey(APP_ID_KEY) - && extras.containsKey(ALL_ZONE_IDS_KEY) - && extras.containsKey(ZONE_ID_KEY); + private boolean isAdColonyConfigured() { + return !AdColony.getSDKVersion().isEmpty(); } - private String[] extractAllZoneIds(Map serverExtras) { - String[] result = Json.jsonArrayToStringArray(serverExtras.get(ALL_ZONE_IDS_KEY)); + private AdColonyInterstitialListener getAdColonyInterstitialListener() { + if (mAdColonyInterstitialListener != null) { + return mAdColonyInterstitialListener; + } else { + return new AdColonyInterstitialListener() { + @Override + public void onRequestFilled(com.adcolony.sdk.AdColonyInterstitial adColonyInterstitial) { + mAdColonyInterstitial = adColonyInterstitial; + Log.d(TAG, "AdColony interstitial ad has been successfully loaded."); + mHandler.post(new Runnable() { + @Override + public void run() { + mCustomEventInterstitialListener.onInterstitialLoaded(); + } + }); + } - // AdColony requires at least one valid String in the allZoneIds array. - if (result.length == 0) { - result = new String[]{""}; - } + @Override + public void onRequestNotFilled(AdColonyZone zone) { + Log.d(TAG, "AdColony interstitial ad has no fill."); + mHandler.post(new Runnable() { + @Override + public void run() { + mCustomEventInterstitialListener.onInterstitialFailed(MoPubErrorCode.NETWORK_NO_FILL); + } + }); + } - return result; - } + @Override + public void onClosed(com.adcolony.sdk.AdColonyInterstitial ad) { + Log.d(TAG, "AdColony interstitial ad has been dismissed."); + mHandler.post(new Runnable() { + @Override + public void run() { + mCustomEventInterstitialListener.onInterstitialDismissed(); + } + }); + } - private void scheduleOnInterstitialLoaded() { - Runnable runnable = new Runnable() { - @Override - public void run() { - if (mAdColonyVideoAd.isReady()) { - Log.d("MoPub", "AdColony interstitial ad successfully loaded."); - mIsLoading = false; - mScheduledThreadPoolExecutor.shutdownNow(); + @Override + public void onOpened(com.adcolony.sdk.AdColonyInterstitial ad) { + Log.d(TAG, "AdColony interstitial ad shown: " + ad.getZoneID()); mHandler.post(new Runnable() { @Override public void run() { - mCustomEventInterstitialListener.onInterstitialLoaded(); + mCustomEventInterstitialListener.onInterstitialShown(); } }); } - } - }; - if (!mIsLoading) { - mScheduledThreadPoolExecutor.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS); - mIsLoading = true; - } - } + @Override + public void onExpiring(com.adcolony.sdk.AdColonyInterstitial ad) { + Log.d(TAG, "AdColony interstitial ad is expiring; requesting new ad"); + AdColony.requestInterstitial(ad.getZoneID(), mAdColonyInterstitialListener); + } - /* - * AdColonyAdListener implementation - */ + @Override + public void onLeftApplication(com.adcolony.sdk.AdColonyInterstitial ad) { + mHandler.post(new Runnable() { + @Override + public void run() { + mCustomEventInterstitialListener.onLeaveApplication(); + } + }); + } - @Override - public void onAdColonyAdStarted(AdColonyAd adColonyAd) { - Log.d("MoPub", "AdColony interstitial ad shown."); - mHandler.post(new Runnable() { - @Override - public void run() { - mCustomEventInterstitialListener.onInterstitialShown(); - } - }); + @Override + public void onClicked(com.adcolony.sdk.AdColonyInterstitial ad) { + mCustomEventInterstitialListener.onInterstitialClicked(); + } + }; + } } - @Override - public void onAdColonyAdAttemptFinished(AdColonyAd adColonyAd) { - Log.d("MoPub", "AdColony interstitial ad dismissed."); - mHandler.post(new Runnable() { - @Override - public void run() { - mCustomEventInterstitialListener.onInterstitialDismissed(); - } - }); + private boolean extrasAreValid(Map extras) { + return extras.containsKey(CLIENT_OPTIONS_KEY) + && extras.containsKey(APP_ID_KEY) + && extras.containsKey(ALL_ZONE_IDS_KEY) + && extras.containsKey(ZONE_ID_KEY); } - @Deprecated // for testing - ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor() { - return mScheduledThreadPoolExecutor; + private String[] extractAllZoneIds(Map serverExtras) { + String[] result = Json.jsonArrayToStringArray(serverExtras.get(ALL_ZONE_IDS_KEY)); + + // AdColony requires at least one valid String in the allZoneIds array. + if (result.length == 0) { + result = new String[]{""}; + } + + return result; } - @Deprecated // for testing - void resetAdColonyConfigured() { - isAdColonyConfigured = false; + @Deprecated + // For testing + public static String getAdUnitId(MoPubInterstitial interstitial) { + return interstitial.getMoPubInterstitialView().getAdUnitId(); } } diff --git a/extras/src/com/mopub/mobileads/AdColonyRewardedVideo.java b/extras/src/com/mopub/mobileads/AdColonyRewardedVideo.java index 4d9baac46..8d81a6f76 100644 --- a/extras/src/com/mopub/mobileads/AdColonyRewardedVideo.java +++ b/extras/src/com/mopub/mobileads/AdColonyRewardedVideo.java @@ -4,39 +4,40 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.util.Log; + +import com.adcolony.sdk.AdColony; +import com.adcolony.sdk.AdColonyAdOptions; +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.jirbo.adcolony.AdColony; -import com.jirbo.adcolony.AdColonyAd; -import com.jirbo.adcolony.AdColonyAdListener; -import com.jirbo.adcolony.AdColonyV4VCAd; -import com.jirbo.adcolony.AdColonyV4VCListener; -import com.jirbo.adcolony.AdColonyV4VCReward; import com.mopub.common.BaseLifecycleListener; import com.mopub.common.DataKeys; import com.mopub.common.LifecycleListener; import com.mopub.common.MediationSettings; import com.mopub.common.MoPubReward; -import com.mopub.common.logging.MoPubLog; import com.mopub.common.util.Json; import java.util.Map; import java.util.WeakHashMap; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * A custom event for showing AdColony rewarded videos. - * - * Certified with AdColony 2.0.3 */ public class AdColonyRewardedVideo extends CustomEventRewardedVideo { + private static final String TAG = "AdColonyRewardedVideo"; /* * We recommend passing the AdColony client options, app ID, all zone IDs, and current zone ID * in the serverExtras Map by specifying Custom Event Data in MoPub's web interface. * * Please see AdColony's documentation for more information: - * https://github.com/AdColony/AdColony-Android-SDK/wiki/API-Details#configure-activity-activity-string-client_options-string-app_id-string-zone_ids- + * https://github.com/AdColony/AdColony-Android-SDK-3 */ private static final String DEFAULT_CLIENT_OPTIONS = "version=YOUR_APP_VERSION_HERE,store:google"; private static final String DEFAULT_APP_ID = "YOUR_AD_COLONY_APP_ID_HERE"; @@ -52,31 +53,23 @@ public class AdColonyRewardedVideo extends CustomEventRewardedVideo { public static final String ZONE_ID_KEY = "zoneId"; private static boolean sInitialized = false; - private static LifecycleListener sLifecycleListener = new BaseLifecycleListener() { - @Override - public void onPause(@NonNull final Activity activity) { - super.onPause(activity); - AdColony.pause(); - } - - @Override - public void onResume(@NonNull final Activity activity) { - super.onResume(activity); - AdColony.resume(activity); - } - }; - private static AdColonyListener sAdColonyListener = new AdColonyListener(); - private static WeakHashMap sAdToZoneIdMap = new WeakHashMap(); + private static LifecycleListener sLifecycleListener = new BaseLifecycleListener(); - private AdColonyV4VCAd mAd; + AdColonyInterstitial mAd; private String mZoneId; - @Nullable private String mAdUnitId; + private AdColonyListener mAdColonyListener; + private AdColonyAdOptions mAdColonyAdOptions = new AdColonyAdOptions(); + private AdColonyAppOptions mAdColonyAppOptions = new AdColonyAppOptions(); + private static WeakHashMap sZoneIdToAdMap = new WeakHashMap<>(); + + + @Nullable + private String mAdUnitId; private boolean mIsLoading = false; // For waiting and notifying the SDK: private final Handler mHandler; private final ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor; - private ScheduledFuture mFuture; public AdColonyRewardedVideo() { mScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); @@ -86,7 +79,7 @@ public AdColonyRewardedVideo() { @Nullable @Override public CustomEventRewardedVideoListener getVideoListenerForSdk() { - return sAdColonyListener; + return mAdColonyListener; } @Nullable @@ -104,12 +97,19 @@ public String getAdNetworkId() { @Override protected void onInvalidate() { mScheduledThreadPoolExecutor.shutdownNow(); + AdColonyInterstitial ad = sZoneIdToAdMap.get(mZoneId); + if (ad != null) { + ad.setListener(null); + ad.destroy(); + sZoneIdToAdMap.remove(mZoneId); + Log.d(TAG, "AdColony rewarded video destroyed"); + } } @Override public boolean checkAndInitializeSdk(@NonNull final Activity launcherActivity, - @NonNull final Map localExtras, - @NonNull final Map serverExtras) throws Exception { + @NonNull final Map localExtras, + @NonNull final Map serverExtras) throws Exception { synchronized (AdColonyRewardedVideo.class) { if (sInitialized) { return false; @@ -127,8 +127,12 @@ public boolean checkAndInitializeSdk(@NonNull final Activity launcherActivity, } setUpGlobalSettings(); - AdColony.configure(launcherActivity, adColonyClientOptions, adColonyAppId, adColonyAllZoneIds); - AdColony.addV4VCListener(sAdColonyListener); + setAppOptions(adColonyClientOptions); + + if (!isAdColonyConfigured()) { + AdColony.configure(launcherActivity, mAdColonyAppOptions, adColonyAppId, adColonyAllZoneIds); + } + sInitialized = true; return true; } @@ -136,8 +140,8 @@ public boolean checkAndInitializeSdk(@NonNull final Activity launcherActivity, @Override protected void loadWithSdkInitialized(@NonNull final Activity activity, - @NonNull final Map localExtras, - @NonNull final Map serverExtras) throws Exception { + @NonNull final Map localExtras, + @NonNull final Map serverExtras) throws Exception { mZoneId = DEFAULT_ZONE_ID; if (extrasAreValid(serverExtras)) { @@ -148,24 +152,66 @@ protected void loadWithSdkInitialized(@NonNull final Activity activity, mAdUnitId = (String) adUnitObject; } - mAd = new AdColonyV4VCAd(mZoneId).withListener(sAdColonyListener); - sAdToZoneIdMap.put(mAd, mZoneId); + sZoneIdToAdMap.put(mZoneId, null); + setUpAdOptions(); + mAdColonyListener = new AdColonyListener(mAdColonyAdOptions); + AdColony.setRewardListener(mAdColonyListener); + AdColony.requestInterstitial(mZoneId, mAdColonyListener, mAdColonyAdOptions); scheduleOnVideoReady(); } + private void setUpAdOptions() { + mAdColonyAdOptions.enableConfirmationDialog(getConfirmationDialogFromSettings()); + mAdColonyAdOptions.enableResultsDialog(getResultsDialogFromSettings()); + } + + private void setAppOptions(String clientOptions) { + if(android.text.TextUtils.isEmpty(clientOptions)) { + Log.d(TAG, "AdColony client options are not configured on the MoPub dashboard"); + return; + } + + String[] allOptions = clientOptions.split(","); + for (String option : allOptions) { + String optionNameAndValue[] = option.split(":"); + if (optionNameAndValue.length == 2) { + switch (optionNameAndValue[0]) { + case "store": + mAdColonyAppOptions.setOriginStore(optionNameAndValue[1]); + break; + case "version": + mAdColonyAppOptions.setAppVersion(optionNameAndValue[1]); + break; + default: + Log.e(TAG, "AdColony client options in wrong format - please check your MoPub dashboard"); + return; + } + } else { + Log.e(TAG, "AdColony client options is not recognized - please check your MoPub " + + "dashboard"); + return; + } + } + } + + private boolean isAdColonyConfigured() { + return !AdColony.getSDKVersion().isEmpty(); + } + @Override public boolean hasVideoAvailable() { - return mAd != null && mAd.isReady() && mAd.getAvailableViews() != 0; + return mAd != null && !mAd.isExpired(); } @Override public void showVideo() { if (this.hasVideoAvailable()) { - boolean withConfirmationDialog = getConfirmationDialogFromSettings(); - boolean withResultsDialog = getResultsDialogFromSettings(); - mAd.withConfirmationDialog(withConfirmationDialog).withResultsDialog(withResultsDialog).show(); + mAd.show(); } else { - MoPubRewardedVideoManager.onRewardedVideoPlaybackError(AdColonyRewardedVideo.class, mZoneId, MoPubErrorCode.VIDEO_PLAYBACK_ERROR); + MoPubRewardedVideoManager.onRewardedVideoPlaybackError( + AdColonyRewardedVideo.class, + mZoneId, + MoPubErrorCode.VIDEO_PLAYBACK_ERROR); } } @@ -191,11 +237,8 @@ private void setUpGlobalSettings() { final AdColonyGlobalMediationSettings globalMediationSettings = MoPubRewardedVideoManager.getGlobalMediationSettings(AdColonyGlobalMediationSettings.class); if (globalMediationSettings != null) { - if (globalMediationSettings.getCustomId() != null) { - AdColony.setCustomID(globalMediationSettings.getCustomId()); - } - if (globalMediationSettings.getDeviceId() != null) { - AdColony.setDeviceID(globalMediationSettings.getDeviceId()); + if (globalMediationSettings.getUserId() != null) { + mAdColonyAppOptions.setUserID(globalMediationSettings.getUserId()); } } } @@ -216,13 +259,15 @@ private void scheduleOnVideoReady() { Runnable runnable = new Runnable() { @Override public void run() { - if (mAd.isReady()) { + if (isAdAvailable(mZoneId)) { + mAd = sZoneIdToAdMap.get(mZoneId); mIsLoading = false; mScheduledThreadPoolExecutor.shutdownNow(); mHandler.post(new Runnable() { @Override public void run() { - if (mAd.getAvailableViews() > 0) { + if (hasVideoAvailable()) { + Log.d(TAG, "AdColony rewarded ad has been successfully loaded."); MoPubRewardedVideoManager.onRewardedVideoLoadSuccess( AdColonyRewardedVideo.class, mZoneId); @@ -244,71 +289,92 @@ public void run() { } } - private static class AdColonyListener implements AdColonyAdListener, - AdColonyV4VCListener, CustomEventRewardedVideoListener { - - @Override - public void onAdColonyAdAttemptFinished(final AdColonyAd adColonyAd) { - String zoneId = sAdToZoneIdMap.get(adColonyAd); - MoPubRewardedVideoManager.onRewardedVideoClosed(AdColonyRewardedVideo.class, zoneId); - if (adColonyAd.notShown()) { - if (adColonyAd.canceled() || adColonyAd.skipped()) { - MoPubLog.d("User canceled ad playback"); - return; - } - - MoPubErrorCode reason = MoPubErrorCode.VIDEO_DOWNLOAD_ERROR; - if (adColonyAd.noFill()) { - reason = MoPubErrorCode.NETWORK_NO_FILL; - } + private boolean isAdAvailable(String zoneId) { + return sZoneIdToAdMap.get(zoneId) != null; + } - MoPubRewardedVideoManager.onRewardedVideoLoadFailure( - AdColonyRewardedVideo.class, - zoneId, - reason); - } - } + private static class AdColonyListener extends AdColonyInterstitialListener + implements AdColonyRewardListener, CustomEventRewardedVideoListener { + private static final String TAG = "AdColonyListener"; + private AdColonyAdOptions mAdOptions; - @Override - public void onAdColonyAdStarted(final com.jirbo.adcolony.AdColonyAd adColonyAd) { - MoPubRewardedVideoManager.onRewardedVideoStarted( - AdColonyRewardedVideo.class, - sAdToZoneIdMap.get(adColonyAd)); + AdColonyListener(AdColonyAdOptions adOptions) { + mAdOptions = adOptions; } @Override - public void onAdColonyV4VCReward(final AdColonyV4VCReward adColonyV4VCReward) { + public void onReward(AdColonyReward a) { MoPubReward reward; - if (adColonyV4VCReward.success()) { - reward = MoPubReward.success(adColonyV4VCReward.name(), adColonyV4VCReward.amount()); + if (a.success()) { + Log.d(TAG, "AdColonyReward name: " + a.getRewardName()); + Log.d(TAG, "AdColonyReward amount: " + a.getRewardAmount()); + reward = MoPubReward.success(a.getRewardName(), a.getRewardAmount()); } else { + Log.d(TAG, "AdColonyReward failed"); reward = MoPubReward.failure(); } + MoPubRewardedVideoManager.onRewardedVideoCompleted( AdColonyRewardedVideo.class, - null, // Can't deduce the zoneId from this object. + a.getZoneID(), reward); } - } - public static final class AdColonyGlobalMediationSettings implements MediationSettings { + @Override + public void onRequestFilled(com.adcolony.sdk.AdColonyInterstitial adColonyInterstitial) { + sZoneIdToAdMap.put(adColonyInterstitial.getZoneID(), adColonyInterstitial); + } - @Nullable private final String mCustomId; - @Nullable private final String mDeviceId; + @Override + public void onRequestNotFilled(AdColonyZone zone) { + Log.d(TAG, "AdColony rewarded ad has no fill."); + MoPubRewardedVideoManager.onRewardedVideoLoadFailure( + AdColonyRewardedVideo.class, + zone.getZoneID(), + MoPubErrorCode.NETWORK_NO_FILL); + } - public AdColonyGlobalMediationSettings(@Nullable String customId, @Nullable String deviceId) { - mCustomId = customId; - mDeviceId = deviceId; + @Override + public void onClosed(com.adcolony.sdk.AdColonyInterstitial ad) { + Log.d(TAG, "AdColony rewarded ad has been dismissed."); + MoPubRewardedVideoManager.onRewardedVideoClosed( + AdColonyRewardedVideo.class, + ad.getZoneID()); } + @Override + public void onOpened(com.adcolony.sdk.AdColonyInterstitial ad) { + Log.d(TAG, "AdColony rewarded ad shown: " + ad.getZoneID()); + MoPubRewardedVideoManager.onRewardedVideoStarted( + AdColonyRewardedVideo.class, + ad.getZoneID()); + } + + @Override + public void onExpiring(com.adcolony.sdk.AdColonyInterstitial ad) { + Log.d(TAG, "AdColony rewarded ad is expiring; requesting new ad"); + AdColony.requestInterstitial(ad.getZoneID(), ad.getListener(), mAdOptions); + } + + @Override + public void onClicked(com.adcolony.sdk.AdColonyInterstitial ad) { + MoPubRewardedVideoManager.onRewardedVideoClicked( + AdColonyRewardedVideo.class, + ad.getZoneID()); + } + } + + public static final class AdColonyGlobalMediationSettings implements MediationSettings { @Nullable - public String getCustomId() { - return mCustomId; + private final String mUserId; + + public AdColonyGlobalMediationSettings(@Nullable String userId) { + mUserId = userId; } @Nullable - public String getDeviceId() { - return mDeviceId; + public String getUserId() { + return mUserId; } } diff --git a/extras/src/com/mopub/mobileads/UnityInterstitial.java b/extras/src/com/mopub/mobileads/UnityInterstitial.java new file mode 100644 index 000000000..4e2c9ece2 --- /dev/null +++ b/extras/src/com/mopub/mobileads/UnityInterstitial.java @@ -0,0 +1,118 @@ +package com.mopub.mobileads; + +import android.app.Activity; +import android.content.Context; + +import com.unity3d.ads.mediation.IUnityAdsExtendedListener; +import com.unity3d.ads.UnityAds; + +import java.util.Map; + +public class UnityInterstitial extends CustomEventInterstitial implements IUnityAdsExtendedListener { + + private static boolean sInitialized = false; + private static boolean sAdCached = false; + private CustomEventInterstitialListener mCustomEventInterstitialListener; + private Activity mLauncherActivity; + private String mPlacementId = "video"; + + @Override + protected void loadInterstitial(Context context, + CustomEventInterstitialListener customEventInterstitialListener, + Map localExtras, + Map serverExtras) { + + mPlacementId = UnityRouter.placementIdForServerExtras(serverExtras, mPlacementId); + mCustomEventInterstitialListener = customEventInterstitialListener; + + if (!sInitialized) { + if (context == null || !(context instanceof Activity)) { + mCustomEventInterstitialListener.onInterstitialFailed(MoPubErrorCode.NETWORK_INVALID_STATE); + return; + } + + mLauncherActivity = (Activity) context; + + if (!UnityRouter.initUnityAds(serverExtras, mLauncherActivity, this, new Runnable() { + public void run() { + mCustomEventInterstitialListener.onInterstitialFailed(MoPubErrorCode.NETWORK_INVALID_STATE); + } + })) { + return; + } + + UnityAds.setListener(this); + + UnityRouter.initPlacement(mPlacementId, new Runnable() { + public void run() { + mCustomEventInterstitialListener.onInterstitialFailed(MoPubErrorCode.NETWORK_INVALID_STATE); + } + }, new Runnable() { + public void run() { + mCustomEventInterstitialListener.onInterstitialLoaded(); + } + }); + + sInitialized = true; + } else { + UnityAds.setListener(this); + if (UnityAds.isReady(mPlacementId)) { + mCustomEventInterstitialListener.onInterstitialLoaded(); + } else { + sAdCached = false; + } + } + } + + @Override + protected void showInterstitial() { + if (UnityAds.isReady(mPlacementId) && mLauncherActivity != null) { + UnityAds.show(mLauncherActivity, mPlacementId); + } + } + + @Override + protected void onInvalidate() { + UnityAds.setListener(null); + } + + @Override + public void onUnityAdsReady(String placementId) { + if (!sAdCached && placementId.equals(mPlacementId)) { + sAdCached = true; + mCustomEventInterstitialListener.onInterstitialLoaded(); + } + } + + @Override + public void onUnityAdsStart(String s) { + mCustomEventInterstitialListener.onInterstitialShown(); + } + + @Override + public void onUnityAdsFinish(String s, UnityAds.FinishState finishState) { + mCustomEventInterstitialListener.onInterstitialDismissed(); + } + + @Override + public void onUnityAdsClick(String placementId) { + mCustomEventInterstitialListener.onInterstitialClicked(); + } + + @Override + public void onUnityAdsError(UnityAds.UnityAdsError unityAdsError, String s) { + MoPubErrorCode errorCode; + switch (unityAdsError) { + case VIDEO_PLAYER_ERROR: + errorCode = MoPubErrorCode.VIDEO_PLAYBACK_ERROR; + break; + case INTERNAL_ERROR: + errorCode = MoPubErrorCode.INTERNAL_ERROR; + break; + default: + errorCode = MoPubErrorCode.NETWORK_INVALID_STATE; + break; + } + mCustomEventInterstitialListener.onInterstitialFailed(errorCode); + } +} \ No newline at end of file diff --git a/extras/src/com/mopub/mobileads/UnityRewardedVideo.java b/extras/src/com/mopub/mobileads/UnityRewardedVideo.java index f4fe4bcc9..feaea2cfc 100644 --- a/extras/src/com/mopub/mobileads/UnityRewardedVideo.java +++ b/extras/src/com/mopub/mobileads/UnityRewardedVideo.java @@ -3,38 +3,31 @@ import android.app.Activity; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.text.TextUtils; import com.mopub.common.BaseLifecycleListener; -import com.mopub.common.DataKeys; import com.mopub.common.LifecycleListener; -import com.mopub.common.MediationSettings; import com.mopub.common.MoPubReward; import com.mopub.common.VisibleForTesting; import com.mopub.common.logging.MoPubLog; -import com.unity3d.ads.android.IUnityAdsListener; -import com.unity3d.ads.android.UnityAds; +import com.unity3d.ads.mediation.IUnityAdsExtendedListener; +import com.unity3d.ads.UnityAds; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; /** * A custom event for showing Unity rewarded videos. - * - * Certified with Unity 1.4.7 */ public class UnityRewardedVideo extends CustomEventRewardedVideo { - private static final String DEFAULT_ZONE_ID = ""; private static final String GAME_ID_KEY = "gameId"; - private static final String ZONE_ID_KEY = "zoneId"; private static final LifecycleListener sLifecycleListener = new UnityLifecycleListener(); private static final UnityAdsListener sUnityAdsListener = new UnityAdsListener(); private static boolean sInitialized = false; - @NonNull private static String sZoneId = DEFAULT_ZONE_ID; + private static boolean sAdCached = false; + private static String sPlacementId = "rewardedVideo"; - @Nullable private UnityMediationSettings mMediationSettings; + @Nullable + private Activity mLauncherActivity; @Override @NonNull @@ -51,30 +44,24 @@ public LifecycleListener getLifecycleListener() { @Override @NonNull public String getAdNetworkId() { - return sZoneId; + return sPlacementId; } @Override public boolean checkAndInitializeSdk(@NonNull final Activity launcherActivity, - @NonNull final Map localExtras, - @NonNull final Map serverExtras) throws Exception { + @NonNull final Map localExtras, + @NonNull final Map serverExtras) throws Exception { if (sInitialized) { return false; } - String gameId; - if (serverExtras.containsKey(GAME_ID_KEY)) { - gameId = serverExtras.get(GAME_ID_KEY); - if (TextUtils.isEmpty(gameId)) { + UnityRouter.initUnityAds(serverExtras, launcherActivity, sUnityAdsListener, new Runnable() { + @Override + public void run() { throw new IllegalStateException("Unity rewarded video initialization failed due " + - "to empty " + GAME_ID_KEY); + "to empty or missing " + GAME_ID_KEY); } - } else { - throw new IllegalStateException("Unity rewarded video initialization failed due to " + - "missing " + GAME_ID_KEY); - } - - UnityAds.init(launcherActivity, gameId, sUnityAdsListener); + }); sInitialized = true; return true; @@ -82,32 +69,40 @@ public boolean checkAndInitializeSdk(@NonNull final Activity launcherActivity, @Override protected void loadWithSdkInitialized(@NonNull Activity activity, - @NonNull Map localExtras, @NonNull Map serverExtras) + @NonNull Map localExtras, + @NonNull Map serverExtras) throws Exception { - if (serverExtras.containsKey(ZONE_ID_KEY)) { - String zoneId = serverExtras.get(ZONE_ID_KEY); - sZoneId = TextUtils.isEmpty(zoneId) ? sZoneId : zoneId; - } - - try { - setUpMediationSettingsForRequest((String) localExtras.get(DataKeys.AD_UNIT_ID_KEY)); - } catch (ClassCastException e) { - MoPubLog.e("Failed to set up Unity mediation settings due to invalid ad unit id", e); - } + sPlacementId = UnityRouter.placementIdForServerExtras(serverExtras, sPlacementId); + mLauncherActivity = activity; + UnityAds.setListener(sUnityAdsListener); - loadRewardedVideo(); + UnityRouter.initPlacement(sPlacementId, new Runnable() { + @Override + public void run() { + MoPubRewardedVideoManager.onRewardedVideoLoadFailure(UnityRewardedVideo.class, sPlacementId, MoPubErrorCode.ADAPTER_CONFIGURATION_ERROR); + } + }, new Runnable() { + @Override + public void run() { + if (UnityAds.isReady(sPlacementId)) { + MoPubRewardedVideoManager.onRewardedVideoLoadSuccess(UnityRewardedVideo.class, sPlacementId); + } else { + sAdCached = false; + } + } + }); } @Override public boolean hasVideoAvailable() { - return UnityAds.canShow(); + return UnityRouter.hasVideoAvailable(sPlacementId); } @Override public void showVideo() { if (hasVideoAvailable()) { - UnityAds.show(getUnityProperties()); + UnityAds.show(mLauncherActivity, sPlacementId); } else { MoPubLog.d("Attempted to show Unity rewarded video before it was available."); } @@ -118,120 +113,78 @@ protected void onInvalidate() { UnityAds.setListener(null); } - - private void setUpMediationSettingsForRequest(@Nullable final String moPubId) { - mMediationSettings = - MoPubRewardedVideoManager.getGlobalMediationSettings(UnityMediationSettings.class); - - // Instance settings override global settings. - if (moPubId != null) { - final UnityMediationSettings instanceSettings = MoPubRewardedVideoManager - .getInstanceMediationSettings(UnityMediationSettings.class, moPubId); - if (instanceSettings != null) { - mMediationSettings = instanceSettings; - } - } - - } - private static final class UnityLifecycleListener extends BaseLifecycleListener { @Override public void onCreate(@NonNull final Activity activity) { super.onCreate(activity); - UnityAds.changeActivity(activity); } @Override public void onResume(@NonNull final Activity activity) { super.onResume(activity); - UnityAds.changeActivity(activity); } } - @NonNull - private Map getUnityProperties() { - if (mMediationSettings == null) { - return Collections.emptyMap(); - } - return mMediationSettings.getPropertiesMap(); - } - - - private static class UnityAdsListener implements IUnityAdsListener, + private static class UnityAdsListener implements IUnityAdsExtendedListener, CustomEventRewardedVideoListener { @Override - public void onFetchCompleted() { - MoPubLog.d("Unity rewarded video cached for zone " + UnityAds.getZone() + "."); - loadRewardedVideo(); - } - - @Override - public void onFetchFailed() { - MoPubLog.d("Unity rewarded video cache failed for zone " + UnityAds.getZone() + "."); - MoPubRewardedVideoManager.onRewardedVideoLoadFailure(UnityRewardedVideo.class, - UnityAds.getZone(), MoPubErrorCode.NETWORK_NO_FILL); - } - - @Override - public void onShow() { - MoPubLog.d("Unity rewarded video displayed for zone " + UnityAds.getZone() + "."); - } - - @Override - public void onHide() { - MoPubRewardedVideoManager.onRewardedVideoClosed(UnityRewardedVideo.class, UnityAds.getZone()); - MoPubLog.d("Unity rewarded video dismissed for zone " + UnityAds.getZone() + "."); + public void onUnityAdsReady(String placementId) { + if (!sAdCached && placementId.equals(sPlacementId)) { + sAdCached = true; + MoPubLog.d("Unity rewarded video cached for placement " + placementId + "."); + MoPubRewardedVideoManager.onRewardedVideoLoadSuccess(UnityRewardedVideo.class, placementId); + } } @Override - public void onVideoStarted() { - MoPubRewardedVideoManager.onRewardedVideoStarted(UnityRewardedVideo.class, UnityAds.getZone()); - MoPubLog.d("Unity rewarded video started for zone " + UnityAds.getZone() + "."); + public void onUnityAdsStart(String placementId) { + MoPubRewardedVideoManager.onRewardedVideoStarted(UnityRewardedVideo.class, placementId); + MoPubLog.d("Unity rewarded video started for placement " + placementId + "."); } @Override - public void onVideoCompleted(final String itemKey, final boolean skipped) { - if (!skipped) { + public void onUnityAdsFinish(String placementId, UnityAds.FinishState finishState) { + if (finishState == UnityAds.FinishState.ERROR) { + MoPubRewardedVideoManager.onRewardedVideoPlaybackError( + UnityRewardedVideo.class, + sPlacementId, + MoPubErrorCode.VIDEO_PLAYBACK_ERROR); + MoPubLog.d("Unity rewarded video encountered a playback error for placement " + placementId); + } else if (finishState == UnityAds.FinishState.COMPLETED) { MoPubRewardedVideoManager.onRewardedVideoCompleted( UnityRewardedVideo.class, - UnityAds.getZone(), - MoPubReward.success(itemKey, MoPubReward.NO_REWARD_AMOUNT)); - MoPubLog.d("Unity rewarded video completed for zone " + UnityAds.getZone() - + " with reward item key " + itemKey); + sPlacementId, + MoPubReward.success(MoPubReward.NO_REWARD_LABEL, MoPubReward.NO_REWARD_AMOUNT)); + MoPubLog.d("Unity rewarded video completed for placement " + placementId); } else { MoPubRewardedVideoManager.onRewardedVideoCompleted( UnityRewardedVideo.class, - UnityAds.getZone(), + placementId, MoPubReward.failure()); - MoPubLog.d("Unity rewarded video skipped for zone " + UnityAds.getZone() + " with " - + "reward item key " + itemKey); + MoPubLog.d("Unity rewarded video skipped for placement " + placementId); } + MoPubRewardedVideoManager.onRewardedVideoClosed(UnityRewardedVideo.class, sPlacementId); + UnityAds.setListener(null); } - } - - private static void loadRewardedVideo() { - UnityAds.setZone(sZoneId); - MoPubRewardedVideoManager.onRewardedVideoLoadSuccess(UnityRewardedVideo.class, UnityAds.getZone()); - } - public static final class UnityMediationSettings implements MediationSettings { - @NonNull private final HashMap mProperties; - - public UnityMediationSettings(@NonNull final String gamerId) { - mProperties = new HashMap(); - mProperties.put(UnityAds.UNITY_ADS_OPTION_GAMERSID_KEY, gamerId); + @Override + public void onUnityAdsClick(String placementId) { + MoPubRewardedVideoManager.onRewardedVideoClicked(UnityRewardedVideo.class, placementId); + MoPubLog.d("Unity rewarded video clicked for placement " + placementId + "."); } - @NonNull - public Map getPropertiesMap() { - return mProperties; + @Override + public void onUnityAdsError(UnityAds.UnityAdsError unityAdsError, String message) { + MoPubLog.d("Unity rewarded video cache failed for placement " + sPlacementId + "."); + MoPubRewardedVideoManager.onRewardedVideoLoadFailure(UnityRewardedVideo.class, + sPlacementId, MoPubErrorCode.NETWORK_NO_FILL); } } @VisibleForTesting void reset() { sInitialized = false; - sZoneId = DEFAULT_ZONE_ID; + sPlacementId = ""; } } diff --git a/extras/src/com/mopub/mobileads/UnityRouter.java b/extras/src/com/mopub/mobileads/UnityRouter.java new file mode 100644 index 000000000..a86ed26bb --- /dev/null +++ b/extras/src/com/mopub/mobileads/UnityRouter.java @@ -0,0 +1,62 @@ +package com.mopub.mobileads; + +import android.app.Activity; +import android.text.TextUtils; + +import com.mopub.common.MoPub; +import com.unity3d.ads.mediation.IUnityAdsExtendedListener; +import com.unity3d.ads.UnityAds; +import com.unity3d.ads.metadata.MediationMetaData; + +import java.util.Map; + +public class UnityRouter { + private static final String GAME_ID_KEY = "gameId"; + private static final String ZONE_ID_KEY = "zoneId"; + private static final String PLACEMENT_ID_KEY = "placementId"; + + static boolean initUnityAds(Map serverExtras, Activity launcherActivity, IUnityAdsExtendedListener unityAdsListener, Runnable onInitFailed) { + String gameId; + if (serverExtras.containsKey(GAME_ID_KEY)) { + gameId = serverExtras.get(GAME_ID_KEY); + if (TextUtils.isEmpty(gameId)) { + onInitFailed.run(); + return false; + } + } else { + onInitFailed.run(); + return false; + } + + MediationMetaData mediationMetaData = new MediationMetaData(launcherActivity); + mediationMetaData.setName("MoPub"); + mediationMetaData.setVersion(MoPub.SDK_VERSION); + mediationMetaData.commit(); + + UnityAds.initialize(launcherActivity, gameId, unityAdsListener); + return true; + } + + static String placementIdForServerExtras(Map serverExtras, String defaultPlacementId) { + String placementId = null; + if (serverExtras.containsKey(PLACEMENT_ID_KEY)) { + placementId = serverExtras.get(PLACEMENT_ID_KEY); + } else if (serverExtras.containsKey(ZONE_ID_KEY)) { + placementId = serverExtras.get(ZONE_ID_KEY); + } + return TextUtils.isEmpty(placementId) ? defaultPlacementId : placementId; + } + + static void initPlacement(String placementId, Runnable onInitFailure, Runnable onInitSuccess) { + if (TextUtils.isEmpty(placementId)) { + onInitFailure.run(); + } else if (hasVideoAvailable(placementId)) { + onInitSuccess.run(); + } + } + + static boolean hasVideoAvailable(String placementId) { + return UnityAds.isReady(placementId); + } + +} \ No newline at end of file