package org.mtransit.android.util;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import org.mtransit.android.R;
import org.mtransit.android.commons.ArrayUtils;
import org.mtransit.android.commons.MTLog;
import org.mtransit.android.commons.TaskUtils;
import org.mtransit.android.commons.task.MTAsyncTask;
import org.mtransit.android.data.DataSourceProvider;
import org.mtransit.android.ui.MTActivityWithLocation;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.view.View;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
public final class AdsUtils implements MTLog.Loggable {
private static final String TAG = AdsUtils.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private static boolean AD_ENABLED = true;
private static final boolean DEBUG = false;
private static Boolean showingAds = null;
private static Boolean adLoaded = null;
private static final ArrayList<String> KEYWORDS = ArrayUtils.asArrayList("transit", "transport", "bus", "subway", "metro", "taxi", "bike", "sharing",
"velo", "train", "ferries", "boat", "trail", "lrt", "streetcar", "traversier", "tram", "tramway");
private static void setupAd(Activity activity) {
if (!AD_ENABLED) {
return;
}
if (!isShowingAds(activity)) {
return;
}
if (setupAdTask == null) {
setupAdTask = new SetupAdTask(activity);
TaskUtils.execute(setupAdTask);
}
}
private static SetupAdTask setupAdTask;
private static class SetupAdTask extends MTAsyncTask<Void, Void, Boolean> {
private static final String TAG = AdsUtils.class.getSimpleName() + ">" + SetupAdTask.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private WeakReference<Activity> activityWR;
public SetupAdTask(Activity activity) {
this.activityWR = new WeakReference<Activity>(activity);
}
@Override
protected Boolean doInBackgroundMT(Void... params) {
if (!AD_ENABLED) {
return false;
}
Activity activity = this.activityWR == null ? null : this.activityWR.get();
return !isCancelled() && isShowingAds(activity);
}
@Override
protected void onPostExecute(Boolean result) {
Activity activity = this.activityWR == null ? null : this.activityWR.get();
if (activity != null && result && !isCancelled()) { // show ads
View adLayout = activity.findViewById(R.id.ad_layout);
if (adLayout != null) {
AdView adView = (AdView) adLayout.findViewById(R.id.ad);
if (adView != null) {
adView.setAdListener(new MTAdListener(activity));
AdRequest.Builder adRequestBd = new AdRequest.Builder();
if (activity instanceof MTActivityWithLocation) {
adRequestBd.setLocation(((MTActivityWithLocation) activity).getLastLocation());
}
for (String keyword : KEYWORDS) {
adRequestBd.addKeyword(keyword);
}
if (DEBUG) {
adRequestBd.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
for (String deviceId : activity.getResources().getStringArray(R.array.google_ads_test_devices_ids)) {
adRequestBd.addTestDevice(deviceId);
}
}
adView.loadAd(adRequestBd.build());
}
}
} else { // hide ads
hideAds(activity);
}
}
}
private static class MTAdListener extends AdListener {
private WeakReference<Activity> activityWR;
public MTAdListener(Activity activity) {
this.activityWR = new WeakReference<Activity>(activity);
}
@Override
public void onAdFailedToLoad(int errorCode) {
super.onAdFailedToLoad(errorCode);
switch (errorCode) {
case AdRequest.ERROR_CODE_INTERNAL_ERROR:
MTLog.w(TAG, "Failed to received ad! Internal error code: '%s'.", errorCode);
break;
case AdRequest.ERROR_CODE_INVALID_REQUEST:
MTLog.w(TAG, "Failed to received ad! Invalid request error code: '%s'.", errorCode);
break;
case AdRequest.ERROR_CODE_NETWORK_ERROR:
MTLog.w(TAG, "Failed to received ad! Network error code: '%s'.", errorCode);
break;
case AdRequest.ERROR_CODE_NO_FILL:
MTLog.w(TAG, "Failed to received ad! No fill error code: '%s'.", errorCode);
break;
default:
MTLog.w(TAG, "Failed to received ad! Error code: '%s'.", errorCode);
}
adLoaded = null;
hideAds(this.activityWR == null ? null : this.activityWR.get());
}
@Override
public void onAdLoaded() {
super.onAdLoaded();
adLoaded = true;
showAdsIfEnoughSpace(this.activityWR == null ? null : this.activityWR.get());
}
@Override
public void onAdClosed() {
super.onAdClosed();
}
@Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
}
@Override
public void onAdOpened() {
super.onAdOpened();
}
}
public static void adaptToScreenSize(Activity activity, Configuration configuration) {
if (!AD_ENABLED) {
return;
}
if (!isShowingAds(activity)) {
return;
}
if (isEnoughSpace(configuration)) {
if (adLoaded != null && adLoaded) {
resumeAd(activity);
showAds(activity);
}
} else {
hideAds(activity);
pauseAd(activity);
}
}
private static boolean isEnoughSpace(Configuration configuration) {
if (configuration == null) {
return false;
}
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
return true;
}
int sizeMask = configuration.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
boolean smallScreen = sizeMask == Configuration.SCREENLAYOUT_SIZE_SMALL || sizeMask == Configuration.SCREENLAYOUT_SIZE_NORMAL;
return !smallScreen;
}
private static void showAdsIfEnoughSpace(Activity activity) {
MTLog.v(TAG, "showAdsIfEnoughSpace(%s)", activity);
if (activity != null) {
adaptToScreenSize(activity, activity.getResources().getConfiguration());
}
}
private static void showAds(Activity activity) {
View adLayout = activity == null ? null : activity.findViewById(R.id.ad_layout);
if (adLayout != null) {
AdView adView = (AdView) adLayout.findViewById(R.id.ad);
if (adView != null && adView.getVisibility() != View.VISIBLE) {
adView.setVisibility(View.VISIBLE);
}
if (adLayout.getVisibility() != View.VISIBLE) {
adLayout.setVisibility(View.VISIBLE);
}
}
}
private static void hideAds(Activity activity) {
View adLayout = activity == null ? null : activity.findViewById(R.id.ad_layout);
if (adLayout != null) {
AdView adView = (AdView) adLayout.findViewById(R.id.ad);
if (adLayout.getVisibility() != View.GONE) {
adLayout.setVisibility(View.GONE);
}
if (adView != null && adView.getVisibility() != View.GONE) {
adView.setVisibility(View.GONE);
}
}
}
public static void pauseAd(Activity activity) {
if (!AD_ENABLED) {
return;
}
View adLayout = activity == null ? null : activity.findViewById(R.id.ad_layout);
if (adLayout != null) {
AdView adView = (AdView) adLayout.findViewById(R.id.ad);
if (adView != null) {
adView.pause();
}
}
}
private static void resumeAd(Activity activity) {
if (!AD_ENABLED) {
return;
}
View adLayout = activity == null ? null : activity.findViewById(R.id.ad_layout);
if (adLayout != null) {
AdView adView = (AdView) adLayout.findViewById(R.id.ad);
if (adView != null) {
adView.resume();
}
}
}
public static void destroyAd(Activity activity) {
if (!AD_ENABLED) {
return;
}
View adLayout = activity == null ? null : activity.findViewById(R.id.ad_layout);
if (adLayout != null) {
AdView adView = (AdView) adLayout.findViewById(R.id.ad);
if (adView != null) {
try {
adView.removeAllViews();
adView.destroy();
} catch (Throwable t) {
MTLog.w(TAG, t, "Error while destroying ad view!");
}
}
}
adLoaded = null;
TaskUtils.cancelQuietly(setupAdTask, true);
setupAdTask = null;
}
private static final int MIN_AGENCIES_FOR_ADS = 2;
private static Integer nbAgencies = null;
public static void onModulesUpdated(Activity activity) {
nbAgencies = null; // reset
refreshAdStatus(activity);
}
private static boolean isShowingAds(Context context) {
if (!AD_ENABLED) {
return false;
}
if (nbAgencies == null) {
nbAgencies = DataSourceProvider.get(context).getAllAgenciesCount();
}
if (nbAgencies <= MIN_AGENCIES_FOR_ADS) {
return false;
}
if (showingAds == null) {
return false;
}
return showingAds;
}
public static void setShowingAds(Boolean newShowingAds, Activity activity) {
showingAds = newShowingAds;
refreshAdStatus(activity);
}
private static void refreshAdStatus(Activity activity) {
if (isShowingAds(activity)) {
if (adLoaded == null || !adLoaded) {
setupAd(activity);
}
} else {
if (adLoaded != null && adLoaded) {
hideAds(activity);
pauseAd(activity);
}
}
}
}