Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support trick_doubleTapLockScreen and trick_doubleTapStatusBar on android 10 #8

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions app/src/main/java/com/darkeyes/tricks/FeatureFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.darkeyes.tricks;

import com.darkeyes.tricks.features.DoubleTapStatusBarOrLockScreenSdk29;
import com.darkeyes.tricks.features.DoubleTapStatusBarOrLockScreenSdk31AndHigher;
import com.darkeyes.tricks.features.Feature;
import com.darkeyes.tricks.features.QuickPullDownFeatureSdk31AndHigher;

public class FeatureFactory {

private FeatureFactory() {
}

/**
* Create instances of features if available.
*
* @param featureName the feature you want to instantiate. See {@link com.darkeyes.tricks.features.FeatureNames}
* @return null if feature is not available other the feature you want.
*/
public static Feature createFeature(final String featureName) {
Feature feature = null;

if (DoubleTapStatusBarOrLockScreenSdk31AndHigher.isPlatformSupported(featureName)) {
feature = new DoubleTapStatusBarOrLockScreenSdk31AndHigher();
} else if (DoubleTapStatusBarOrLockScreenSdk29.isPlatformSupported(featureName)) {
feature = new DoubleTapStatusBarOrLockScreenSdk29();
} else if (QuickPullDownFeatureSdk31AndHigher.isPlatformSupported(featureName)) {
feature = new QuickPullDownFeatureSdk31AndHigher();
}
return feature;
}

/**
* Check if a feature is available on this android platform.
*
* @param featureName the feature you want to instantiate. See {@link com.darkeyes.tricks.features.FeatureNames}
* @return true if available otherwise false
*/
public static boolean hasFeature(final String featureName) {
boolean hasFeature = DoubleTapStatusBarOrLockScreenSdk31AndHigher.isPlatformSupported(featureName);
if (!hasFeature) {
hasFeature = DoubleTapStatusBarOrLockScreenSdk29.isPlatformSupported(featureName);
}
if (!hasFeature) {
hasFeature = QuickPullDownFeatureSdk31AndHigher.isPlatformSupported(featureName);
}
return hasFeature;
}
}
157 changes: 14 additions & 143 deletions app/src/main/java/com/darkeyes/tricks/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,18 @@
import android.text.Editable;
import android.text.TextWatcher;
import android.util.ArrayMap;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.TextView;

import com.darkeyes.tricks.features.Feature;
import com.darkeyes.tricks.features.FeatureNames;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.IXposedHookZygoteInit;
Expand Down Expand Up @@ -99,11 +96,6 @@ public class Main implements IXposedHookZygoteInit, IXposedHookLoadPackage {
private ArrayMap<String, Long> mLastTimestamps = new ArrayMap<>();
private long mDownTime = 0L;
private boolean mCameraGesture;
private GestureDetector mDoubleTapGesture;
private Object mNotificationPanelViewController;
private int mStatusBarHeight = 0;
private int mStatusBarHeaderHeight = 0;
private long mLastDownEvent = 0L;
private Object mLockPatterUtils;
private Object mLockCallback;
private Object mKeyguardMonitor;
Expand All @@ -113,8 +105,6 @@ public class Main implements IXposedHookZygoteInit, IXposedHookLoadPackage {
private float mBottom;
private Object mEdgeObject;
private String mOldEntry;
private Date securityPatch;
private Date december;

public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) {

Expand Down Expand Up @@ -170,12 +160,7 @@ protected void beforeHookedMethod(MethodHookParam param) {
}

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
securityPatch = format.parse(Build.VERSION.SECURITY_PATCH);
december = format.parse("2022-12-01");
} catch (ParseException ignored) {
}
final Utils utils = new Utils();

if (param.packageName.equals("com.android.systemui")) {
classLoader = param.classLoader;
Expand Down Expand Up @@ -366,131 +351,17 @@ protected void beforeHookedMethod(MethodHookParam param) {
}
}

if ((pref.getBoolean("trick_doubleTapStatusBar", false) || (pref.getBoolean("trick_doubleTapLockScreen", false))
|| pref.getBoolean("trick_quickPulldown", true)) && Build.VERSION.SDK_INT >= 31) {

String notificationPanelViewController = securityPatch.after(december) ? "com.android.systemui.shade.NotificationPanelViewController" : "com.android.systemui.statusbar.phone.NotificationPanelViewController";
findAndHookMethod(notificationPanelViewController, param.classLoader, "onFinishInflate", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
mNotificationPanelViewController = param.thisObject;

if (pref.getBoolean("trick_doubleTapStatusBar", false) || pref.getBoolean("trick_doubleTapLockScreen", false)) {
mStatusBarHeight = getIntField(param.thisObject, "mStatusBarMinHeight");
mStatusBarHeaderHeight = getIntField(param.thisObject, "mStatusBarHeaderHeightKeyguard");
View view = (View) getObjectField(param.thisObject, "mView");
if (mPowerManager == null)
mPowerManager = (PowerManager) getObjectField(param.thisObject, "mPowerManager");
if (mDoubleTapGesture == null) {
mDoubleTapGesture = new GestureDetector(view.getContext(),
new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
callMethod(mPowerManager, "goToSleep", e.getEventTime());
return true;
}
});
}
}
}
});

if (pref.getBoolean("trick_quickPulldown", true)) {
if (Build.VERSION.SDK_INT >= 33) {
findAndHookMethod("com.android.systemui.statusbar.phone.HeadsUpTouchHelper", param.classLoader, "onTouchEvent", MotionEvent.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
MotionEvent event = (MotionEvent) param.args[0];
if (getBooleanField(mNotificationPanelViewController, "mSplitShadeEnabled") &&
(boolean) callMethod(mNotificationPanelViewController, "touchXOutsideOfQs", event.getX()))
return;
ViewGroup view = (ViewGroup) getObjectField(mNotificationPanelViewController, "mView");
int state = (int) getObjectField(mNotificationPanelViewController, "mBarState");
int height = getIntField(mNotificationPanelViewController, "mStatusBarMinHeight");
boolean tracking = getBooleanField(param.thisObject, "mTrackingHeadsUp");

float w = view.getMeasuredWidth();
float x = event.getX();
float y = event.getY(event.getActionIndex());

if (x > 3.f * w / 4.f && state == 0 && !tracking && y < height) {
setBooleanField(mNotificationPanelViewController, "mQsExpandImmediate", true);
callMethod(mNotificationPanelViewController, "setShowShelfOnly", true);
String update = securityPatch.after(december) ? "updateExpandedHeightToMaxHeight" : "requestPanelHeightUpdate";
callMethod(mNotificationPanelViewController, update);
callMethod(mNotificationPanelViewController, "setListening", true);
}
}
});
} else {
findAndHookMethod("com.android.systemui.statusbar.phone.NotificationPanelViewController", param.classLoader, "isOpenQsEvent", MotionEvent.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
if ((boolean) param.getResult() == false) {
MotionEvent event = (MotionEvent) param.args[0];
ViewGroup view = (ViewGroup) getObjectField(param.thisObject, "mView");
int state = (int) getObjectField(param.thisObject, "mBarState");
float w = view.getMeasuredWidth();
float x = event.getX();

param.setResult(x > 3.f * w / 4.f && state == 0);
}
}
});
}
if ((pref.getBoolean(FeatureNames.TRICK_DOUBLE_TAP_STATUSBAR, false) || (pref.getBoolean(FeatureNames.TRICK_DOUBLE_TAP_LOCKSCREEN, false))) ) {
Feature feature = FeatureFactory.createFeature(FeatureNames.TRICK_DOUBLE_TAP_STATUSBAR);
if (feature != null) {
feature.inject(param, pref, utils);
}
}

if (pref.getBoolean("trick_doubleTapStatusBar", false) || pref.getBoolean("trick_doubleTapLockScreen", false)) {
String touchHandler = securityPatch.after(december) ? "com.android.systemui.shade.PanelViewController$TouchHandler" : "com.android.systemui.statusbar.phone.PanelViewController$TouchHandler";
findAndHookMethod(touchHandler, param.classLoader, "onTouch", View.class, MotionEvent.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
String notificationPanelView = securityPatch.after(december) ? "com.android.systemui.shade.NotificationPanelView" : "com.android.systemui.statusbar.phone.NotificationPanelView";
if (param.args[0].getClass().getName().equals(notificationPanelView)
&& mNotificationPanelViewController != null && mDoubleTapGesture != null) {
MotionEvent event = (MotionEvent) param.args[1];
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("trick_doubleTapLockScreen", false))
|| (isStatusBar && pref.getBoolean("trick_doubleTapStatusBar", false)))
mDoubleTapGesture.onTouchEvent(event);
}
}
});

if (pref.getBoolean("trick_doubleTapLockScreen", false)) {
findAndHookMethod("com.android.systemui.statusbar.DragDownHelper", param.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();
}
}
});
}

if (pref.getBoolean("trick_doubleTapStatusBar", false) && Build.VERSION.SDK_INT < 33) {
findAndHookMethod("com.android.systemui.statusbar.phone.PanelViewController", param.classLoader, "startOpening", MotionEvent.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
param.setResult(null);
}
});
}
if (pref.getBoolean(FeatureNames.TRICK_QUICK_PULLDOWN, true)) {
Feature feature = FeatureFactory.createFeature(FeatureNames.TRICK_QUICK_PULLDOWN);
if (feature != null) {
feature.inject(param, pref, utils);
}
}

Expand Down Expand Up @@ -836,7 +707,7 @@ protected void beforeHookedMethod(MethodHookParam param) {

if (pref.getBoolean("trick_skipTrack", true) || pref.getBoolean("trick_powerTorch", false)) {
if (Build.VERSION.SDK_INT >= 33) {
String init = securityPatch.after(december) ? "initKeyCombinationRules" : "init";
String init = utils.isSecurityPatchAfterDecember2022() ? "initKeyCombinationRules" : "init";
findAndHookMethod("com.android.server.policy.PhoneWindowManager", param.classLoader, init, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
Expand Down
21 changes: 17 additions & 4 deletions app/src/main/java/com/darkeyes/tricks/SettingsActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

import java.io.File;

import static com.darkeyes.tricks.features.FeatureNames.TRICK_DOUBLE_TAP_LOCKSCREEN;
import static com.darkeyes.tricks.features.FeatureNames.TRICK_DOUBLE_TAP_STATUSBAR;
import static com.darkeyes.tricks.features.FeatureNames.TRICK_QUICK_PULLDOWN;

public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {

private EditTextPreference customCarrierText;
Expand All @@ -42,8 +46,8 @@ protected void onCreate(Bundle savedInstanceState) {
SwitchPreference navbarAlwaysRight = (SwitchPreference) findPreference("trick_navbarAlwaysRight");
SwitchPreference hideBuildVersion = (SwitchPreference) findPreference("trick_hideBuildVersion");
SwitchPreference powerTorch = (SwitchPreference) findPreference("trick_powerTorch");
SwitchPreference doubleTapStatusBar = (SwitchPreference) findPreference("trick_doubleTapStatusBar");
SwitchPreference doubleTapLockScreen = (SwitchPreference) findPreference("trick_doubleTapLockScreen");
SwitchPreference doubleTapStatusBar = (SwitchPreference) findPreference(TRICK_DOUBLE_TAP_STATUSBAR);
SwitchPreference doubleTapLockScreen = (SwitchPreference) findPreference(TRICK_DOUBLE_TAP_LOCKSCREEN);
quickUnlock = (SwitchPreference) findPreference("trick_quickUnlock");
SwitchPreference batteryEstimate = (SwitchPreference) findPreference("trick_batteryEstimate");
customCarrierText = (EditTextPreference) findPreference("trick_customCarrierText");
Expand All @@ -52,6 +56,7 @@ protected void onCreate(Bundle savedInstanceState) {
SwitchPreference smallClock = (SwitchPreference) findPreference("trick_smallClock");
gestureHeight = (ListPreference) findPreference("trick_gestureHeight");
SwitchPreference expandedNotifications = (SwitchPreference) findPreference("trick_expandedNotifications");
SwitchPreference quickPulldown = (SwitchPreference) findPreference(TRICK_QUICK_PULLDOWN);

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
updateSummary();
Expand All @@ -69,9 +74,14 @@ protected void onCreate(Bundle savedInstanceState) {
prefScreen.removePreference(hideBuildVersion);
prefScreen.removePreference(lessNotifications);
}
if (Build.VERSION.SDK_INT < 31) {

if (!FeatureFactory.hasFeature(TRICK_DOUBLE_TAP_STATUSBAR)) {
prefScreen.removePreference(doubleTapStatusBar);
}
if (!FeatureFactory.hasFeature(TRICK_DOUBLE_TAP_LOCKSCREEN)) {
prefScreen.removePreference(doubleTapLockScreen);
}
if (Build.VERSION.SDK_INT < 31) {
prefScreen.removePreference(quickUnlock);
prefScreen.removePreference(batteryEstimate);
prefScreen.removePreference(smallClock);
Expand All @@ -84,6 +94,9 @@ protected void onCreate(Bundle savedInstanceState) {
if (!torchAvailable()) {
prefScreen.removePreference(powerTorch);
}
if (!FeatureFactory.hasFeature(TRICK_QUICK_PULLDOWN)) {
prefScreen.removePreference(quickPulldown);
}
}

@Override
Expand Down Expand Up @@ -189,4 +202,4 @@ private static void setBoolean(Bundle extras) {
sp.edit().putBoolean(preference, value).commit();
}
}
}
}
34 changes: 34 additions & 0 deletions app/src/main/java/com/darkeyes/tricks/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.darkeyes.tricks;

import android.os.Build;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Utils {

private Date securityPatch;
private Date december;

public Utils() {
initDates();
}

private void initDates() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
securityPatch = format.parse(Build.VERSION.SECURITY_PATCH);
december = format.parse("2022-12-01");
} catch (ParseException ignored) {
}
}

public String getComAndroidSystemui_NotificationPanelViewControllerClassName() {
return isSecurityPatchAfterDecember2022() ? "com.android.systemui.shade.NotificationPanelViewController" : "com.android.systemui.statusbar.phone.NotificationPanelViewController";
}

public boolean isSecurityPatchAfterDecember2022() {
return securityPatch.after(december);
}
}
Loading