app/src/main/java/daylemk/xposed/xbridge/action/AppSettingsAction.java
public class AppSettingsAction extends Action {
    public static final String TAG = "AppSettingsAction";
    public static final String STR_DESC = "View in AppSettings";
    public static final String PKG_NAME = "de.robv.android.xposed.mods.appsettings";
    public static final String ACTIVITY_CLASS_NAME = PKG_NAME + ".settings.ApplicationSettings";
    public static final String ARG_PACKAGE_NAME = "package";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    public static Drawable sIcon = null;

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_appsettings);
        keyShowInAppInfo = sModRes.getString(R.string.key_appsettings_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_appsettings_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_appsettings_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.appsettings_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.appsettings_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.appsettings_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.appsettings_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        Intent intent = new Intent();
        intent.setClassName(PKG_NAME, ACTIVITY_CLASS_NAME);
        intent.putExtra(ARG_PACKAGE_NAME, pkgName);
        return intent;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {
    }

    @Override
    public Drawable getIcon(PackageManager packageManager)
    {
        if(sIcon == null){
            sIcon = getPackageIcon(packageManager, PKG_NAME);
        }
        return sIcon;
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }

}
app/src/main/java/daylemk/xposed/xbridge/utils/Log.java
public final class Log {
    public static final String TAG = "DayL";
    public static String keyDebug;
    public static boolean debug = false;
    // if the version is debug, let enable the log by default
    public static boolean isDebugDefault = BuildConfig.DEBUG;

    private Log() {
    }

    private static String getFormattedTag(String tag) {
        return TAG + "[" + tag + "]";
    }

    private static void xposedLog(String tag, String msg) {
        XposedBridge.log(getFormattedTag(tag) + msg);
    }

    public static void i(String tag, String msg) {
        // FIXED: now is not available for App to log to the xposed
        //xposedLog(tag, msg);
        android.util.Log.i(getFormattedTag(tag), msg);
    }

    public static void v(String tag, String msg) {
        //xposedLog(tag, msg);
        android.util.Log.v(getFormattedTag(tag), msg);
    }

    public static void d(String tag, String msg) {
        if (debug) {
            //xposedLog(tag, msg);
            android.util.Log.d(getFormattedTag(tag), msg);
        }
    }

    public static void w(String tag, String msg) {
        //xposedLog(tag, msg);
        android.util.Log.w(getFormattedTag(tag), msg);
    }

    public static void e(String tag, String msg) {
        //xposedLog(tag, msg);
        android.util.Log.e(getFormattedTag(tag), msg);
    }
}
app/src/main/java/daylemk/xposed/xbridge/data/StaticData.java
public final class StaticData {
    public static final String THIS_PACKAGE_NAME = XposedInit.class.getPackage().getName();

    public static final String PKG_NAME_SYSTEMUI = "com.android.systemui";
    public static final String PKG_NAME_FRAMEWORK = "android";
    public static final String PKG_NAME_SETTINGS = "com.android.settings";

    public static final String ACTION_PREFERENCE_CHANGED = "daylemk.xposed.xbridge" +
            ".PREFERENCE_CHANGED";
    public static final String ARG_KEY = "key";
    public static final String ARG_VALUE = "value";
    /*
    public static final boolean DEFAULT_SHOW_IN_RECENT_PANEL = false;
    public static final boolean DEFAULT_SHOW_IN_APP_INFO = false;
    public static final boolean DEFAULT_SHOW_IN_NOTIFICATION = false;
    public static final boolean DEFAULT_TWO_FINGER_IN_RECENT_PANEL = false;
    */
    /*
    public static final boolean DEFAULT_DIRECTLY_SHOW_IN_PLAY = false;
    // browser-store swtich
    public static final boolean DEFAULT_USE_BROWSER = false;
    public static final boolean DEFAULT_DEBUG_LOGS = false;
    */
    public static final String XDA_THREAD = "http://forum.xda-developers" +
            ".com/xposed/modules/xposed-xbridge-bridge-task-app-t3119373";

    // can't construct this class
    private StaticData() {
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/XPrivacyAction.java
public class XPrivacyAction extends Action {
    public static final String TAG = "XPrivacyAction";
    public static final String STR_DESC = "View in XPrivacy";
    public static final String PKG_NAME = "biz.bokhorst.xprivacy";
    public static final String ACTIVITY_CLASS_NAME = PKG_NAME + ".ActivityApp";
    public static final String ARG_UID = "Uid";
//    public static final String ARG_RESTRICTION = "RestrictionName";
//    public static final String VALUE_VIEW = "view";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    public static Drawable sIcon = null;

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_xprivacy);
        keyShowInAppInfo = sModRes.getString(R.string.key_xprivacy_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_xprivacy_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_xprivacy_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.xprivacy_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.xprivacy_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.xprivacy_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.xprivacy_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInStatusBarDefault);
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }


    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        Intent intent = new Intent();
        intent.setClassName(PKG_NAME, ACTIVITY_CLASS_NAME);
        // set no animation to start activity quickly
        intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        intent.putExtra(ARG_UID, getUid(context, pkgName));
//        intent.putExtra(ARG_RESTRICTION, VALUE_VIEW);
        return intent;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {

    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        if (sIcon == null) {
            sIcon = getPackageIcon(packageManager, PKG_NAME);
        }
        return sIcon;
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/data/OnPreferenceChangedReceiver.java
public class OnPreferenceChangedReceiver extends BroadcastReceiver {
    public static final String TAG = "OnPreferenceChangedReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.d(TAG, "onReceive: " + action + "," + intent);
        if (action != null && action.equals(StaticData.ACTION_PREFERENCE_CHANGED)) {
            String key = intent.getStringExtra(StaticData.ARG_KEY);
            String value = intent.getStringExtra(StaticData.ARG_VALUE);
            Log.d(TAG, "key:" + key + ",value:" + value);
            Action.onReceiveNewValue(key, value);
        }
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/MyAndroidToolsAction.java
public class MyAndroidToolsAction extends Action {
    public static final String TAG = "MyAndroidToolsAction";
    public static final String STR_DESC = "View in MyAndroidTools";
    public static final String PKG_NAME = "cn.wq.myandroidtools";
    public static final String PKG_PRO_NAME = "cn.wq.myandroidtoolspro";
    public static final String ACTION_NAME = "cn.wq.myandroidtools.SHOW_APP_INFO";
    public static final String ARG_PKG_NAME = "packageName";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_myandroidtools);
        keyShowInAppInfo = sModRes.getString(R.string.key_myandroidtools_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_myandroidtools_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_myandroidtools_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.myandroidtools_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.myandroidtools_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.myandroidtools_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.myandroidtools_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        return null;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {
        Intent intent = new Intent(ACTION_NAME);
        //intent.setPackage(PKG_NAME);
        intent.putExtra(ARG_PKG_NAME, pkgName);
        Log.d(TAG, "send broadcast:" + intent + ", pkg: " + pkgName);
        context.sendBroadcast(intent);
    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        String pkgName = PKG_NAME;
        try {
            packageManager.getPackageInfo(PKG_PRO_NAME, 0);
            pkgName = PKG_PRO_NAME;
        } catch (PackageManager.NameNotFoundException e) {
            Log.d(TAG, "Did not found the pro package");
        }
        return getPackageIcon(packageManager, pkgName);
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/NotifyCleanAction.java
public class NotifyCleanAction extends Action {
    public static final String TAG = "NotifyCleanAction";
    public static final String STR_DESC = "View in NotifyClean";
    public static final String PKG_NAME = "de.defim.apk.notifyclean";
    public static final String ACTION_NAME = "de.defim.apk.notifyclean.action.NOTIFY";
    public static final String ARG_PKG_NAME = "pkg";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_notifyclean);
        keyShowInAppInfo = sModRes.getString(R.string.key_notifyclean_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_notifyclean_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_notifyclean_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.notifyclean_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.notifyclean_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.notifyclean_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.notifyclean_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        return null;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {
        Intent intent = new Intent(ACTION_NAME);
        intent.setPackage(PKG_NAME);
        intent.putExtra(ARG_PKG_NAME, pkgName);
        Log.d(TAG, "send broadcast:" + intent + ", pkg: " + pkgName);
        context.sendBroadcast(intent);
    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        return getPackageIcon(packageManager, PKG_NAME);
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/ui/SizeInputFragment.java
public class SizeInputFragment extends DialogFragment {
    public static final String TAG = "SizeInputFragment";
    public static final int SIZE_DEFAULT = 75;

    // The size of icon
    public static String keySize;
    public static int size;

    private EditText editText;

    public SizeInputFragment() {
        super();
    }

    public static SizeInputFragment getDialogFragment(Bundle bundle) {
        SizeInputFragment sizeInputFragment = new SizeInputFragment();
        sizeInputFragment.setArguments(bundle);
        return sizeInputFragment;
    }

    public static void loadPreferenceKeys(Resources sModRes) {
        keySize = sModRes.getString(R.string.key_size_of_icon_in_noti);
    }

    public static void loadPreference(SharedPreferences preferences) {
        size = preferences.getInt(keySize, SIZE_DEFAULT);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keySize)) {
            size = Integer.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        super.onCreateDialog(savedInstanceState);
        // Use inflater to inflate the layout and set the content
        LayoutInflater inflater = LayoutInflater.from(this.getActivity());
        View v = inflater.inflate(R.layout.fragment_size_input, null);
        // Use string instead of int
        editText = (EditText) v.findViewById(R.id.edit_text_size);
        editText.setText(String.valueOf(size));

        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
        // Here use the inflated view
        return dialogBuilder.setView(v)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Editable text = editText.getText();
                        try {
                            size = Integer.parseInt(text.toString());
                        } catch (Exception e) {
                            // Input size is not number, do nothing
                            XposedBridge.log(e);
                            return;
                        }

                        if (size < 1) {
                            size = 1;
                        } else if (size > 1000) {
                            size = 1000;
                        }

                        // set the xbridgeFragment need2Load params
                        Fragment fragment = getFragmentManager().findFragmentByTag
                                (XBridgeFragment.TAG);
                        Log.d(TAG, "xBridgeFragment on switch changed: " + fragment);
                        if (fragment != null) {
                            XBridgeFragment xBridgeFragment = (XBridgeFragment) fragment;
                            xBridgeFragment.loadPreferenceValue();
                            // Save the value
                            SharedPreferences.Editor editor = MainPreferences
                                    .getEditablePreferences(xBridgeFragment
                                            .getPreferenceManager()).edit();
                            editor.putInt(keySize, size);
                            editor.commit();
                        }
                    }
                }).setTitle("Size of icon").setCancelable(true).create();
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/XHaloFloatingWindowAction.java
public class XHaloFloatingWindowAction extends Action {
    public static final String TAG = "XHaloFloatingWindowAction";
    public static final String STR_DESC = "View in XHalo floating window";
    public static final String PKG_NAME = "com.zst.xposed.halo.floatingwindow";
    public static final String STR_FLAG_FLOATING_WINDOW = "FLAG_FLOATING_WINDOW";
    public static int FLAG_FLOATING_WINDOW = 0x2000;
	public static int FLAG_FLOATING_WINDOW_Default = 0x2000;
	
    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;
    public static String keyShowButtonNow;
	public static String keyFloatingFlag;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;
    public static boolean showButtonNowDefault;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    public static boolean isShowButtonNow = true;
	
    /* the key should the sub class overwrite ------------end */
    // just need to init the icon and listener once
    // EDIT: maybe the icon is already one instance in the system
    public static Drawable sIcon = null;
    //public static View.OnClickListener sOnClickListener = null;
    // EDIT: the on click listener should be different

    private int flagFloatingWindow = 0;

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_xhalofloatingwindow);
        keyShowInAppInfo = sModRes.getString(R.string.key_xhalofloatingwindow_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_xhalofloatingwindow_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_xhalofloatingwindow_status_bar);
        keyShowButtonNow = sModRes.getString(R.string.key_xhalofloatingwindow_show_button_now);
		keyFloatingFlag = sModRes.getString(R.string.key_xhalofloatingwindow_floating_flag);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.xhalofloatingwindow_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool
                .xhalofloatingwindow_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.xhalofloatingwindow_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.xhalofloatingwindow_default);
        showButtonNowDefault = sModRes.getBoolean(R.bool
                .xhalofloatingwindow_show_button_now_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        isShowButtonNow = preferences.getBoolean(keyShowButtonNow,
                showButtonNowDefault);
		FLAG_FLOATING_WINDOW = preferences.getInt(keyFloatingFlag, FLAG_FLOATING_WINDOW_Default);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow + "isShowButtonNow:" + isShowButtonNow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else if (key.equals(keyShowButtonNow)) {
            isShowButtonNow = Boolean.valueOf(value);
		} else if (key.equals(keyFloatingFlag)) {
            FLAG_FLOATING_WINDOW = Integer.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        // check the icon. if good, just return.
        // TODO: check if the app is just install or upgrade and the icon should be changed
        if (sIcon == null) {
//        Drawable pkgIcon = null;
            sIcon = getPackageIcon(packageManager, PKG_NAME);
        } else {
            Log.d(TAG, "icon is ok, no need to create again");
        }
        return sIcon;
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        return null;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        Intent intent;
        // if the hook is recent task hook, handle it with method which with a intent parameter
        if (hook instanceof RecentTaskHook) {
            intent = new Intent(originalIntent);
        } else {
            // we don't know that launch intent, so use package manager to get it for us
            intent = context.getPackageManager().getLaunchIntentForPackage
                    (pkgName);
        }
        if (intent != null) {
            getFloatingWindowFlag();
            // the floating window flag
            intent.addFlags(flagFloatingWindow | Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
                    Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
        } else {
            Log.w(TAG, "the launcher for: " + pkgName + " is not available");
        }

        return intent;
    }

    // Get the floating window flag from the system
    private void getFloatingWindowFlag() {
        // Get the flag
        if (flagFloatingWindow == 0) {
            try {
                Field f = Intent.class.getField(STR_FLAG_FLOATING_WINDOW);
                flagFloatingWindow = f.getInt(null);
            } catch (Exception e) {
                Log.w(TAG, "Did not found the floating window flag");
                // Did not found the floating flag, use default one
                flagFloatingWindow = FLAG_FLOATING_WINDOW;
            }
        }
        Log.d(TAG, "Floating window flag:" + Integer.toOctalString(flagFloatingWindow));
    }

    /**
     * when the launch intent for this package can't be found, then this method will be called,
     * so we just show a toast to notify user
     *
     * @param context Context
     * @param pkgName The package name
     */
    @Override
    public void handleData(Context context, String pkgName) {
        XBridgeToast.showToastOnHandler(context, Hook.getXBridgeContext(context).getString(R.string
                .cant_launch_in_xhalo) + pkgName);
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/AppOpsAction.java
public class AppOpsAction extends Action {
    public static final String TAG = "AppOpsAction";
    public static final String STR_DESC = "View in App Ops";
    public static final String PKG_NAME = "at.jclehner.appopsxposed";
    public static final String ACTIVITY_CLASS_NAME = PKG_NAME + ".AppOpsActivity";
    public static final String DETAILS_CLASS_NAME = "com.android.settings.applications" +
            ".AppOpsDetails";
    public static final String ARG_PACKAGE_NAME = "package";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    //    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    //    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    //    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    public static Drawable sIcon = null;

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_appops);
//        keyShowInAppInfo = sModRes.getString(R.string.key_appops_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_appops_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_appops_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.appops_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.appops_recent_task_default);
//        showInAppInfoDefault = sModRes.getBoolean(R.bool.appops_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.appops_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInStatusBarDefault);
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInRecentTaskDefault);
//        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
//                PREF_SHOW_IN_APP_INFO_DEFAULT);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        /*} else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);*/
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        Intent intent = new Intent();
        intent.setClassName(PKG_NAME, ACTIVITY_CLASS_NAME);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);

        Bundle bundle = new Bundle();
        bundle.putString(ARG_PACKAGE_NAME, pkgName);

        intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, bundle);
        intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, DETAILS_CLASS_NAME);
        return intent;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {
    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        // check the icon. if good, just return.
        if (sIcon == null) {
            sIcon = getPackageIcon(packageManager, PKG_NAME);
        } else {
            Log.d(TAG, "icon is ok, no need to create again");
        }
        return sIcon;
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/LightningWallAction.java
public class LightningWallAction extends Action {
    public static final String TAG = "LightningwallAction";
    public static final String STR_DESC = "View in LightningWall";
    public static final String PKG_NAME = "de.defim.apk.lightningwall";
    public static final String ACTION_NAME = "de.defim.apk.lightningwall.action.NOTIFY";
    public static final String ARG_PKG_NAME = "pkg";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_lightningwall);
        keyShowInAppInfo = sModRes.getString(R.string.key_lightningwall_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_lightningwall_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_lightningwall_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.lightningwall_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.lightningwall_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.lightningwall_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.lightningwall_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        return null;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {
        Intent intent = new Intent(ACTION_NAME);
        intent.setPackage(PKG_NAME);
        intent.putExtra(ARG_PKG_NAME, pkgName);
        Log.d(TAG, "send broadcast:" + intent + ", pkg: " + pkgName);
        context.sendBroadcast(intent);
    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        return getPackageIcon(packageManager, PKG_NAME);
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/SearchAction.java
public class SearchAction extends Action {
    public static final String TAG = "SearchAction";
    public static final String STR_DESC = "Search";
    // the default of http uri prefix
    public static final String URI_HTTP_PREFIX = "http://";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;
    // key for customize switch
    public static String keyCustomize;
    // key for customize url
    public static String keyUrl;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;
    // key for customize switch default
    public static boolean customizeDefault = false;
    // key for url default
    public static String urlDefault = "";

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    public static boolean isCustomize = false;
    public static String url = "";
    /* the key should the sub class overwrite ------------end */

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_search);
        keyShowInAppInfo = sModRes.getString(R.string.key_search_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_search_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_search_status_bar);
        // key of customize and url
        keyCustomize = sModRes.getString(R.string.key_search_customize_url);
        keyUrl = sModRes.getString(R.string.key_search_url);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.search_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.search_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.search_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.search_default);
        // default url and customize
        urlDefault = sModRes.getString(R.string.search_url_default);
        customizeDefault = sModRes.getBoolean(R.bool.search_customize_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        // should use customize url or not
        isCustomize = preferences.getBoolean(keyCustomize, customizeDefault);
        // the url of customize
        url = preferences.getString(keyUrl, urlDefault);

        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow + "isCustomize:" + isCustomize + "url:" + url);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else if (key.equals(keyCustomize)) {
            isCustomize = Boolean.valueOf(value);
        } else if (key.equals(keyUrl)) {
            url = value;
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    /**
     * get final url search action will use
     *
     * @return url search action will use
     */
    public static String getUrl() {
        String str = urlDefault;
        if (isCustomize) {
            Log.d(TAG, "search url customized: " + url);
            if (Uri.parse(url).getScheme() == null) {
                // if the scheme is null, set it to http
                str = SearchAction.URI_HTTP_PREFIX + url;
                Log.d(TAG, "new url didn't contain prefix, new:" + str);
            } else {
                // if url is ok, just set it
                str = url;
            }
        }
        return str;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        // check if we should use default url or default url
        String str = getUrl();
        intent.setData(Uri.parse(str + pkgName));
        return intent;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {

    }

    /**
     * init the icon from UI
     *
     * @param res resource
     */
    public Action initIcon(Resources res) {
        FrameworksHook.getDefaultIcons(res);
        return this;
    }

    /**
     * need to call initIcon before this method.
     *
     * @param packageManager package manager
     * @return the icon
     */
    @Override
    public Drawable getIcon(PackageManager packageManager) {
        return FrameworksHook.getIconSearch();
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/PlayAction.java
public class PlayAction extends Action {
    public static final String TAG = "PlayAction";
    public static final String STR_DESC = "View in Play Store";
    public static final String PKG_NAME = "com.android.vending";
    public static final String URI_BROWSER = "http://play.google.com/store/apps/details?id=";
    public static final String URI_MARKET = "market://details?id=";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;
    // add for market - browser switch
    public static String keyIsMarket;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;
    public static boolean isMarketDefault = false;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    public static boolean isMarket = false;
    /* the key should the sub class overwrite ------------end */
    // just need to init the icon and listener once
    // EDIT: maybe the icon is already one instance in the system
    public static Drawable sIcon = null;
    //public static View.OnClickListener sOnClickListener = null;
    // EDIT: the on click listener should be different

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_play);
        keyShowInAppInfo = sModRes.getString(R.string.key_play_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_play_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_play_status_bar);
        keyIsMarket = sModRes.getString(R.string.key_play_is_market);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.play_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.play_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.play_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.play_default);
        isMarketDefault = sModRes.getBoolean(R.bool.play_is_market_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        isMarket = preferences.getBoolean(keyIsMarket, isMarketDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                ",isShowInRecentTask:" + isShowInRecentTask + ",isShowInAppInfo:" + isShowInAppInfo
                + ",isShow:" + isShow + ",isMarket:" + isMarket);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else if (key.equals(keyIsMarket)) {
            isMarket = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        // check the icon. if good, just return.
        // TODO: check if the app is just install or upgrade and the icon should be changed
        if (sIcon == null) {
//        Drawable pkgIcon = null;
            sIcon = getPackageIcon(packageManager, PKG_NAME);
        } else {
            Log.d(TAG, "icon is ok, no need to create again");
        }
        return sIcon;
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse((isMarket ? URI_MARKET : URI_BROWSER) + pkgName));
        return intent;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/AppInfoAction.java
public class AppInfoAction extends Action {
    public static final String TAG = "AppInfoAction";
    //TODO: get menu description from xml
    public static final String STR_DESC = "Show info screen of this app";
    public static final String PKG_NAME = StaticData.PKG_NAME_SETTINGS;

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    //    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    //    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    //    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    public static Drawable sIcon = null;

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_appinfo);
//        keyShowInAppInfo = sModRes.getString(R.string.key_appinfo_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_appinfo_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_appinfo_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.appinfo_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.appinfo_recent_task_default);
//        showInAppInfoDefault = sModRes.getBoolean(R.bool.appinfo_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.appinfo_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
//        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
//                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
//        } else if (key.equals(keyShowInAppInfo)) {
//            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                Uri.fromParts("package", pkgName, null));
        intent.setComponent(intent.resolveActivity(context.getPackageManager()));
        return intent;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    @Override
    public void handleData(Context context, String pkgName) {

    }

    @Override
    public Drawable getIcon(PackageManager packageManager) {
        // check the icon. if good, just return.
        if (sIcon == null) {
            sIcon = getPackageIcon(packageManager, PKG_NAME);
        } else {
            Log.d(TAG, "icon is ok, no need to create again");
        }
        return sIcon;
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }
}
app/src/main/java/daylemk/xposed/xbridge/action/ClipBoardAction.java
public class ClipBoardAction extends Action {
    public static final String TAG = "ClipBoardAction";
    public static final String STR_DESC = "Copy to clipboard";

    public static final String ARG_PACKAGE_NAME = "package";

    /* the key should the sub class overwrite ------------begin */
    public static String keyShowInStatusBar;
    public static String keyShowInRecentTask;
    public static String keyShowInAppInfo;
    public static String keyShow;

    public static boolean showInStatusBarDefault = true;
    public static boolean showInRecentTaskDefault = true;
    public static boolean showInAppInfoDefault = true;
    public static boolean showDefault = true;

    public static boolean isShowInRecentTask = true;
    public static boolean isShowInStatusBar = true;
    public static boolean isShowInAppInfo = true;
    public static boolean isShow = true;
    /* the key should the sub class overwrite ------------end */

    /**
     * load the key from the string resource
     *
     * @param sModRes the module resource of package
     */
    public static void loadPreferenceKeys(Resources sModRes) {
        keyShow = sModRes.getString(R.string.key_clipboard);
        keyShowInAppInfo = sModRes.getString(R.string.key_clipboard_app_info);
        keyShowInRecentTask = sModRes.getString(R.string.key_clipboard_recent_task);
        keyShowInStatusBar = sModRes.getString(R.string.key_clipboard_status_bar);
        // get the default value of this action
        showInStatusBarDefault = sModRes.getBoolean(R.bool.clipboard_status_bar_default);
        showInRecentTaskDefault = sModRes.getBoolean(R.bool.clipboard_recent_task_default);
        showInAppInfoDefault = sModRes.getBoolean(R.bool.clipboard_app_info_default);
        showDefault = sModRes.getBoolean(R.bool.clipboard_default);
    }

    public static void loadPreference(SharedPreferences preferences) {
        isShowInStatusBar = preferences.getBoolean(keyShowInStatusBar,
                showInStatusBarDefault);
        isShowInRecentTask = preferences.getBoolean(keyShowInRecentTask,
                showInRecentTaskDefault);
        isShowInAppInfo = preferences.getBoolean(keyShowInAppInfo,
                showInAppInfoDefault);
        isShow = preferences.getBoolean(keyShow,
                showDefault);
        Log.d(TAG, "load preference: " + "isShowInStatusBar:" + isShowInStatusBar +
                "isShowInRecentTask:" + isShowInRecentTask + "isShowInAppInfo:" + isShowInAppInfo
                + "isShow:" + isShow);
    }

    public static boolean onReceiveNewValue(String key, String value) {
        boolean result = true;
        if (key.equals(keyShow)) {
            isShow = Boolean.valueOf(value);
        } else if (key.equals(keyShowInAppInfo)) {
            isShowInAppInfo = Boolean.valueOf(value);
        } else if (key.equals(keyShowInRecentTask)) {
            isShowInRecentTask = Boolean.valueOf(value);
        } else if (key.equals(keyShowInStatusBar)) {
            isShowInStatusBar = Boolean.valueOf(value);
        } else {
            // if not found it, return false
            result = false;
        }
        return result;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName) {
        return null;
    }

    @Override
    protected Intent getIntent(Hook hook, Context context, String pkgName, Intent originalIntent) {
        return null;
    }

    /**
     * init the icon from UI
     *
     * @param res resource
     */
    public Action initIcon(Resources res) {
        FrameworksHook.getDefaultIcons(res);
        return this;
    }

    /**
     * need to call initIcon before this method.
     *
     * @param packageManager package manager
     * @return the icon
     */
    @Override
    public Drawable getIcon(PackageManager packageManager) {
        return FrameworksHook.getIconCopy();
    }

    @Override
    public String getMenuTitle() {
        return STR_DESC;
    }

    @Override
    public void handleData(final Context context, final String pkgName) {
        Log.d(TAG, "handle in the ClipBoard");
        // need run in the main thread
        new Handler(context.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService
                        (Context
                                .CLIPBOARD_SERVICE);
                ClipData clipData = ClipData.newPlainText(ARG_PACKAGE_NAME, pkgName);
                clipboardManager.setPrimaryClip(clipData);
                Context xBridgeContext = Hook.getXBridgeContext(context);

                String str = xBridgeContext.getString(R.string.package_name_copied);
                Toast.makeText(context, str + "\n" + pkgName, Toast.LENGTH_LONG).show();
            }
        });
    }
}


Question: package daylemk.xposed.xbridge.hook;
import android.app.Application;
import android.content.Context;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import daylemk.xposed.xbridge.R;
import daylemk.xposed.xbridge.action.Action;
import daylemk.xposed.xbridge.action.AppInfoAction;
import daylemk.xposed.xbridge.action.AppOpsAction;
import daylemk.xposed.xbridge.action.AppSettingsAction;
import daylemk.xposed.xbridge.action.ClipBoardAction;
import daylemk.xposed.xbridge.action.LightningWallAction;
import daylemk.xposed.xbridge.action.MyAndroidToolsAction;
import daylemk.xposed.xbridge.action.NotifyCleanAction;
import daylemk.xposed.xbridge.action.PlayAction;
import daylemk.xposed.xbridge.action.SearchAction;
import daylemk.xposed.xbridge.action.XHaloFloatingWindowAction;
import daylemk.xposed.xbridge.action.XPrivacyAction;
import daylemk.xposed.xbridge.data.OnPreferenceChangedReceiver;
import daylemk.xposed.xbridge.data.StaticData;
import daylemk.xposed.xbridge.ui.SizeInputFragment;
import daylemk.xposed.xbridge.utils.Log;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;




/**
 * Status bar hook
 * Created by DayLemK on 2015/4/30.
 */
public class StatusBarHook extends Hook {
    public static final String TAG = "StatusBarHook";
    public static final String PKG_KEY_GUARD = "com.android.keyguard";

    // TODO: need get this value from original class
    public static final int FLAG_EXCLUDE_NONE = 0;

    // set the field and we can use it later to collapse notification or unlock screen
    private Object statusBarObject = null;
    private Context context = null;
    private PackageManager packageManager = null;
    // the OnDismissActionInterface
    private Class<?> onDismissActionInterface = null;
    /**
     * notification guts id show always be the same, so, just get once
     */
    private int idGuts = -1;
    /**
     * inspect item layout params should get once too
     */
    private LinearLayout.LayoutParams inspectLayoutParams;

    @Override
    public void initZygote(StartupParam startupParam) throws Throwable {
        super.initZygote(startupParam);

//        inspectItemButton = sModuleRes.fwd(R.layout.notification_inspect_item);
    }

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws
            Throwable {
        super.handleLoadPackage(loadPackageParam);
        Log.v(TAG, "enter the status bar hook");
        Class<?> systemUIAppClass = XposedHelpers.findClass(StaticData.PKG_NAME_SYSTEMUI +
                        ".SystemUIApplication",
                loadPackageParam
                        .classLoader);
        XposedBridge.hookAllMethods(systemUIAppClass, "onCreate", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                Log.d(TAG, "SystemUIApplication onCreate hook");
                Application app = (Application) param.thisObject;
                Log.d(TAG, "app: " + app);
                app.registerReceiver(new OnPreferenceChangedReceiver(), new IntentFilter
                        (StaticData.ACTION_PREFERENCE_CHANGED));
            }
        });

        final Class<?> baseStatusBarClass = XposedHelpers.findClass(StaticData.PKG_NAME_SYSTEMUI +
                ".statusbar.BaseStatusBar", loadPackageParam.classLoader);
        Log.d(TAG, "BaseStatusBar: " + baseStatusBarClass);
        String methodName = "inflateGuts";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Why change the name of method ???
            methodName = "bindGuts";
        }
        XposedBridge.hookAllMethods(baseStatusBarClass, methodName, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                if (!Action.isActionsShowInStatusBar()) {
                    // if none of this is showed here, do nothing
                    return;
                }

                Log.v(TAG, "after inflateGuts/bindGuts method hooked");
                super.afterHookedMethod(param);
                // set the statusBar everytime
                if (!param.thisObject.equals(statusBarObject)) {
                    Log.w(TAG, "statusBar is different: " + statusBarObject);
                    statusBarObject = param.thisObject;
                    context = (Context) XposedHelpers.getObjectField
                            (statusBarObject, "mContext");
                    Log.d(TAG, "context: " + context);
                }
                final Resources res = context.getResources();

                // 1) get the notification guts id
                if (idGuts == -1) {
                    // ignore: and inspect item id
                    // EDIT: get guts view here
                    idGuts = res.getIdentifier("notification_guts", "id",
                            StaticData.PKG_NAME_SYSTEMUI);
                }
                Log.d(TAG, "guts id: " + idGuts);

                // move get guts view here, so we can check if the action is already injected or not
                final Object expandNotiRowObject = param.args[0];
                Log.d(TAG, "expandNotiRowObject: " + expandNotiRowObject);
                final FrameLayout layoutGuts = (FrameLayout) XposedHelpers.callMethod
                        (expandNotiRowObject, "findViewById", idGuts);
                Log.d(TAG, "get the guts view: " + layoutGuts);
                Log.d(TAG, "guts children number: " + layoutGuts.getChildCount());
                // check if the view already exists
                // EDIT: we should use the dynamic generated id, 'cause that will not be equal
                // with another package static id

                boolean isPlayNeed2Add = false;
                boolean isOpsNeed2Add = false;
                boolean isAppSetNeed2Add = false;
                boolean isClipBoardNeed2Add = false;
                boolean isSearchNeed2Add = false;
                boolean isXPrivacyNeed2Add = false;
                boolean isAppInfoNeed2Add = false;
                boolean isNotifyCleanNeed2Add = false;
                boolean isLightningWallNeed2Add = false;
                boolean isXHaloFloatingWinNeed2Add = false;
                boolean isMyAndroidToolsNeed2Add = false;
                // check if need to add action
                if (PlayAction.isShow && PlayAction.isShowInStatusBar) {
                    isPlayNeed2Add = Action.isNeed2Add(layoutGuts, PlayAction.class);
                }
                if (AppOpsAction.isShow && AppOpsAction.isShowInStatusBar) {
                    isOpsNeed2Add = Action.isNeed2Add(layoutGuts, AppOpsAction.class);
                }
Answer:                 if (AppSettingsAction.isShow && AppSettingsAction.isShowInStatusBar) {