public final class ApiBlocking
{

    public static void handle(final String packageName, final XC_LoadPackage.LoadPackageParam lpparam, final XC_MethodHook.MethodHookParam param)
    {
        Context context = (Context) (param.thisObject);

        for (Blocker blocker : Main.blockers)
        {
            try
            {
                String name = blocker.getClass().getSimpleName();
                boolean result = blocker.handleLoadPackage(packageName, lpparam);

                if (result)
                {
                    Util.notifyAdNetwork(context, packageName, name);
                }
            }
            catch (Exception e)
            {
                Util.log(packageName, e.toString());
            }
        }
    }

    /*
        Used for blocking banner function and removing banner
     */
    public static boolean removeBanner(final String packageName, final String bannerClass, final String bannerFunc, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        return removeBannerWithResult(packageName, bannerClass, bannerFunc, new Object(), lpparam);
    }

    public static boolean removeBannerWithResult(final String packageName, final String bannerClass, final String bannerFunc, final Object result, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            Util.hookAllMethods(bannerClass, lpparam.classLoader, bannerFunc, new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("removeBannerWithResult: Detect %s %s in %s", bannerClass, bannerFunc, packageName);

                    Util.log(packageName, debugMsg);

                    ViewBlocking.removeAdView(packageName, (View) param.thisObject);

                    param.setResult(result);
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("removeBannerWithResult: Method %s not found in %s.", bannerFunc, bannerClass));
            }

            return false;
        }
        return true;
    }

    /*
        Used for blocking ad functions
     */
    public static boolean blockAdFunction(final String packageName, final String adClass, final String adFunc, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            Util.hookAllMethods(adClass, lpparam.classLoader, adFunc, new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("blockAdFunction: Detect %s %s in %s", adClass, adFunc, packageName);

                    Util.log(packageName, debugMsg);
                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(new Object());
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunction: Method %s not found in %s.", adFunc, adFunc));
            }

            return false;
        }

        return true;
    }

    public static boolean blockAdFunctionExact(final String packageName, final String adClass, final String adFunc, final Object parameter, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            XposedHelpers.findAndHookMethod(adClass, lpparam.classLoader, adFunc, parameter, new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("Detect %s %s(%s) in %s", adClass, adFunc, parameter.toString(), packageName);

                    Util.log(packageName, debugMsg);

                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(new Object());
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunction: Method %s(%s) not found in %s.", adFunc, parameter.toString(), adClass));
            }

            return false;
        }

        return true;
    }

    public static boolean blockAdFunctionExact(final String packageName, final String adClass, final String adFunc, final Object parameter1, final Object parameter2, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            XposedHelpers.findAndHookMethod(adClass, lpparam.classLoader, adFunc, parameter1, parameter2, new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("Detect %s %s(%s, %s) in %s", adClass, adFunc, parameter1.toString(), parameter2.toString(), packageName);

                    Util.log(packageName, debugMsg);

                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(new Object());
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunction: Method %s(%s, %s) not found in %s.", adFunc, parameter1.toString(), parameter2.toString(), adClass));
            }

            return false;
        }

        return true;
    }

    public static boolean blockAdFunctionExact(final String packageName, final String adClass, final String adFunc, final Object parameter1, final Object parameter2, final Object parameter3, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            XposedHelpers.findAndHookMethod(adClass, lpparam.classLoader, adFunc, parameter1, parameter2, parameter3, new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("Detect %s %s(%s, %s, %s) in %s", adClass, adFunc, parameter1.toString(), parameter2.toString(), parameter3.toString(), packageName);

                    Util.log(packageName, debugMsg);

                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(new Object());
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunction: Method %s(%s, %s, %s) not found in %s.", adFunc, parameter1.toString(), parameter2.toString(), parameter3.toString(), adClass));
            }

            return false;
        }

        return true;
    }

    public static boolean blockAdFunctionWithResult(final String packageName, final String adClass, final String adFunc, final Object result, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            XposedHelpers.findAndHookMethod(adClass, lpparam.classLoader, adFunc, new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("blockAdFunctionWithResult: Detect %s %s in %s", adClass, adFunc, packageName);

                    Util.log(packageName, debugMsg);

                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(result);
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunctionWithResult: Method %s not found in %s.", adFunc, adClass));
            }

            return false;
        }

        return true;
    }


    public static boolean blockAdFunctionWithResultExact(final String packageName, final String adClass, final String adFunc, final Object parameter, final Object result, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            XposedHelpers.findAndHookMethod(adClass, lpparam.classLoader, adFunc, parameter, new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("Detect %s %s(%s) in %s", adClass, adFunc, parameter.toString(), packageName);

                    Util.log(packageName, debugMsg);

                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(result);
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunctionWithResult: Method %s(%s) not found in %s.", adFunc, parameter.toString(), adClass));
            }

            return false;
        }

        return true;
    }


    public static boolean blockAdFunctionWithResultExact(final String packageName, final String adClass, final String adFunc, final Object parameter1, final Object parameter2, final Object result, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        try
        {
            XposedHelpers.findAndHookMethod(adClass, lpparam.classLoader, adFunc, parameter1, parameter2, new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String debugMsg = String.format("Detect %s %s(%s, %s) in %s", adClass, adFunc, parameter1.toString(), parameter2.toString(), packageName);

                    Util.log(packageName, debugMsg);

                    Util.notifyRemoveAdView(null, packageName, 1);

                    param.setResult(result);
                }
            });
        }
        catch (ClassNotFoundError | NoSuchMethodError e)
        {
            if (e instanceof NoSuchMethodError)
            {
                Util.log(packageName, String.format("blockAdFunctionWithResultExact: Method %s(%s, %s) not found in %s.", adFunc, parameter1.toString(), parameter2.toString(), adClass));
            }

            return false;
        }

        return true;
    }
} public abstract class Blocker
{
    /**
     * @param packageName
     * @param lpparam
     * @return True if currrent handling app using this adnetwork. False otherwise.
     */
    abstract public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam);

    abstract public String getBanner();

    abstract public String getBannerPrefix();

    public String getName()
    {
        return getClass().getSimpleName();
    }
} public final class NameBlocking
{

    private static boolean matchBannerName(String clazzName, String banner, String bannerPrefix)
    {
        if (banner != null && banner.equals(clazzName))
        {
            return true;
        }

        return bannerPrefix != null && clazzName.startsWith(bannerPrefix);
    }

    // return adnetwork name
    private static Boolean isAdView(Context context, String pkgName, String clazzName)
    {
        // android widgets
        if (clazzName.startsWith("android"))
            return false;

        // corner case
        if (clazzName.startsWith("com.google.ads"))
            return true;

        for (Blocker blocker : Main.blockers)
        {
            String name = blocker.getClass().getSimpleName();
            String banner = blocker.getBanner();
            String bannerPrefix = blocker.getBannerPrefix();

            // prefix is used to detect adview obfuscate by proguard
            if (matchBannerName(clazzName, banner, bannerPrefix))
            {
                Util.notifyAdNetwork(context, pkgName, name);

                return true;
            }
        }
        return false;
    }

    private static Boolean isAdView(Context context, String pkgName, View view)
    {
        Class clazz = view.getClass();
        // find also parent classes
        int level = 1;

        for (int i = 0; i < level && clazz != null; i++)
        {
            String clazzName = clazz.getName();

            if (isAdView(context, pkgName, clazzName))
                return true;

            clazz = clazz.getSuperclass();
        }

        return false;
    }

    private static void clearAdViewInLayout(final String packageName, final View view)
    {

        if (isAdView(view.getContext(), packageName, view))
        {
            ViewBlocking.removeAdView(packageName, view);
            Util.log(packageName, "clearAdViewInLayout: " + view.getClass().getName());
        }

        if (view instanceof ViewGroup)
        {
            ViewGroup vg = (ViewGroup) view;

            for (int i = 0; i < vg.getChildCount(); i++)
            {
                clearAdViewInLayout(packageName, vg.getChildAt(i));
            }
        }
    }

    public static void nameBasedBlocking(final String pkgName, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        Util.hookAllMethods("android.view.ViewGroup", lpparam.classLoader, "addView", new XC_MethodHook()
        {

            @Override
            protected void beforeHookedMethod(MethodHookParam param)
            {
                View view = (View) param.args[0];

                if (view != null && isAdView(view.getContext(), pkgName, view))
                {
                    Util.log(pkgName, "NameBasedBlocking before addView: " + view.getClass().getName());
                    ViewBlocking.removeAdView(pkgName, view);
                }
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param)
            {
                View view = (View) param.args[0];

                if (view != null && isAdView(view.getContext(), pkgName, view))
                {
                    Util.log(pkgName, "NameBasedBlocking after addView: " + view.getClass().getName());
                    ViewBlocking.removeAdView(pkgName, view);
                }
            }
        });

        Util.hookAllMethods("android.app.Activity", lpparam.classLoader, "setContentView", new XC_MethodHook()
        {
            @Override
            protected void afterHookedMethod(MethodHookParam param)
            {
                Activity ac = (Activity) (param.thisObject);
                ViewGroup root = ac.getWindow().getDecorView().findViewById(android.R.id.content);

                clearAdViewInLayout(pkgName, root);
            }
        });

        Util.hookAllMethods("android.view.LayoutInflater", lpparam.classLoader, "inflate", new XC_MethodHook()
        {

            /*
              http://developer.android.com/intl/zh-tw/reference/android/view/LayoutInflater.html
              inflate(int resource, ViewGroup root)
              inflate(XmlPullParser parser, ViewGroup root)
              inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
              inflate(int resource, ViewGroup root, boolean attachToRoot)

                Returns
                The root View of the inflated hierarchy. If root was supplied and attachToRoot is true,
                this is root; otherwise it is the root of the inflated XML file.
             */

            @Override
            protected void afterHookedMethod(MethodHookParam param)
            {
                View root = (View) param.getResult();

                if (root != null)
                    clearAdViewInLayout(pkgName, root);
            }
        });
    }
} public final class UrlFiltering
{
    private static boolean adExist = false;

    static public boolean removeWebViewAds(final String packageName, LoadPackageParam lpparam)
    {

        try
        {

            Class<?> adView = findClass("android.webkit.WebView", lpparam.classLoader);

            XposedBridge.hookAllMethods(adView, "loadUrl", new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {

                    String url = (String) param.args[0];
                    adExist = urlFiltering(url, "", param, packageName);
                    if (adExist)
                    {
                        param.setResult(new Object());
                    }
                }
            });

            XposedBridge.hookAllMethods(adView, "loadData", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {

                    String data = (String) param.args[0];
                    adExist = urlFiltering("", data, param, packageName);
                    if (adExist)
                    {
                        param.setResult(new Object());
                    }
                }
            });

            XposedBridge.hookAllMethods(adView, "loadDataWithBaseURL", new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    String url = (String) param.args[0];
                    String data = (String) param.args[1];
                    adExist = urlFiltering(url, data, param, packageName);
                    if (adExist)
                    {
                        param.setResult(new Object());
                    }
                }
            });
        }
        catch (ClassNotFoundError e)
        {
            Util.log(packageName, packageName + "can not clear webview ads");
            return false;
        }
        return adExist;
    }

    static private boolean urlFiltering(String url, String data, MethodHookParam param, String packageName)
    {

        Util.log(packageName, "Url filtering");

        if (url == null)
            url = "";

        try
        {
            url = URLDecoder.decode(url, "UTF-8");
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        Util.log(packageName, packageName + " url:\n" + url);

        for (String adUrl : Main.patterns)
        {
            if (url.contains(adUrl))
            {
                Util.log(packageName, "Detect " + packageName + " load url from " + adUrl);

                ViewBlocking.removeAdView(packageName, (View) param.thisObject);
                param.setResult(new Object());

                return true;
            }
        }

        Util.log(packageName, packageName + " data:\n" + data);

        try
        {
            data = URLDecoder.decode(data, "UTF-8");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        for (String adUrl : Main.patterns)
        {
            if (data.contains(adUrl))
            {
                Util.log(packageName, "Detect " + packageName + " load data from " + adUrl);
                ViewBlocking.removeAdView(packageName, (View) param.thisObject);
                param.setResult(new Object());

                return true;
            }
        }

        return false;
    }
} public final class Util
{
    // change it to false for release build
    public static boolean DEBUG = BuildConfig.DEBUG;

    public static ExecutorService notifyWorker;

    public static final String TAG = "MinMinGuard";
    private static final String PACKAGE = "tw.fatminmin.xposed.minminguard";

    private Util() throws InstantiationException
    {
        throw new InstantiationException("This class is not for instantiation");
    }

    public static Boolean xposedEnabled()
    {
        return false;
    }

    public static String getAppVersion(Context context)
    {
        String version = null;
        PackageManager pm = context.getPackageManager();

        try
        {
            version = pm.getPackageInfo(PACKAGE, 0).versionName;
        }
        catch (PackageManager.NameNotFoundException e)
        {
        }

        return version;
    }

    public static void log(String packageName, String msg)
    {
        if (DEBUG)
        {
            //Log.d(TAG, packageName + ": " + msg);
            XposedBridge.log(packageName + ": " + msg);
        }
    }

    public static Application getCurrentApplication()
    {
        try
        {
            return AndroidAppHelper.currentApplication();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null;
    }

    public static void saveLog(final File dest, final Context context, final Handler handler)
    {
        handler.post(new Runnable()
        {

            @Override
            public void run()
            {
                try
                {

                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

    public static void notifyAdNetwork(final Context context, final String pkgName, final String adNetwork)
    {
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    ContentResolver resolver = context.getContentResolver();
                    Uri uri = Uri.parse("content://tw.fatminmin.xposed.minminguard/");
                    ContentValues values = new ContentValues();

                    values.put(Common.KEY_PKG_NAME, pkgName);
                    values.put(Common.KEY_NETWORK, adNetwork);
                    resolver.update(uri, values, null, null);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static void notifyRemoveAdView(final Context context, final String pkgName, final int blockNum)
    {
        final Context mContext;

        if (context == null)
            mContext = getCurrentApplication();
        else
            mContext = context;

        Runnable task = new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    ContentResolver resolver = mContext.getContentResolver();
                    Uri uri = Uri.parse("content://tw.fatminmin.xposed.minminguard/");
                    ContentValues values = new ContentValues();

                    values.put(Common.KEY_PKG_NAME, pkgName);
                    values.put(Common.KEY_BLOCK_NUM, blockNum);
                    resolver.update(uri, values, null, null);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        };

        notifyWorker.submit(task);
    }

    public static void hookAllMethods(String className, ClassLoader classLoader, String method, XC_MethodHook callBack)
    {
        Class<?> clazz = XposedHelpers.findClass(className, classLoader);

        XposedBridge.hookAllMethods(clazz, method, callBack);
    }
} public class Ad2iction extends Blocker
{
    private static final String BANNER = "com.ad2iction.mobileads.Ad2ictionView";
    private static final String BANNER_PREFIX = "com.ad2iction.mobileads";

    private static final String INTER_ADS = "com.ad2iction.mobileads.Ad2ictionInterstitial";

    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "load", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class AdMarvel extends Blocker
{

    private static final String BANNER = "com.admarvel.android.ads.AdMarvelView";
    private static final String BANNER_PREFIX = "com.admarvel.android.ads";

    private static final String INTER_ADS = "com.admarvel.android.ads.AdMarvelInterstitialAds";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "requestNewAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "requestNewInterstitialAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Adbert extends Blocker
{

    private static final String BANNER = "com.adbert.AdbertADView";
    private static final String BANNER_PREFIX = "com.adbert";

    private static final String INTER_ADS = "com.adbert.AdbertInterstitialAD";

    @Override
    public boolean handleLoadPackage(final String packageName, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;
        result = ApiBlocking.removeBanner(packageName, BANNER, "start", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }
} public class Adcolony extends Blocker
{
    private static final String Adcolony_Storage = "com.adcolony.sdk.ab";

    private static final String INTER_ADS = "com.adcolony.sdk.AdColonyInterstitial";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunctionWithResultExact(packageName, Adcolony_Storage, "a", String.class, 0.0d, lpparam);

        result |= ApiBlocking.blockAdFunctionWithResult(packageName, INTER_ADS, "isExpired", true, lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, INTER_ADS, "show", false, lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }
} public class Adfurikun extends Blocker
{

    private static final String BANNER = "jp.tjkapp.adfurikunsdk.AdfurikunBase";
    private static final String BANNER_PREFIX = "jp.tjkapp.adfurikunsdk";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "a", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Adtech extends Blocker
{

    private static final String BANNER = "com.adtech.mobilesdk.publisher.view.AdtechBannerView";
    private static final String BANNER_PREFIX = "com.adtech.mobilesdk.publisher.view";

    private static final String INTER_ADS = "com.adtech.mobilesdk.publisher.view.AdtechInterstitialView";

    @Override
    public boolean handleLoadPackage(final String packageName, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "load", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "load", lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }
} public class Amazon extends Blocker
{

    private static final String BANNER = "com.amazon.device.ads.AdLayout";
    private static final String BANNER_PREFIX = "com.amazon.device.ads";

    private static final String AD_REQUEST = "com.amazon.device.ads.DTBAdRequest";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "setListener", lpparam);
        result |= ApiBlocking.removeBannerWithResult(packageName, BANNER, "loadAd", true, lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, AD_REQUEST, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, AD_REQUEST, "internalLoadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, AD_REQUEST, "loadAdRequest", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Amobee extends Blocker
{

    private static final String BANNER = "com.amobee.adsdk.AdManager";
    private static final String BANNER_PREFIX = "com.amobee.adsdk";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, BANNER, "getAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Aotter extends Blocker
{

    private static final String BANNER_PREFIX = "com.aotter.net.trek.ads";
    private static final String NATIVE_ADS = "com.aotter.net.trek.ads.TKAdN";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, NATIVE_ADS, "setAdListener", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_ADS, "registerViewForInteraction", lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }
} public class AppBrain extends Blocker
{
    private static final String BANNER = "com.appbrain.AppBrainBanner";

    private static final String INTER_ADS = "com.appbrain.AppBrain";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "requestAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "getAds", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Applovin extends Blocker
{
    private static final String MAX_ADVIEW = "com.applovin.mediation.ads.MaxAdView";
    private static final String MAX_INTER = "com.applovin.mediation.ads.MaxInterstitialAd";
    private static final String MAX_REWARDED = "com.applovin.mediation.ads.MaxRewardedAd";

    private static final String SDK_ENABLED = "com.applovin.sdk.AppLovinSdk";

    private static final String NATIVE_ADS = "com.applovin.impl.sdk.NativeAdServiceImpl";

    private static final String APPLOVIN_ADS = "com.applovin.impl.sdk.AppLovinAdServiceImpl";
    private static final String APPLOVIN_ADS_NESTED = APPLOVIN_ADS + "$a";

    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, MAX_ADVIEW, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, MAX_INTER, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, MAX_REWARDED, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, SDK_ENABLED, "isEnabled", false, lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_ADS, "loadNativeAds", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, APPLOVIN_ADS_NESTED, "adReceived", lpparam);
        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }

    @Override
    public String getBanner()
    {
        return null;
    }
} public class Appnext extends Blocker
{
    private static final String INTER_ADS = "com.appnext.ads.interstitial.Interstitial";

    private static final String VIDEO_ADS = "com.appnext.ads.fullscreen.";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "showAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, VIDEO_ADS, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, VIDEO_ADS, "showAd", lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }
} public class AppodealMRAID extends Blocker {

    private static final String BANNER = "com.appodeal.iab.mraid.MRAIDView";
    private static final String BANNER_PREFIX = "com.appodeal.iab.mraid";

    private static final String AD_INTERSTITIAL = "com.appodeal.iab.mraid.MRAIDInterstitial";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam) {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "show", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName,AD_INTERSTITIAL,"show",lpparam);

        return result;
    }

    @Override
    public String getBanner() {
        return BANNER;
    }

    @Override
    public String getBannerPrefix() {
        return BANNER_PREFIX;
    }
} public class Avocarrot extends Blocker
{

    private static final String PREFIX = "com.avocarrot.androidsdk";

    private static final String AD_CONTROLLER = "com.avocarrot.androidsdk.BaseController";
    private static final String AD_CONTROLLER_FUNC = "loadAd";

    @Override
    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, AD_CONTROLLER, AD_CONTROLLER_FUNC, lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return PREFIX;
    }
}    public class Bonzai extends Blocker
{

    private static final String BANNER = "com.bonzai.view.BonzaiAdView";
    private static final String BANNER_PREFIX = "com.bonzai.view";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "update", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Chartboost extends Blocker
{

    private static final String BANNER = "com.chartboost.sdk.Chartboost";
    private static final String BANNER_PREFIX = "com.chartboost.sdk";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, BANNER, "showInterstitial", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, BANNER, "showRewardedVideo", lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, BANNER, "hasInterstitial", false, lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, BANNER, "hasRewardedVideo", false, lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Clickforce extends Blocker
{

    private static final String BANNER = "com.adcustom.sdk.ads.AdBanner";
    private static final String BANNER_PREFIX = "com.adcustom.sdk.ads";

    @Override
    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "show", lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }
} public class Domob extends Blocker
{

    private static final String BANNER = "cn.domob.android.ads.DomobAdView";
    private static final String BANNER_PREFIX = "cn.domob.android.ads";

    private static final String INTER_ADS = "cn.domob.android.ads.DomobInterstitialAd";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "setAdEventListener", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "setInterstitialAdListener", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Facebook extends Blocker
{
    private static final String BANNER = "com.facebook.ads.AdView";
    private static final String BANNER_PREFIX = "com.facebook.ads";

    private static final String INTER = "com.facebook.ads.InterstitialAd";

    private static final String NATIVE_AD = "com.facebook.ads.NativeAd";
    private static final String NATIVE_ADS_MGR = "com.facebook.ads.NativeAdsManager";

    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);
        result |= ApiBlocking.removeBanner(packageName, BANNER, "setAdListener", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER, "loadAdFromBid", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_AD, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_AD, "loadAdFromBid", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_ADS_MGR, "loadAds", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Flurry extends Blocker
{

    private static final String BANNER = "com.flurry.android.FlurryAds";
    private static final String BANNER_PREFIX = "com.flurry.android";

    private static final String NATIVE_AD = "com.flurry.android.ads.FlurryAdNative";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "displayAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, BANNER, "fetchAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_AD, "fetchAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Freewheel extends Blocker
{
    public static final String AdInstace = "tv.freewheel.ad.AdInstance";

    private static final String Ad = "tv.freewheel.ad.Ad";

    public static final String Slot = "tv.freewheel.ad.slot.Slot";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, Ad, "parse", lpparam);
        /*result |= ApiBlocking.blockAdFunctionWithResult(packageName, AdInstace, "isPlayable", false, lpparam, removeAd);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, AdInstace, "isRequiredToShow", false, lpparam, removeAd);
        */

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }
} public class GoogleAdmob extends Blocker
{

    private static final String BANNER = "com.google.ads.AdView";
    private static final String BANNER_PREFIX = "com.google.ads";

    private static final String INTER_ADS = "com.google.ads.InterstitialAd";

    private static final String AD_LOADER = "com.google.android.ads.AdLoader";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, AD_LOADER, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class GoogleGms extends Blocker
{

    private static final String BANNER = "com.google.android.gms.ads.AdView";
    private static final String BANNER_PREFIX = "com.google.android.gms.ads";

    private static final String SEARCH_BANNER = "com.google.android.gms.ads.search.SearchAdView";
    private static final String INTER_ADS = "com.google.android.gms.ads.InterstitialAd";

    private static final String AD_LOADER = "com.google.android.gms.ads.AdLoader";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);
        result |= ApiBlocking.removeBanner(packageName, SEARCH_BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, AD_LOADER, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, AD_LOADER, "loadAds", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class GoogleGmsDoubleClick extends Blocker
{
    private static final String PUBLISHER_BANNER = "com.google.android.gms.ads.doubleclick.PublisherAdView";
    private static final String BANNER_PREFIX = "com.google.android.gms.ads.doubleclick";

    private static final String INTER_ADS = "com.google.android.gms.ads.doubleclick.PublisherInterstitialAd";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, PUBLISHER_BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return PUBLISHER_BANNER;
    }
} public class Hodo extends Blocker
{
    private static final String BANNER = "com.hodo.HodoADView";
    private static final String BANNER_PREFIX = "com.hodo";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "requestAD", lpparam);
        result |= ApiBlocking.removeBanner(packageName, BANNER, "setListener", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Inmobi extends Blocker
{

    private static final String BANNER = "com.inmobi.ads.IMBanner";
    private static final String BANNER_PREFIX = "com.inmobi.ads";

    private static final String INTER_ADS = "com.inmobi.ads.InMobiInterstitial";

    private static final String NATIVE_ADS = "com.inmobi.ads.InMobiNative";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "load", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "load", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_ADS, "load", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Intowow extends Blocker
{

    private static final String BANNER = "com.intowow.sdk.BannerAD";
    private static final String BANNER_FUNC = "onStart";
    private static final String BANNER_PREFIX = "com.intowow.sdk";

    private static final String SPLASH_AD = "com.intowow.sdk.SplashAD";
    private static final String SPLASH_AD_FUNC = "show";

    private static final String I2WAPI = "com.intowow.sdk.I2WAPI";
    private static final String API_FUNC_1 = "requesSingleOfferAD";
    private static final String API_FUNC_2 = "requesSplashAD";
    private static final String API_FUNC_3 = "requestHybridSplashAD";

    private static final String CONTENT_AD_HELPER = "com.intowow.sdk.ContentADHelper";
    private static final String HELPER_FUNC = "requestAD";

    private static final String STREAM_HELPER = "com.intowow.sdk.StreamHelper";

    public static final String STREAM_HELPER_FUNC_1 = "getAD";
    private static final String STREAM_HELPER_FUNC_2 = "setActive";
    private static final String STREAM_HELPER_FUNC_3 = "setListener";

    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, BANNER_FUNC, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, SPLASH_AD, SPLASH_AD_FUNC, lpparam);

        result |= ApiBlocking.blockAdFunctionWithResult(packageName, I2WAPI, API_FUNC_1, null, lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, I2WAPI, API_FUNC_2, null, lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, I2WAPI, API_FUNC_3, null, lpparam);

        result |= ApiBlocking.blockAdFunctionWithResult(packageName, CONTENT_AD_HELPER, HELPER_FUNC, null, lpparam);

//        result |= ApiBlocking.blockAdFunctionWithResult(packageName, streamHelper, streamHelperFunc1, null, lpparam, removeAd);
        result |= ApiBlocking.blockAdFunction(packageName, STREAM_HELPER, STREAM_HELPER_FUNC_2, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, STREAM_HELPER, STREAM_HELPER_FUNC_3, lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Ironsource extends Blocker
{
    private static final String SuperSonicAdsAdapter = "com.ironsource.adapters.supersonicads.SupersonicAdsAdapter";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, SuperSonicAdsAdapter, "showRewardedVideo", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, SuperSonicAdsAdapter, "showInterstitial", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, SuperSonicAdsAdapter, "showOfferwall", lpparam);

        result |= ApiBlocking.blockAdFunctionWithResult(packageName, SuperSonicAdsAdapter, "isRewardedVideoAvailable", false, lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, SuperSonicAdsAdapter, "isInterstitialReady", false, lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }
} public class KuAd extends Blocker
{

    private static final String BANNER = "com.waystorm.ads.WSAdBanner";
    private static final String BANNER_PREFIX = "com.waystorm.ads";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "setWSAdListener", lpparam);
        result |= ApiBlocking.removeBanner(packageName, BANNER, "setApplicationId", lpparam);
        result |= ApiBlocking.removeBanner(packageName, BANNER, "mediationLoadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Madvertise extends Blocker
{

    private static final String BANNER = "de.madvertise.android.sdk.MadvertiseMraidView";
    private static final String BANNER_PREFIX = "de.madvertise.android.sdk";

    //TODO Check if we are using an Xposed version that doesnt support Resource hooking. What is SS????
    public static void handleInitPackageResources(InitPackageResourcesParam resparam)
    {

        final String packageName = "net.tsapps.appsales";

        if (!resparam.packageName.equals(packageName))
        {
            return;
        }

        String[] files = {
                "fragment_watchdetail", "fragment_watchdetail_tablet", "fragment_list", "fragment_saledetail", "fragment_saledetail_tablet"
        };

        for (String file : files)
        {
            resparam.res.hookLayout(packageName, "layout", file, new XC_LayoutInflated()
            {
                @Override
                public void handleLayoutInflated(LayoutInflatedParam liparam)
                {

                    Util.log(packageName, "Set view gone");
                    final ViewGroup root = liparam.view.findViewById(liparam.res.getIdentifier("ll_adcontainer", "id", packageName));

                    root.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener()
                    {

                        @Override
                        public void onChildViewRemoved(View parent, View child)
                        {
                            root.removeAllViews();
                        }

                        @Override
                        public void onChildViewAdded(View parent, View child)
                        {

                        }
                    });

                    ss(root);
                }
            });
        }
    }

    //FIXME What is this??
    private static void ss(View vv)
    {

        vv.setVisibility(View.GONE);

        if (vv instanceof ViewGroup)
        {
            ViewGroup vg = (ViewGroup) vv;
            vg.setVisibility(View.GONE);
            for (int i = 0; i < vg.getChildCount(); i++)
            {
                View v = vg.getChildAt(i);
                ss(v);
            }
        }
    }

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {

        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class MasAd extends Blocker
{

    private static final String BANNER = "mediba.ad.sdk.android.openx.MasAdView";
    private static final String BANNER_PREFIX = "mediba.ad.sdk.android.openx";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "b", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class MdotM extends Blocker
{

    private static final String BANNER = "com.mdotm.android.view.MdotMAdView";
    private static final String BANNER_PREFIX = "com.mdotm.android.view";

    private static final String INTER_ADS = "com.mdotm.android.view.MdotMInterstitial";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadBannerAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadInterstitial", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Millennial extends Blocker
{

    private static final String BANNER = "com.millennialmedia.android.MMAdView";
    private static final String BANNER_PREFIX = "com.millennialmedia.android";

    private static final String INTER_ADS = "com.millennialmedia.android.MMInterstitial";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "getAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "display", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class MoPub extends Blocker
{

    private static final String BANNER = "com.mopub.mobileads.MoPubView";
    private static final String BANNER_PREFIX = "com.mopub.mobileads";

    private static final String INTER_ADS = "com.mopub.mobileads.MoPubInterstitial";
    private static final String NATIVE_AD = "com.mopub.nativeads.MoPubAdAdapter";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "load", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_AD, "loadAds", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class MobFox extends Blocker
{

    private static final String BANNER = "com.adsdk.sdk.waterfall.Banner";
    private static final String BANNER_PREFIX = "com.adsdk.sdk.waterfall";

    @Override
    //TODO Check if this needs to use removeBanner
    public boolean handleLoadPackage(final String packageName, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        return ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }
} public class Mobclix extends Blocker
{
    private static final String BANNER = "com.mobclix.android.sdk.MobclixMMABannerXLAdView";
    private static final String BANNER_PREFIX = "com.mobclix.android.sdk";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "getAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Nend extends Blocker
{

    private static final String BANNER = "net.nend.android.NendAdView";
    private static final String BANNER_PREFIX = "net.nend.android";

    //TODO Does this need to use removeBanner?
    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Og extends Blocker
{

    private static final String BANNER = "com.og.wa.AdWebView";
    private static final String BANNER_PREFIX = "com.og.wa";

    //FIXME Use APIBlocking Please....... Use fields for classNames
    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        try
        {
            final Class<?> adView = XposedHelpers.findClass("com.og.wa.AdWebView", lpparam.classLoader);
            final Class<?> webView = XposedHelpers.findClass("android.webkit.WebView", lpparam.classLoader);
            XposedBridge.hookAllMethods(webView, "loadUrl", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    if (adView.isInstance(param.thisObject))
                    {
                        Util.log(packageName, "Detect og AdWebView loadUrl in " + packageName);
                        param.setResult(new Object());
                        ViewBlocking.removeAdView(packageName, (View) param.thisObject);
                    }
                }
            });
            Util.log(packageName, packageName + " uses Og AdWebView");
        }
        catch (ClassNotFoundError e)
        {
            return false;
        }

        return true;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Onelouder extends Blocker
{

    private static final String BANNER = "com.onelouder.adlib.AdView";
    private static final String BANNER_PREFIX = "com.onelouder.adlib";

    //TODO Use APIBlocking
    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        try
        {
            Class<?> adView = XposedHelpers.findClass("com.onelouder.adlib.AdView", lpparam.classLoader);
            XposedBridge.hookAllMethods(adView, "setVisibility", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    Util.log(packageName, "Detect onelouder AdView setVisibility in " + packageName);

                    param.args[0] = View.GONE;
                }
            });

            final Method method = XposedHelpers.findMethodBestMatch(adView, "setVisibility", Integer.class);

            XposedBridge.hookAllMethods(adView, "addProxiedAdView", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable
                {
                    Util.log(packageName, "Detect onelouder addProxiedAdView in " + packageName);

                    method.invoke(param.thisObject, View.GONE);
                    param.setResult(new Object());
                }
            });

            XposedBridge.hookAllMethods(adView, "resume", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable
                {
                    Util.log(packageName, "Detect onelouder AdView resume in " + packageName);

                    method.invoke(param.thisObject, View.GONE);
                    param.setResult(new Object());
                }
            });

            Class<?> interad = XposedHelpers.findClass("com.onelouder.adlib.AdInterstitial", lpparam.classLoader);
            XposedBridge.hookAllMethods(interad, "displayInterstitial", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    Util.log(packageName, "Detect onelouder AdInterstitial displayInterstitial in " + packageName);
                    param.setResult(new Object());
                }
            });

            Util.log(packageName, packageName + " uses onelouder");
        }
        catch (ClassNotFoundError e)
        {
            return false;
        }
        return true;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class OpenX extends Blocker
{

    private static final String BANNER = "com.openx.ad.mobile.sdk.interfaces.OXMAdBannerView";
    private static final String BANNER_PREFIX = "com.openx.ad.mobile.sdk.interfaces";

    //TODO Does this need to use removeBanner?
    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class SmartAdserver extends Blocker
{

    private static final String BANNER = "com.smartadserver.android.library.ui.SASAdView";
    private static final String BANNER_PREFIX = "com.smartadserver.android.library.ui";

    //TODO Does this need to use removeBanner?
    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class SourcekitMRAID extends Blocker {

    private static final String BANNER = "org.nexage.sourcekit.mraid.MRAIDView";
    private static final String BANNER_PREFIX = "org.nexage.sourcekit.mraid";

    private static final String AD_INTERSTITIAL = "org.nexage.sourcekit.mraid.MRAIDInterstitial";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam) {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "show", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName,AD_INTERSTITIAL,"show",lpparam);

        return result;
    }

    @Override
    public String getBanner() {
        return BANNER;
    }

    @Override
    public String getBannerPrefix() {
        return BANNER_PREFIX;
    }
} public class Startapp extends Blocker
{

    // API document: https://github.com/StartApp-SDK/Documentation/wiki/Android-InApp-Documentation

    private static final String SDK = "com.startapp.android.publish.StartAppSDK";
    private static final String SDK_INIT = "init";

    private static final String BANNER = "com.startapp.android.publish.HtmlAd";
    private static final String BANNER_FUNC = "show";
    private static final String BANNER_PREFIX = "com.startapp.android.publish";

    private static final String NATIVE_AD = "com.startapp.android.publish.nativead.StartAppNativeAd";
    private static final String NATIVE_AD_FUNC = "getNativeAds";

    private static final String INTER = "com.startapp.android.publish.StartAppAd";
    private static final String INTER_FUNC1 = "showAd";
    private static final String INTER_FUNC2 = "showSplash";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, SDK, SDK_INIT, lpparam);
        result |= ApiBlocking.removeBanner(packageName, BANNER, BANNER_FUNC, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_AD, NATIVE_AD_FUNC, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER, INTER_FUNC1, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER, INTER_FUNC2, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER, INTER_FUNC2, lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class TWMads extends Blocker
{

    private static final String BANNER = "com.taiwanmobile.pt.adp.view.TWMAdView";
    private static final String BANNER_PREFIX = "com.taiwanmobile.pt.adp.view";
    private static final String INTER_ADS = "com.taiwanmobile.pt.adp.view.TWMInterstitialAd";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        //TODO Does this need to use removeBanner?
        result = ApiBlocking.removeBanner(packageName, BANNER, "activeAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Tapfortap extends Blocker
{

    private static final String BANNER = "com.tapfortap.AdView";
    private static final String BANNER_PREFIX = "com.tapfortap";

    private static final String INTER_ADS = "com.tapfortap.Interstitial";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        //TODO Does this need to use removeBanner????
        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAds", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class UnityAds extends Blocker
{

    private static final String UnityAds = "com.unity3d.ads.UnityAds";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunction(packageName, UnityAds, "show", lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, UnityAds, "canShow", false, lpparam);
        result |= ApiBlocking.blockAdFunctionWithResult(packageName, UnityAds, "canShowAds", false, lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }
} public class Vpadn extends Blocker
{
    private static final String BANNER = "com.vpadn.ads.VpadnBanner";
    private static final String BANNER_PREFIX = "com.vpadn.ads";

    private static final String INTER_ADS = "com.vpadn.ads.VpadnInterstitialAd";
    private static final String NATIVE_ADS = "com.vpadn.ads.VpadnNativeAd";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_ADS, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_ADS, "registerViewForInteraction", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Vpon extends Blocker
{

    private static final String BANNER = "com.vpon.ads.VponBanner";
    private static final String BANNER_PREFIX = "com.vpon.ads";
    private static final String INTER_ADS = "com.vpon.ads.VponInterstitialAd";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "show", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Vungle extends Blocker
{
    private static final String VUNGLE_WARREN = "com.vungle.warren.Vungle";

    private static final String VUNGLE_WARREN_STORAGE = "com.vungle.warren.Storage";

    private static final String VUNGLE_PUBLISHER = "com.vungle.publisher.VunglePub";

    @Override
    public boolean handleLoadPackage(String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.blockAdFunctionWithResult(packageName, VUNGLE_WARREN_STORAGE, "findValidAdvertisementForPlacement", null, lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, VUNGLE_WARREN, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, VUNGLE_PUBLISHER, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, VUNGLE_PUBLISHER, "isAdPlayable", lpparam);

        return result;
    }

    @Override
    public String getBanner()
    {
        return null;
    }

    @Override
    public String getBannerPrefix()
    {
        return null;
    }
} public class Waystorm extends Blocker
{
    private static final String BANNER = "com.waystorm.ads.WSAdBanner";
    private static final String BANNER_PREFIX = "com.waystorm.ads";
    private static final String INTER_ADS = "com.waystorm.ads.WSAdInterstitial";

    public boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, INTER_ADS, "loadAd", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class Yandex extends Blocker
{
    private static final String BANNER = "com.yandex.mobile.ads.AdView";
    private static final String BANNER_PREFIX = "com.yandex.mobile.ads";

    private static final String INTERSTITIAL = "com.yandex.mobile.ads.InterstitialAd";

    private static final String NATIVE = "com.yandex.mobile.ads.nativeads.NativeAdLoader";
    //public static final String NATIVE_APP_INSTALL = "com.yandex.mobile.ads.nativeads.NativeAppInstallAdView";
    //public static final String NATIVE_CONTENT = "com.yandex.mobile.ads.nativeads.NativeContentAdView";
    //public static final String NATIVE_IMAGE = "com.yandex.mobile.ads.nativeads.NativeImageAdView";

    private static final String VIDEO = "com.yandex.mobile.ads.video.YandexVideoAds";

    @Override
    public boolean handleLoadPackage(final String packageName, final XC_LoadPackage.LoadPackageParam lpparam)
    {
        boolean result = false;

        //TODO Does this need to use removeBanner?
        result = ApiBlocking.removeBanner(packageName, BANNER, "loadAd", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, INTERSTITIAL, "loadAd", lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, NATIVE, "loadAd", lpparam);
//        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_APP_INSTALL, "getNativeAd", lpparam);
//        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_CONTENT, "getNativeAd", lpparam);
//        result |= ApiBlocking.blockAdFunction(packageName, NATIVE_IMAGE, LOAD_AD, lpparam);

        result |= ApiBlocking.blockAdFunction(packageName, VIDEO, "loadBlocksInfo", lpparam);
        result |= ApiBlocking.blockAdFunction(packageName, VIDEO, "loadVideoAds", lpparam);

        return result;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public class mAdserve extends Blocker
{

    private static final String BANNER = "com.adsdk.sdk.banner.InAppWebView";
    private static final String BANNER_PREFIX = "com.adsdk.sdk.banner";

    public boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {

        try
        {
            //TODO Add blockConstructor to ApiBlocking, so we dont have to do this hack..
            Class<?> adView = XposedHelpers.findClass("com.adsdk.sdk.banner.InAppWebView", lpparam.classLoader);
            XposedBridge.hookAllConstructors(adView, new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    Util.log(packageName, "Detect mAdserve InAppWebView constructor in " + packageName);

                    param.setResult(new Object());
                }
            });

            Util.log(packageName, packageName + " uses mAdserve");
        }
        catch (ClassNotFoundError e)
        {
            return false;
        }
        return true;
    }

    @Override
    public String getBannerPrefix()
    {
        return BANNER_PREFIX;
    }

    @Override
    public String getBanner()
    {
        return BANNER;
    }
} public final class NextMedia
{

    private static final String AD_UTILS = "com.nextmediatw.data.AdUtils";

    private NextMedia() throws InstantiationException
    {
        throw new InstantiationException("This class is not for instantiation");
    }

    static public void handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        ApiBlocking.blockAdFunctionWithResult(packageName, AD_UTILS, "skipAd", true, lpparam);
    }
} public final class OneWeather
{
    private static final String LAYOUT = "com.handmark.expressweather";

    private OneWeather() throws InstantiationException
    {
        throw new InstantiationException("This class is not for instantiation");
    }

    public static boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        try
        {
            Class<?> adView = XposedHelpers.findClass("com.handmark.expressweather.billing.BillingUtils", lpparam.classLoader);
            XposedBridge.hookAllMethods(adView, "isPurchased", new XC_MethodHook()
            {

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {

                    param.setResult(Boolean.valueOf(true));
                }
            });
        }
        catch (ClassNotFoundError e)
        {
            return false;
        }
        return true;
    }

    public static void handleInitPackageResources(InitPackageResourcesParam resparam)
    {
        if (!resparam.packageName.equals(LAYOUT))
        {
            return;
        }

        resparam.res.hookLayout(LAYOUT, "layout", "main_phone", new XC_LayoutInflated()
        {

            @Override
            public void handleLayoutInflated(LayoutInflatedParam liparam)
            {

                View ad = liparam.view.findViewById(liparam.res.getIdentifier("adview", "id", LAYOUT));

                ad.setVisibility(View.GONE);

                ad = liparam.view.findViewById(liparam.res.getIdentifier("share_ad_cover", "id", LAYOUT));

                ad.setVisibility(View.GONE);
            }
        });
    }
} public final class Viafree
{
    private static final String pkg = "viafree.android";
    private static final String className = "com.viafree.android.videoplayer.ad.models.Freewheel";
    private static final String method = "f";

    private Viafree() throws InstantiationException
    {
        throw new InstantiationException("This class is not for instantiation");
    }

    public static boolean handleLoadPackage(final String packageName, XC_LoadPackage.LoadPackageParam lpparam)
    {
        if (!lpparam.packageName.contains(pkg))
        {
            return false;
        }

        XposedHelpers.findAndHookMethod(className, lpparam.classLoader, method, new XC_MethodHook()
        {
            @Override
            protected void beforeHookedMethod(MethodHookParam param)
            {
                param.setResult(new ArrayList<Object>());
                Util.notifyRemoveAdView(null, packageName, 1);
            }
        });

        return true;
    }
} public final class _2chMate
{

    private _2chMate() throws InstantiationException
    {
        throw new InstantiationException("This class is not for instantiation");
    }

    public static boolean handleLoadPackage(final String packageName, LoadPackageParam lpparam)
    {
        if (!packageName.equals("jp.co.airfront.android.a2chMate"))
        {
            return false;
        }

        try
        {
            final Class<?> viewGroupClass = XposedHelpers.findClass("android.view.ViewGroup", lpparam.classLoader);
            XposedBridge.hookAllMethods(viewGroupClass, "addView", new XC_MethodHook()
            {
                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                {
                    final View view = (View) param.args[0];
                    if (view.getClass().getName().equals("jp.syoboi.a2chMate.view.MyAdView"))
                    {
                        Util.log(packageName, "Detect 2chmate MyAdView in " + packageName);

                        param.setResult(null);
                    }
                }
            });
            Util.log(packageName, packageName + " is 2chmate");
        }
        catch (ClassNotFoundError e)
        {
            return false;
        }

        return true;
    }
}
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.XModuleResources;
import android.os.Build;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
import tw.fatminmin.xposed.minminguard.blocker.ApiBlocking;
import tw.fatminmin.xposed.minminguard.blocker.Blocker;
import tw.fatminmin.xposed.minminguard.blocker.NameBlocking;
import tw.fatminmin.xposed.minminguard.blocker.UrlFiltering;
import tw.fatminmin.xposed.minminguard.blocker.Util;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Ad2iction;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.AdMarvel;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Adbert;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Adcolony;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Adfurikun;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Adtech;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Amazon;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Amobee;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Aotter;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.AppBrain;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Applovin;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Appnext;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.AppodealMRAID;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Avocarrot;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Bonzai;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Chartboost;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Clickforce;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Domob;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Facebook;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Flurry;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Freewheel;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.GoogleAdmob;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.GoogleGms;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.GoogleGmsDoubleClick;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Hodo;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Inmobi;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Intowow;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Ironsource;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.KuAd;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Madvertise;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.MasAd;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.MdotM;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Millennial;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.MoPub;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.MobFox;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Mobclix;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Nend;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Og;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Onelouder;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.OpenX;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.SmartAdserver;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.SourcekitMRAID;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Startapp;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.TWMads;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Tapfortap;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.UnityAds;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Vpadn;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Vpon;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Vungle;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Waystorm;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.Yandex;
import tw.fatminmin.xposed.minminguard.blocker.adnetwork.mAdserve;
import tw.fatminmin.xposed.minminguard.blocker.custom_mod.NextMedia;
import tw.fatminmin.xposed.minminguard.blocker.custom_mod.OneWeather;
import tw.fatminmin.xposed.minminguard.blocker.custom_mod.Viafree;
import tw.fatminmin.xposed.minminguard.blocker.custom_mod._2chMate;
package tw.fatminmin.xposed.minminguard;




public class Main implements IXposedHookZygoteInit, IXposedHookLoadPackage
{
    private static final String MY_PACKAGE_NAME = Main.class.getPackage().getName();
    private static String MODULE_PATH;
    public static Set<String> patterns = new HashSet<>();
    public static Resources resources;
    public static Integer xposedVersionCode;
    private SharedPreferences pref;

    public static Blocker[] blockers = {
            /* Popular adnetwork */
            new Ad2iction(), new Adbert(), new Adcolony(), new Adfurikun(), new AdMarvel(), new AppodealMRAID(), new GoogleAdmob(), new GoogleGms(), new Adtech(), new Amazon(), new Amobee(),
            new Aotter(), new AppBrain(), new Applovin(), new Appnext(), new Avocarrot(), new Bonzai(), new Chartboost(), new Clickforce(), new Domob(), new Facebook(),