package com.appboy.unity; import android.app.Activity; import android.content.Intent; import com.appboy.Constants; import com.appboy.models.IInAppMessage; import com.appboy.models.MessageButton; import com.appboy.support.AppboyLogger; import com.appboy.ui.inappmessage.AppboyInAppMessageManager; import com.appboy.ui.inappmessage.InAppMessageCloser; import com.appboy.ui.inappmessage.InAppMessageOperation; import com.appboy.ui.inappmessage.listeners.IInAppMessageManagerListener; import com.unity3d.player.UnityPlayerNativeActivity; public class AppboyUnityNativeInAppMessageManagerListener implements IInAppMessageManagerListener { private static final String TAG = String.format("%s.%s", Constants.APPBOY_LOG_TAG_PREFIX, AppboyUnityNativeInAppMessageManagerListener.class.getName()); private static volatile AppboyUnityNativeInAppMessageManagerListener sInstance; private UnityPlayerNativeActivity mContainerActivity; private AppboyOverlayActivity mOverlayActivity; private boolean mShowInAppMessagesManually = false; private IAppboyUnityInAppMessageListener mAppboyUnityInAppMessageListener; private AppboyUnityNativeInAppMessageManagerListener() { } public static AppboyUnityNativeInAppMessageManagerListener getInstance() { if (sInstance == null) { synchronized (AppboyUnityNativeInAppMessageManagerListener.class) { if (sInstance == null) { sInstance = new AppboyUnityNativeInAppMessageManagerListener(); } } } return sInstance; } /** * Assigns a custom IAppboyUnityInAppMessageListener that will be used when displaying in-app messages. * To un-assign your listener, call this method again with a null listener. * * @param appboyUnityInAppMessageListener A custom IAppboyUnityInAppMessageListener or null (to un-assign * your listener). */ public void setUnityInAppMessageListener(IAppboyUnityInAppMessageListener appboyUnityInAppMessageListener) { mAppboyUnityInAppMessageListener = appboyUnityInAppMessageListener; } /** * Call to register a container activity (the game activity) that will be returned to * after the in-app message displays. * * @param containerActivity a UnityPlayerNativeActivity instance */ public void registerContainerActivity(UnityPlayerNativeActivity containerActivity) { mContainerActivity = containerActivity; } /** * The overlay activity instance must register with AppboyUnityNativeInAppMessageManagerListener once * it is created. This is because we need to have an {@link AppboyOverlayActivity} instance registered before * we request the display of an in-app message, to ensure the in-app message will use it. * * We then call {@link AppboyInAppMessageManager#requestDisplayInAppMessage()} to trigger display * of the in-app message from within the {@link AppboyOverlayActivity} * * See {@link #beforeInAppMessageDisplayed(IInAppMessage)} * * @param overlayActivity an AppboyOverlayActivity instance */ public void registerOverlayActivityAndRequestDisplay(AppboyOverlayActivity overlayActivity) { if (mContainerActivity == null) { AppboyLogger.w(TAG, "No container activity is registered. You must register a container activity " + "before registering or un-registering an overlay activity."); finishOverlayActivity(); return; } mOverlayActivity = overlayActivity; AppboyInAppMessageManager.getInstance().registerInAppMessageManager(mOverlayActivity); AppboyInAppMessageManager.getInstance().requestDisplayInAppMessage(); } /** * Unregister the overlay activity instance with AppboyUnityNativeInAppMessageManagerListener once * it is being destroyed. * * Re-register the container activity. */ public void unregisterOverlayActivityAndReRegisterContainer() { if (mContainerActivity == null) { AppboyLogger.w(TAG, "No container activity is registered. You must register a container activity " + "before registering or un-registering an overlay activity."); finishOverlayActivity(); return; } AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false); AppboyInAppMessageManager.getInstance().unregisterInAppMessageManager(mOverlayActivity); if (mContainerActivity != null) { AppboyInAppMessageManager.getInstance().registerInAppMessageManager(mContainerActivity); } finishOverlayActivity(); } /** * See {@link IInAppMessageManagerListener#onInAppMessageReceived(IInAppMessage)} */ @Override public boolean onInAppMessageReceived(IInAppMessage inAppMessage) { if (mAppboyUnityInAppMessageListener != null) { return mAppboyUnityInAppMessageListener.onInAppMessageReceived(inAppMessage); } return mShowInAppMessagesManually; } /** * If mOverlayActivity is null, we create a new {@link AppboyOverlayActivity}. The new activity * will automatically register itself via {@link #registerOverlayActivityAndRequestDisplay(AppboyOverlayActivity)}. At that * point, display will be re-requested. * * At this point, mOverlayActivity should no longer be null, and we display the in-app message * on mOverlayActivity. * * {@link IInAppMessage#setAnimateIn(boolean)} is set to false because activities already have * their own animation. * * See {@link IInAppMessageManagerListener#beforeInAppMessageDisplayed(IInAppMessage)} */ @Override public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) { if (mContainerActivity == null) { AppboyLogger.w(TAG, "No container activity is registered. You must register a container activity " + "before an in-app message can be displayed."); return InAppMessageOperation.DISPLAY_LATER; } if (mOverlayActivity != null) { inAppMessage.setAnimateIn(false); return InAppMessageOperation.DISPLAY_NOW; } else { startOverlayActivity(); return InAppMessageOperation.DISPLAY_LATER; } } /** * See {@link IInAppMessageManagerListener#onInAppMessageClicked(IInAppMessage, InAppMessageCloser)} */ @Override public boolean onInAppMessageClicked(IInAppMessage inAppMessage, InAppMessageCloser inAppMessageCloser) { inAppMessageCloser.close(true); finishOverlayActivity(); if (mAppboyUnityInAppMessageListener != null) { return mAppboyUnityInAppMessageListener.onInAppMessageClicked(inAppMessage); } return false; } /** * See {@link IInAppMessageManagerListener#onInAppMessageButtonClicked(MessageButton, InAppMessageCloser)} */ @Override public boolean onInAppMessageButtonClicked(MessageButton button, InAppMessageCloser inAppMessageCloser) { inAppMessageCloser.close(true); finishOverlayActivity(); if (mAppboyUnityInAppMessageListener != null) { return mAppboyUnityInAppMessageListener.onInAppMessageButtonClicked(button); } return false; } /** * See {@link IInAppMessageManagerListener#onInAppMessageDismissed(IInAppMessage)} */ @Override public void onInAppMessageDismissed(IInAppMessage inAppMessage) { finishOverlayActivity(); } /** * Allows the client to specify that they will handle the display of in-app messages * themselves. If set, Appboy will not handle the display of incoming in-app messages. * * @param showInAppMessagesManually whether the client will handle in-app messages * themselves. */ void setShowInAppMessagesManually(boolean showInAppMessagesManually) { mShowInAppMessagesManually = showInAppMessagesManually; } /** * Finish and null out mOverlayActivity if available. This is called whenever an in-app message * is closed, ensuring that we don't leak mOverlayActivity. * * See {@link Activity#finish()} */ private void finishOverlayActivity() { if (mOverlayActivity != null) { mOverlayActivity.finish(); mOverlayActivity = null; } } /** * Start a new Overlay activity and assign it to mOverlayActivity. * * mContainerActivity may not be null. */ private void startOverlayActivity() { Intent overlayIntent = new Intent(mContainerActivity, AppboyOverlayActivity.class); mContainerActivity.startActivity(overlayIntent); } }