diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 10d3d5c1fd..6830609dd0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -4,7 +4,6 @@ -keep class com.sevtinge.hyperceiler.utils.Helpers{boolean isModuleActive;} -keep class com.sevtinge.hyperceiler.utils.Helpers{int XposedVersion;} -keep class * extends com.sevtinge.hyperceiler.module.base.BaseHook --keep class * extends com.sevtinge.hyperceiler.utils.hook.HookUtils -keep class com.sevtinge.hyperceiler.ui.HideAppActivity -keep class * extends com.sevtinge.hyperceiler.ui.fragment.base.* -keep class miui.drm.**{*;} diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java b/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java index f08b4f5dec..1127bfab06 100644 --- a/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java +++ b/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java @@ -45,6 +45,7 @@ import com.sevtinge.hyperceiler.module.hook.home.folder.SmallFolderIconBlur; import com.sevtinge.hyperceiler.module.hook.home.gesture.DoubleTap; import com.sevtinge.hyperceiler.module.hook.home.gesture.HotSeatSwipe; +import com.sevtinge.hyperceiler.module.hook.home.gesture.QuickBack; import com.sevtinge.hyperceiler.module.hook.home.gesture.ShakeDevice; import com.sevtinge.hyperceiler.module.hook.home.layout.HotSeatsHeight; import com.sevtinge.hyperceiler.module.hook.home.layout.HotSeatsMarginBottom; @@ -116,6 +117,7 @@ public void handleLoadPackage() { initHook(LoadHostDir.INSTANCE); // 手势 + initHook(new QuickBack(), mPrefsMap.getBoolean("home_navigation_quick_back")); initHook(new DoubleTap(), mPrefsMap.getInt("home_gesture_double_tap_action", 0) > 0); initHook(new ScreenSwipe(), mPrefsMap.getInt("home_gesture_up_swipe_action", 0) > 0 || mPrefsMap.getInt("home_gesture_down_swipe_action", 0) > 0 || diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/hook/home/gesture/QuickBack.java b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/home/gesture/QuickBack.java new file mode 100644 index 0000000000..74e4fdac8c --- /dev/null +++ b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/home/gesture/QuickBack.java @@ -0,0 +1,116 @@ +package com.sevtinge.hyperceiler.module.hook.home.gesture; + +import android.app.ActivityManager; +import android.app.ActivityOptions; +import android.content.Context; + +import com.sevtinge.hyperceiler.module.base.BaseHook; + +import java.util.ArrayList; + +import de.robv.android.xposed.XposedHelpers; + +public class QuickBack extends BaseHook { + @Override + public void init() { + findAndHookMethod("com.miui.home.recents.GestureStubView", + "isDisableQuickSwitch", new MethodHook() { + @Override + protected void before(MethodHookParam param) { + param.setResult(false); + } + } + ); + + findAndHookMethod("com.miui.home.recents.GestureStubView", + "getNextTask", Context.class, boolean.class, int.class, + new MethodHook() { + @Override + protected void before(MethodHookParam param) { + Context context = (Context) param.args[0]; + ActivityManager.RunningTaskInfo runningTask; + Object recentsModel = XposedHelpers.callStaticMethod(findClass("com.miui.home.recents.RecentsModel"), "getInstance", context); + Object taskLoader = XposedHelpers.callMethod(recentsModel, "getTaskLoader"); + Object createLoadPlan = XposedHelpers.callMethod(taskLoader, "createLoadPlan", context); + XposedHelpers.callMethod(taskLoader, "preloadTasks", createLoadPlan, -1); + Object taskStack = XposedHelpers.callMethod(createLoadPlan, "getTaskStack"); + ActivityOptions activityOptions = null; + if (taskStack == null || (int) XposedHelpers.callMethod(taskStack, "getTaskCount") == 0 || (runningTask = (ActivityManager.RunningTaskInfo) XposedHelpers.callMethod(recentsModel, "getRunningTask")) == null) { + param.setResult(null); + return; + } + ArrayList stackTasks = (ArrayList) XposedHelpers.callMethod(taskStack, "getStackTasks"); + int size = stackTasks.size(); + Object task = null; + int i2 = 0; + while (true) { + if (i2 >= size - 1) { + break; + } else if ((int) XposedHelpers.getObjectField(XposedHelpers.getObjectField(stackTasks.get(i2), "key"), "id") == runningTask.id) { + task = stackTasks.get(i2 + 1); + break; + } else { + i2++; + } + } + if (task == null && size >= 1 && "com.miui.home".equals(runningTask.baseActivity.getPackageName())) { + task = stackTasks.get(0); + } + if (task != null && XposedHelpers.getObjectField(task, "icon") == null) { + XposedHelpers.setObjectField(task, "icon", XposedHelpers.callMethod(taskLoader, "getAndUpdateActivityIcon", + XposedHelpers.getObjectField(task, "key"), + XposedHelpers.getObjectField(task, "taskDescription"), + context.getResources(), true + )); + } + if (!(boolean) param.args[1] || task == null) { + param.setResult(task); + return; + } + int i = (int) param.args[2]; + if (i == 0) { + activityOptions = ActivityOptions.makeCustomAnimation(context, + (int) XposedHelpers.callStaticMethod( + findClass("com.miui.home.recents.GestureStubView"), + "getAnimId", context, "recents_quick_switch_left_enter"), + (int) XposedHelpers.callStaticMethod( + findClass("com.miui.home.recents.GestureStubView"), + "getAnimId", context, "recents_quick_switch_left_exit")); + } else if (i == 1) { + activityOptions = ActivityOptions.makeCustomAnimation(context, + (int) XposedHelpers.callStaticMethod( + findClass("com.miui.home.recents.GestureStubView"), + "getAnimId", context, "recents_quick_switch_right_enter"), + (int) XposedHelpers.callStaticMethod( + findClass("com.miui.home.recents.GestureStubView"), + "getAnimId", context, "recents_quick_switch_right_exit")); + } + Object iActivityManager = XposedHelpers.callStaticMethod(findClass("android.app.ActivityManagerNative"), "getDefault"); + if (iActivityManager != null) { + try { + if ((int) XposedHelpers.getObjectField(XposedHelpers.getObjectField(task, "key"), "windowingMode") == 3) { + if (activityOptions == null) { + activityOptions = ActivityOptions.makeBasic(); + } + activityOptions.getClass().getMethod("setLaunchWindowingMode", Integer.class).invoke(activityOptions, 4); + } + XposedHelpers.callMethod(iActivityManager, "startActivityFromRecents", + XposedHelpers.getObjectField( + XposedHelpers.getObjectField(task, "key"), + "id"), + activityOptions == null ? null : activityOptions.toBundle()); + param.setResult(task); + return; + } catch (Exception e) { + logE(TAG, "Error :" + e); + param.setResult(task); + return; + } + } + param.setResult(task); + } + } + ); + + } +} diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c40a7e0d8b..bc2dbb401d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -806,6 +806,8 @@ 系统桌面 手势与导航 导航 + 切换上一个应用 + 从屏幕两侧向内滑动并停顿,快速切换上一个应用 返回手势区域高度 返回手势区域宽度 手势 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3d9f2b524e..e4b6e65bed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -790,6 +790,8 @@ System launcher Gesture and Navigation Navigation + Go back to previous app + Swipe across the screen starting from the edge to go back to previous app Back gesture area height Back gesture area width Gesture diff --git a/app/src/main/res/xml/home_gesture.xml b/app/src/main/res/xml/home_gesture.xml index 2646decbca..bb9ae27134 100644 --- a/app/src/main/res/xml/home_gesture.xml +++ b/app/src/main/res/xml/home_gesture.xml @@ -2,78 +2,84 @@ + + + app:maxValue="100" + app:minValue="10" + app:showSeekBarValue="true" + app:stepValue="5" /> + app:maxValue="400" + app:minValue="100" + app:showSeekBarValue="true" + app:stepValue="5" /> + android:title="@string/home_gesture_double_tap" /> + android:title="@string/home_gesture_shake" /> + android:title="@string/home_gesture_left_swipe" /> + android:title="@string/home_gesture_right_swipe" /> + android:title="@string/home_gesture_up_swipe" /> + android:title="@string/home_gesture_down_swipe" /> + android:title="@string/home_gesture_up_swipe2" /> + android:title="@string/home_gesture_down_swipe2" />