diff --git a/README.md b/README.md index 3784b807..ce39737d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +#### Fork from evermind-zz +added goto sleep on double tap on lockscreen + +#### original readme content below: + # Firefds Kit [Q] Xposed, EdXposed 4 and EdXposed 5 module for Samsung Q devices. diff --git a/firefdskit/src/main/java/sb/firefds/q/firefdskit/FeatureFactory.java b/firefdskit/src/main/java/sb/firefds/q/firefdskit/FeatureFactory.java new file mode 100644 index 00000000..487c0ab6 --- /dev/null +++ b/firefdskit/src/main/java/sb/firefds/q/firefdskit/FeatureFactory.java @@ -0,0 +1,35 @@ +package sb.firefds.q.firefdskit; + +import sb.firefds.q.firefdskit.features.DoubleTapStatusBarOrLockScreenSdk29; +import sb.firefds.q.firefdskit.features.Feature; + +public class FeatureFactory { + + private FeatureFactory() { + } + + /** + * Create instances of features if available. + * + * @param featureName the feature you want to instantiate. See {@link sb.firefds.q.firefdskit.utils.Preferences} + * @return null if feature is not available other the feature you want. + */ + public static Feature createFeature(final String featureName) { + Feature feature = null; + + if (DoubleTapStatusBarOrLockScreenSdk29.isPlatformSupported(featureName)) { + feature = new DoubleTapStatusBarOrLockScreenSdk29(); + } + return feature; + } + + /** + * Check if a feature is available on this android platform. + * + * @param featureName the feature you want to instantiate. See {@link sb.firefds.q.firefdskit.utils.Preferences} + * @return true if available otherwise false + */ + public static boolean hasFeature(final String featureName) { + return DoubleTapStatusBarOrLockScreenSdk29.isPlatformSupported(featureName); + } +} diff --git a/firefdskit/src/main/java/sb/firefds/q/firefdskit/XSysUIFeaturePackage.java b/firefdskit/src/main/java/sb/firefds/q/firefdskit/XSysUIFeaturePackage.java index 81f25729..df9e3d5f 100644 --- a/firefdskit/src/main/java/sb/firefds/q/firefdskit/XSysUIFeaturePackage.java +++ b/firefdskit/src/main/java/sb/firefds/q/firefdskit/XSysUIFeaturePackage.java @@ -37,6 +37,9 @@ import de.robv.android.xposed.XSharedPreferences; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; +import sb.firefds.q.firefdskit.features.Feature; +import sb.firefds.q.firefdskit.features.Utils; +import sb.firefds.q.firefdskit.utils.Preferences; import static sb.firefds.q.firefdskit.utils.Packages.SYSTEM_UI; import static sb.firefds.q.firefdskit.utils.Preferences.PREF_CLOCK_DATE_ON_RIGHT; @@ -80,6 +83,7 @@ public class XSysUIFeaturePackage { public static void doHook(XSharedPreferences prefs, ClassLoader classLoader) { + Utils utils = new Utils(); try { if (prefs.getBoolean(PREF_STATUSBAR_DOUBLE_TAP, false)) { XposedHelpers.findAndHookMethod(CUSTOM_SDK_MONITOR, @@ -88,6 +92,13 @@ public static void doHook(XSharedPreferences prefs, ClassLoader classLoader) { XC_MethodReplacement.returnConstant(Boolean.TRUE)); } + if (prefs.getBoolean(Preferences.PREF_LOCKSCREEN_DOUBLE_TAP, false)) { + Feature feature = FeatureFactory.createFeature(Preferences.PREF_LOCKSCREEN_DOUBLE_TAP); + if (feature != null) { + feature.inject(classLoader, prefs, utils); + } + } + if (prefs.getBoolean(PREF_DISABLE_EYE_STRAIN_DIALOG, false)) { XposedHelpers.findAndHookMethod(TOGGLE_SLIDER_VIEW, classLoader, diff --git a/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/DoubleTapStatusBarOrLockScreenSdk29.java b/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/DoubleTapStatusBarOrLockScreenSdk29.java new file mode 100644 index 00000000..cfa10443 --- /dev/null +++ b/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/DoubleTapStatusBarOrLockScreenSdk29.java @@ -0,0 +1,45 @@ +package sb.firefds.q.firefdskit.features; + +import android.content.Context; +import android.os.Build; +import android.os.PowerManager; +import android.view.MotionEvent; + +import java.util.Objects; + +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XSharedPreferences; +import sb.firefds.q.firefdskit.utils.Preferences; + +import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; +import static de.robv.android.xposed.XposedHelpers.getObjectField; + +public class DoubleTapStatusBarOrLockScreenSdk29 extends DoubleTapStatusBarOrLockScreenSdk31AndHigher { + + public static boolean isPlatformSupported(final String featureName) { + return Build.VERSION.SDK_INT == 29 // Android 10 + && (Objects.equals(featureName, Preferences.PREF_LOCKSCREEN_DOUBLE_TAP)); + } + + @Override + public void inject(final ClassLoader classLoader, + final XSharedPreferences pref, + final Utils utils) { + findAndHookMethod("com.android.systemui.statusbar.phone.PanelView", classLoader, "onFinishInflate", new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) { + final Context context = (Context) getObjectField(param.thisObject, "mContext"); + if (mPowerManager == null) + mPowerManager = context.getSystemService(PowerManager.class); + registerGestureDetectorListener(param, context, mPowerManager); + } + }); + + findAndHookMethod("com.android.systemui.statusbar.phone.NotificationPanelView", classLoader, "onTouchEvent", MotionEvent.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) { + fireOnTouchEventIfPossible((MotionEvent) param.args[0], pref); + } + }); + } +} diff --git a/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/DoubleTapStatusBarOrLockScreenSdk31AndHigher.java b/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/DoubleTapStatusBarOrLockScreenSdk31AndHigher.java new file mode 100644 index 00000000..8bb50f6d --- /dev/null +++ b/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/DoubleTapStatusBarOrLockScreenSdk31AndHigher.java @@ -0,0 +1,117 @@ +package sb.firefds.q.firefdskit.features; + +import android.content.Context; +import android.os.Build; +import android.os.PowerManager; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.View; + +import java.util.Objects; + +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XSharedPreferences; + +import static de.robv.android.xposed.XposedHelpers.callMethod; +import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; +import static de.robv.android.xposed.XposedHelpers.getBooleanField; +import static de.robv.android.xposed.XposedHelpers.getIntField; +import static de.robv.android.xposed.XposedHelpers.getObjectField; +import static sb.firefds.q.firefdskit.utils.Preferences.PREF_LOCKSCREEN_DOUBLE_TAP; + +public class DoubleTapStatusBarOrLockScreenSdk31AndHigher implements Feature { + + protected Object mNotificationPanelViewController; + protected GestureDetector mDoubleTapGesture; + protected int mStatusBarHeight = 0; + protected PowerManager mPowerManager; + private int mStatusBarHeaderHeight = 0; + private long mLastDownEvent = 0L; + + public static boolean isPlatformSupported(final String featureName) { + return Build.VERSION.SDK_INT >= 31 + && (Objects.equals(featureName, PREF_LOCKSCREEN_DOUBLE_TAP)); + } + + @Override + public void inject(final ClassLoader classLoader, + final XSharedPreferences pref, + final Utils utils) { + final String notificationPanelViewController = utils.getComAndroidSystemui_NotificationPanelViewControllerClassName(); + findAndHookMethod(notificationPanelViewController, classLoader, "onFinishInflate", new XC_MethodHook() { + + @Override + protected void afterHookedMethod(MethodHookParam param) { + if (mPowerManager == null) + mPowerManager = (PowerManager) getObjectField(param.thisObject, "mPowerManager"); + mStatusBarHeaderHeight = getIntField(param.thisObject, "mStatusBarHeaderHeightKeyguard"); + final View view = (View) getObjectField(param.thisObject, "mView"); + registerGestureDetectorListener(param, view.getContext(), mPowerManager); + } + }); + + String touchHandler = utils.isSecurityPatchAfterDecember2022() ? "com.android.systemui.shade.PanelViewController$TouchHandler" : "com.android.systemui.statusbar.phone.PanelViewController$TouchHandler"; + findAndHookMethod(touchHandler, classLoader, "onTouch", View.class, MotionEvent.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) { + final String notificationPanelView = utils.isSecurityPatchAfterDecember2022() ? "com.android.systemui.shade.NotificationPanelView" : "com.android.systemui.statusbar.phone.NotificationPanelView"; + if (param.args[0].getClass().getName().equals(notificationPanelView)) { + fireOnTouchEventIfPossible((MotionEvent) param.args[1], pref); + } + } + }); + + if (pref.getBoolean(PREF_LOCKSCREEN_DOUBLE_TAP, false)) { + findAndHookMethod("com.android.systemui.statusbar.DragDownHelper", classLoader, "onInterceptTouchEvent", MotionEvent.class, new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) { + MotionEvent event = (MotionEvent) param.args[0]; + long time = event.getEventTime(); + View host = (View) getObjectField(param.thisObject, "host"); + if (mPowerManager == null) + mPowerManager = (PowerManager) host.getContext().getSystemService(Context.POWER_SERVICE); + if (event.getActionMasked() == MotionEvent.ACTION_DOWN + && event.getY() < mStatusBarHeaderHeight) { + if (time - mLastDownEvent < 300) { + callMethod(mPowerManager, "goToSleep", time); + } + mLastDownEvent = event.getEventTime(); + } + } + }); + } + } + + protected void registerGestureDetectorListener(final XC_MethodHook.MethodHookParam param, + final Context context, + final PowerManager powerManager) { + mNotificationPanelViewController = param.thisObject; + mStatusBarHeight = getIntField(param.thisObject, "mStatusBarMinHeight"); + + if (mDoubleTapGesture == null) { + mDoubleTapGesture = new GestureDetector(context, + new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDoubleTap(MotionEvent e) { + callMethod(powerManager, "goToSleep", e.getEventTime()); + return true; + } + }); + } + } + + protected void fireOnTouchEventIfPossible(final MotionEvent event, + final XSharedPreferences pref) { + if (mNotificationPanelViewController != null && mDoubleTapGesture != null) { + boolean isExpanded = getBooleanField(mNotificationPanelViewController, "mQsExpanded"); + boolean isPulsing = getBooleanField(mNotificationPanelViewController, "mPulsing"); + boolean isDozing = getBooleanField(mNotificationPanelViewController, "mDozing"); + boolean isKeyguard = getIntField(mNotificationPanelViewController, "mBarState") == 1 + && !isPulsing && !isDozing; + //boolean isStatusBar = event.getY() < mStatusBarHeight && !isExpanded; + + if (isKeyguard && pref.getBoolean(PREF_LOCKSCREEN_DOUBLE_TAP, false)) + mDoubleTapGesture.onTouchEvent(event); + } + } +} diff --git a/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/Feature.java b/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/Feature.java new file mode 100644 index 00000000..e0707a6c --- /dev/null +++ b/firefdskit/src/main/java/sb/firefds/q/firefdskit/features/Feature.java @@ -0,0 +1,20 @@ +package sb.firefds.q.firefdskit.features; + +import de.robv.android.xposed.XSharedPreferences; +import sb.firefds.q.firefdskit.FeatureFactory; + +/** + * A feature is the implementation of an modification you want to do with Xposed. + *
+ * Every class that implements {@link Feature} should also implement a static method + * that determines if a feature is supported on which platforms. The static method + * should have a signature like this: + *
+ * static boolean hasFeature(String featureName);
+ *