package de.theknut.xposedgelsettings.hooks.gestures; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.Point; import android.view.Display; import android.view.View; import android.view.ViewPropertyAnimator; import android.view.WindowManager; import android.widget.FrameLayout.LayoutParams; import net.margaritov.preference.colorpicker.ColorPickerPreference; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import de.theknut.xposedgelsettings.hooks.Common; import de.theknut.xposedgelsettings.hooks.HooksBaseClass; import de.theknut.xposedgelsettings.hooks.ObfuscationHelper; import de.theknut.xposedgelsettings.hooks.ObfuscationHelper.Fields; import de.theknut.xposedgelsettings.hooks.PreferencesHelper; import de.theknut.xposedgelsettings.hooks.Utils; import static de.robv.android.xposed.XposedHelpers.callMethod; import static de.robv.android.xposed.XposedHelpers.getObjectField; public class GestureHelper extends HooksBaseClass { public enum Gestures { DOWN_LEFT, DOWN_MIDDLE, DOWN_RIGHT, UP_LEFT, UP_MIDDLE, UP_RIGHT, DOUBLE_TAP, NONE } public static float gestureDistance = Utils.dpToPx(50); static int animateDuration = 300; static boolean isAnimating = false; static ViewPropertyAnimator hideAnimation; static AnimatorListener hideListener; static ViewPropertyAnimator showAnimation; static AnimatorListener showListener; static View mHotseat; static int FORCEHIDE = 0xB00B5; static WindowManager wm; static Display display; static Point size; static int width; static int height; static int sector; static boolean isLandscape; static Method method; static void init() throws IOException { if (DEBUG) log("Init Gestures"); wm = (WindowManager) Common.LAUNCHER_CONTEXT.getSystemService(Context.WINDOW_SERVICE); display = wm.getDefaultDisplay(); size = new Point(); display.getSize(size); width = size.x; height = size.y; sector = width / 3; if (PreferencesHelper.appdockSettingsSwitch && PreferencesHelper.hideAppDock) { isAnimating = false; mHotseat = (View) getObjectField(Common.LAUNCHER_INSTANCE, Fields.lHotseat); mHotseat.setBackgroundColor(Color.parseColor(ColorPickerPreference.convertToARGB(PreferencesHelper.appDockBackgroundColor))); showListener = new AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { isAnimating = false; Common.APPDOCK_HIDDEN = false; if (DEBUG) log("OnEnd Showanimation"); } @Override public void onAnimationCancel(Animator animation) { isAnimating = false; Common.APPDOCK_HIDDEN = false; if (DEBUG) log("OnCancel Showanimation"); } @Override public void onAnimationRepeat(Animator animation) { isAnimating = true; if (DEBUG) log("OnRepeat Showanimation"); } @Override public void onAnimationStart(Animator animation) { //Common.APPDOCK_HIDDEN = false; isAnimating = true; mHotseat.setVisibility(View.VISIBLE); } }; hideListener = new AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { hide(); if (DEBUG) log("OnEnd Hideanimation"); } @Override public void onAnimationCancel(Animator animation) { hide(); if (DEBUG) log("OnCancel Hideanimation"); } @Override public void onAnimationRepeat(Animator animation) { isAnimating = true; if (DEBUG) log("OnRepeat Hideanimation"); } @Override public void onAnimationStart(Animator animation) { //Common.APPDOCK_HIDDEN = true; isAnimating = true; } public void hide() { mHotseat.setVisibility(View.INVISIBLE); LayoutParams lp = (LayoutParams) mHotseat.getLayoutParams(); lp.width = 0; lp.height = 0; mHotseat.setLayoutParams(lp); isAnimating = false; Common.APPDOCK_HIDDEN = true; } }; } } static String getGestureKey(Gestures gesture) { switch (gesture) { case DOWN_LEFT: return "gesture_one_down_left"; case DOWN_MIDDLE: return "gesture_one_down_middle"; case DOWN_RIGHT: return "gesture_one_down_right"; case UP_LEFT: return "gesture_one_up_left"; case UP_MIDDLE: return "gesture_one_up_middle"; case UP_RIGHT: return "gesture_one_up_right"; case DOUBLE_TAP: return "gesture_double_tap"; default: return ""; } } static void handleGesture(String gestureKey, String action) { handleGesture(Common.LAUNCHER_CONTEXT, gestureKey, action); } static public void handleGesture(final Context context, String gestureKey, String action) { if (action.equals("NOTIFICATION_BAR")) { Intent myIntent = new Intent(); myIntent.putExtra(Common.XGELS_ACTION_EXTRA, Common.XGELS_ACTION_OTHER); myIntent.putExtra(Common.XGELS_ACTION, "SHOW_NOTIFICATION_BAR"); myIntent.setAction(Common.XGELS_INTENT); context.sendBroadcast(myIntent); } else if (action.equals("QUICKSETTINGS_PANEL")) { Intent myIntent = new Intent(); myIntent.putExtra(Common.XGELS_ACTION_EXTRA, Common.XGELS_ACTION_OTHER); myIntent.putExtra(Common.XGELS_ACTION, "SHOW_SETTINGS_PANEL"); myIntent.setAction(Common.XGELS_INTENT); context.sendBroadcast(myIntent); } else if (action.equals("OPEN_APPDRAWER")) { Common.LAUNCHER_INSTANCE.runOnUiThread(new Runnable() { @Override public void run() { if (Common.GNL_VERSION >= ObfuscationHelper.GNL_5_3_23) { callMethod(Common.LAUNCHER_INSTANCE, "showAppsView", true, false, false, false); } else if (Common.PACKAGE_OBFUSCATED && Common.GNL_VERSION >= ObfuscationHelper.GNL_4_1_21) { Object objectField = getObjectField(Common.LAUNCHER_INSTANCE, Fields.lAppsCustomizeTabHost); try { method.invoke(Common.LAUNCHER_INSTANCE, true, callMethod(objectField, ObfuscationHelper.Methods.acthGetContentTypeForTabTag, "APPS"), false); } catch (IllegalAccessException e) { e.printStackTrace(); log("Ex1"); } catch (InvocationTargetException e) { log("Ex2"); e.printStackTrace(); } } else { callMethod(Common.LAUNCHER_INSTANCE, "onClickAllAppsButton", new View(context)); } } }); } else if (action.equals("LAST_APP")) { Intent myIntent = new Intent(); myIntent.putExtra(Common.XGELS_ACTION_EXTRA, Common.XGELS_ACTION_OTHER); myIntent.putExtra(Common.XGELS_ACTION, "GESTURE_LAST_APP"); myIntent.setAction(Common.XGELS_INTENT); context.sendBroadcast(myIntent); } else if (action.equals("SHOW_RECENTS")) { Intent myIntent = new Intent(); myIntent.putExtra(Common.XGELS_ACTION_EXTRA, Common.XGELS_ACTION_OTHER); myIntent.putExtra(Common.XGELS_ACTION, "SHOW_RECENTS"); myIntent.setAction(Common.XGELS_INTENT); context.sendBroadcast(myIntent); } else if (action.equals("OPEN_SETTINGS")) { Intent LaunchIntent = new Intent(android.provider.Settings.ACTION_SETTINGS); LaunchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Utils.startActivity(LaunchIntent); } else if (action.equals("SCREEN_OFF")) { Intent myIntent = new Intent(); myIntent.putExtra(Common.XGELS_ACTION_EXTRA, Common.XGELS_ACTION_OTHER); myIntent.putExtra(Common.XGELS_ACTION, "GO_TO_SLEEP"); myIntent.setAction(Common.XGELS_INTENT); context.sendBroadcast(myIntent); } else if (action.equals("TOGGLE_DOCK")) { if (PreferencesHelper.appdockSettingsSwitch && PreferencesHelper.hideAppDock) { if (mHotseat.getAlpha() == 0.0f) { showAppdock(animateDuration); } else { hideAppdock(animateDuration); } } } else if (action.equals("DRAWER_SEARCH")) { callMethod(Common.LAUNCHER_INSTANCE, "showAppsView", true, false, true, true); } else if (action.contains("APP")) { String pkg = PreferencesHelper.prefs.getString(gestureKey + "_launch", ""); if (!pkg.equals("")) { Intent LaunchIntent = context.getPackageManager().getLaunchIntentForPackage(pkg); LaunchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Utils.startActivity(LaunchIntent); } } } static Gestures identifyGesture(float upX, float upY, float downX, float downY) { if (isSwipeDOWN(upY, downY)) { if (isSwipeLEFT(upX, downX, true)) { return Gestures.DOWN_LEFT; } else if (isSwipeRIGHT(upX, downX, true)) { return Gestures.DOWN_RIGHT; } else if (isSwipeMIDDLE(upX, downX, true)) { return Gestures.DOWN_MIDDLE; } else { // wait, what?? } } else if (isSwipeUP(upY, downY)) { if (isSwipeLEFT(upX, downX, false)) { return Gestures.UP_LEFT; } else if (isSwipeRIGHT(upX, downX, false)) { return Gestures.UP_RIGHT; } else if (isSwipeMIDDLE(upX, downX, false)) { return Gestures.UP_MIDDLE; } else { // wait, what?? } } return Gestures.NONE; } static boolean isSwipeDOWN(float upY, float downY) { return (upY - downY) > gestureDistance; } static boolean isSwipeUP(float upY, float downY) { return ((upY - downY) < -gestureDistance); } static boolean isSwipeLEFT(float upX, float downX, boolean isUP) { if (isUP) { if (PreferencesHelper.gesture_one_down_middle.equals("NONE")) { return downX < (width / 2); } } else { if (PreferencesHelper.gesture_one_up_middle.equals("NONE")) { return downX < (width / 2); } } return downX < sector; } static boolean isSwipeMIDDLE(float upX, float downX, boolean isUP) { return downX > sector && downX < (sector * 2); } static boolean isSwipeRIGHT(float upX, float downX, boolean isUP) { if (isUP) { if (PreferencesHelper.gesture_one_down_middle.equals("NONE")) { return downX > (width / 2); } } else { if (PreferencesHelper.gesture_one_up_middle.equals("NONE")) { return downX > (width / 2); } } return downX > (sector * 2); } static void showAppdock(int duration) { mHotseat = (View) getObjectField(Common.LAUNCHER_INSTANCE, Fields.lHotseat); if (Common.LAUNCHER_INSTANCE == null || mHotseat == null || mHotseat.getAlpha() != 0.0f) { if (DEBUG) log("Don't show App Dock"); return; } if (DEBUG) log("Show App Dock"); final LayoutParams lp = (LayoutParams) mHotseat.getLayoutParams(); if (isLandscape) { lp.width = Common.HOTSEAT_BAR_HEIGHT; lp.height = LayoutParams.MATCH_PARENT; } else { lp.width = LayoutParams.MATCH_PARENT; lp.height = Common.HOTSEAT_BAR_HEIGHT; } mHotseat.setLayoutParams(lp); showAnimation = mHotseat.animate(); showAnimation.setListener(showListener); showAnimation .alpha(1f) .setDuration(duration) .start(); } static void hideAppdock(final int duration) { if (duration == FORCEHIDE) { mHotseat = (View) getObjectField(Common.LAUNCHER_INSTANCE, Fields.lHotseat); LayoutParams lp = (LayoutParams) mHotseat.getLayoutParams(); lp.width = 0; lp.height = 0; isAnimating = false; mHotseat.setAlpha(0.0f); mHotseat.setLayoutParams(lp); } if (Common.LAUNCHER_INSTANCE == null || mHotseat == null || isAnimating || mHotseat.getAlpha() == 0.0f) { if (DEBUG) log("Don't hide App Dock\n" + "Was Launcher null: " + (Common.LAUNCHER_INSTANCE == null) + "\nWas Hotseat null: " + (mHotseat == null) + "\nisAnimating: " + isAnimating + "\nAlpha == 0.0f: " + (mHotseat.getAlpha() == 0.0f)); return; } if (DEBUG) log("Hide App Dock (duration " + duration + ")"); if (duration != 0) { mHotseat = (View) getObjectField(Common.LAUNCHER_INSTANCE, Fields.lHotseat); hideAnimation = mHotseat.animate(); hideAnimation.setListener(hideListener); Common.LAUNCHER_INSTANCE.runOnUiThread(new Runnable() { @Override public void run() { hideAnimation .alpha(0f) .setListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { callMethod(Common.LAUNCHER_INSTANCE, ObfuscationHelper.Methods.lCloseFolder); } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }) .setDuration(duration) .start(); } }); } else { LayoutParams lp = (LayoutParams) mHotseat.getLayoutParams(); lp.width = 0; lp.height = 0; mHotseat.setLayoutParams(lp); } } }