package com.mopub.mobileads;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.mopub.common.AdReport;
import com.mopub.common.VisibleForTesting;
import com.mopub.common.logging.MoPubLog;
import com.mopub.mobileads.CustomEventInterstitial.CustomEventInterstitialListener;
import com.mopub.mraid.MraidController;
import com.mopub.mraid.MraidController.MraidListener;
import com.mopub.mraid.MraidController.UseCustomCloseListener;
import com.mopub.mraid.MraidWebViewDebugListener;
import com.mopub.mraid.PlacementType;
import static com.mopub.common.DataKeys.AD_REPORT_KEY;
import static com.mopub.common.DataKeys.BROADCAST_IDENTIFIER_KEY;
import static com.mopub.common.DataKeys.HTML_RESPONSE_BODY_KEY;
import static com.mopub.mobileads.BaseInterstitialActivity.JavaScriptWebViewCallbacks.WEB_VIEW_DID_APPEAR;
import static com.mopub.mobileads.BaseInterstitialActivity.JavaScriptWebViewCallbacks.WEB_VIEW_DID_CLOSE;
import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_CLICK;
import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_DISMISS;
import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_FAIL;
import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_SHOW;
import static com.mopub.mobileads.EventForwardingBroadcastReceiver.broadcastAction;
public class MraidActivity extends BaseInterstitialActivity {
@Nullable private MraidController mMraidController;
@Nullable private MraidWebViewDebugListener mDebugListener;
public static void preRenderHtml(@NonNull final Context context,
@NonNull final CustomEventInterstitialListener customEventInterstitialListener,
@NonNull final String htmlData) {
BaseWebView dummyWebView = new BaseWebView(context);
dummyWebView.enablePlugins(false);
dummyWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(final WebView view, final String url) {
customEventInterstitialListener.onInterstitialLoaded();
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
@Override
public void onReceivedError(final WebView view, final int errorCode,
final String description,
final String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
customEventInterstitialListener.onInterstitialFailed(
MoPubErrorCode.MRAID_LOAD_ERROR);
}
});
dummyWebView.loadDataWithBaseURL(null, htmlData, "text/html", "UTF-8", null);
}
public static void start(@NonNull Context context, @Nullable AdReport adreport, @NonNull String htmlData, long broadcastIdentifier) {
Intent intent = createIntent(context, adreport, htmlData, broadcastIdentifier);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException exception) {
Log.d("MraidInterstitial", "MraidActivity.class not found. Did you declare MraidActivity in your manifest?");
}
}
@VisibleForTesting
protected static Intent createIntent(@NonNull Context context, @Nullable AdReport adReport,
@NonNull String htmlData, long broadcastIdentifier) {
Intent intent = new Intent(context, MraidActivity.class);
intent.putExtra(HTML_RESPONSE_BODY_KEY, htmlData);
intent.putExtra(BROADCAST_IDENTIFIER_KEY, broadcastIdentifier);
intent.putExtra(AD_REPORT_KEY, adReport);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
@Override
public View getAdView() {
String htmlData = getIntent().getStringExtra(HTML_RESPONSE_BODY_KEY);
if (htmlData == null) {
MoPubLog.w("MraidActivity received a null HTML body. Finishing the activity.");
finish();
return new View(this);
}
mMraidController = new MraidController(
this, mAdReport, PlacementType.INTERSTITIAL);
mMraidController.setDebugListener(mDebugListener);
mMraidController.setMraidListener(new MraidListener() {
@Override
public void onLoaded(View view) {
// This is only done for the interstitial. Banners have a different mechanism
// for tracking third party impressions.
mMraidController.loadJavascript(WEB_VIEW_DID_APPEAR.getJavascript());
}
@Override
public void onFailedToLoad() {
MoPubLog.d("MraidActivity failed to load. Finishing the activity");
broadcastAction(MraidActivity.this, getBroadcastIdentifier(),
ACTION_INTERSTITIAL_FAIL);
finish();
}
public void onClose() {
mMraidController.loadJavascript(WEB_VIEW_DID_CLOSE.getJavascript());
finish();
}
@Override
public void onExpand() {
// No-op. The interstitial is always expanded.
}
@Override
public void onOpen() {
broadcastAction(MraidActivity.this, getBroadcastIdentifier(),
ACTION_INTERSTITIAL_CLICK);
}
});
// Needed because the Activity provides the close button, not the controller. This
// gets called if the creative calls mraid.useCustomClose.
mMraidController.setUseCustomCloseListener(new UseCustomCloseListener() {
public void useCustomCloseChanged(boolean useCustomClose) {
if (useCustomClose) {
hideInterstitialCloseButton();
} else {
showInterstitialCloseButton();
}
}
});
mMraidController.loadContent(htmlData);
return mMraidController.getAdContainer();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
broadcastAction(this, getBroadcastIdentifier(), ACTION_INTERSTITIAL_SHOW);
if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
}
@Override
protected void onPause() {
if (mMraidController != null) {
mMraidController.pause();
}
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if (mMraidController != null) {
mMraidController.resume();
}
}
@Override
protected void onDestroy() {
if (mMraidController != null) {
mMraidController.destroy();
}
broadcastAction(this, getBroadcastIdentifier(), ACTION_INTERSTITIAL_DISMISS);
super.onDestroy();
}
@VisibleForTesting
public void setDebugListener(@Nullable MraidWebViewDebugListener debugListener) {
mDebugListener = debugListener;
if (mMraidController != null) {
mMraidController.setDebugListener(debugListener);
}
}
}