Skip to content

Commit 158772f

Browse files
committed
fix: bugs
1 parent 102c820 commit 158772f

12 files changed

Lines changed: 182 additions & 71 deletions

File tree

library/core/src/main/res/xml/framework_other.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@
8989
android:summary="@string/system_framework_guided_access_tile_more"
9090
android:title="@string/system_framework_guided_access_tile" />
9191

92+
<SwitchPreference
93+
android:defaultValue="false"
94+
android:dependency="prefs_key_system_framework_guided_access"
95+
android:key="prefs_key_system_framework_guided_access_block_dialog"
96+
android:summary="@string/system_framework_guided_access_block_dialog_more"
97+
android:title="@string/system_framework_guided_access_block_dialog" />
98+
9299
<SwitchPreference
93100
android:defaultValue="false"
94101
android:dependency="prefs_key_system_framework_guided_access"

library/libhook/src/main/java/com/sevtinge/hyperceiler/libhook/app/SystemUI/SystemUIB.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.DisableBottomBar;
7171
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.DisableInfinitymodeGesture;
7272
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.DisableMiuiMultiWinSwitch;
73+
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.GuidedAccessDialogBlock;
7374
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.MonetThemeOverlay;
7475
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.NotificationFreeform;
7576
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.RemoveMiuiMultiWinSwitch;
@@ -219,6 +220,9 @@ public void onPackageLoaded() {
219220
initHook(DoubleTapToSleep.INSTANCE, PrefsBridge.getBoolean("system_ui_status_bar_double_tap_to_sleep"));
220221
initHook(new HideStatusBarBeforeScreenshot(), PrefsBridge.getBoolean("system_ui_status_bar_hide_icon"));
221222

223+
initHook(new GuidedAccessDialogBlock(),
224+
PrefsBridge.getBoolean("system_framework_guided_access")
225+
&& PrefsBridge.getBoolean("system_framework_guided_access_block_dialog"));
222226
initHook(new MonetThemeOverlay(), PrefsBridge.getBoolean("system_ui_monet_overlay_custom"));
223227
initHook(new AllowManageAllNotifications(), PrefsBridge.getBoolean("system_framework_allow_manage_all_notifications"));
224228
initHook(new NotificationFreeform(), PrefsBridge.getBoolean("system_ui_notification_freeform"));

library/libhook/src/main/java/com/sevtinge/hyperceiler/libhook/app/SystemUI/SystemUIV.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.DisableInfinitymodeGesture;
9191
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.DisableMiuiMultiWinSwitch;
9292
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.FuckStatusbarGestures;
93+
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.GuidedAccessDialogBlock;
9394
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.MonetThemeOverlay;
9495
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.NotificationFreeform;
9596
import com.sevtinge.hyperceiler.libhook.rules.systemui.other.RemoveMiuiMultiWinSwitch;
@@ -267,6 +268,9 @@ public void onPackageLoaded() {
267268
initHook(DoubleTapToSleep.INSTANCE, PrefsBridge.getBoolean("system_ui_status_bar_double_tap_to_sleep"));
268269
initHook(new HideStatusBarBeforeScreenshot(), PrefsBridge.getBoolean("system_ui_status_bar_hide_icon"));
269270

271+
initHook(new GuidedAccessDialogBlock(),
272+
PrefsBridge.getBoolean("system_framework_guided_access")
273+
&& PrefsBridge.getBoolean("system_framework_guided_access_block_dialog"));
270274
initHook(new UiLockApp(), PrefsBridge.getBoolean("system_framework_guided_access") && PrefsBridge.getBoolean("system_framework_guided_access_status"));
271275
initHook(new AllowManageAllNotifications(), PrefsBridge.getBoolean("system_framework_allow_manage_all_notifications"));
272276
initHook(new MonetThemeOverlay(), PrefsBridge.getBoolean("system_ui_monet_overlay_custom"));

library/libhook/src/main/java/com/sevtinge/hyperceiler/libhook/rules/home/recent/GuidedAccessHome.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import android.view.MotionEvent;
2424
import android.view.View;
2525

26+
import androidx.annotation.NonNull;
27+
2628
import com.sevtinge.hyperceiler.common.log.XposedLog;
2729
import com.sevtinge.hyperceiler.common.utils.PrefsBridge;
2830
import com.sevtinge.hyperceiler.libhook.base.BaseHook;
@@ -45,22 +47,22 @@ public void init() {
4547
private void hookPointerEvent() {
4648
findAndChainMethod("com.miui.home.recents.NavStubView",
4749
"onPointerEvent",
50+
MotionEvent.class,
4851
new XposedInterface.Hooker() {
4952
@Override
50-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
53+
public Object intercept(@NonNull XposedInterface.Chain chain) throws Throwable {
5154
Context context = resolveContext(chain.getThisObject());
5255
if (getLockApp(context) == -1) return chain.proceed();
5356
return false;
5457
}
55-
},
56-
MotionEvent.class
58+
}
5759
);
5860
}
5961

6062
private void hookIsMistakeTouch() {
6163
findAndChainMethod("com.miui.home.recents.NavStubView", "isMistakeTouch", new XposedInterface.Hooker() {
6264
@Override
63-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
65+
public Object intercept(@NonNull XposedInterface.Chain chain) throws Throwable {
6466
Context context = resolveContext(chain.getThisObject());
6567
if (getLockApp(context) == -1) return chain.proceed();
6668
return true;
@@ -72,15 +74,15 @@ private void hookScreenPinTouchResolution() {
7274
try {
7375
findAndChainMethod("com.miui.home.recents.NavStubView",
7476
"screenPinTouchResolution",
77+
MotionEvent.class,
7578
new XposedInterface.Hooker() {
7679
@Override
77-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
80+
public Object intercept(@NonNull XposedInterface.Chain chain) throws Throwable {
7881
Context context = resolveContext(chain.getThisObject());
7982
if (getLockApp(context) == -1) return chain.proceed();
8083
return null;
8184
}
82-
},
83-
MotionEvent.class
85+
}
8486
);
8587
} catch (Throwable e) {
8688
// Pad variant may not include this method; keep other hooks alive.
@@ -90,25 +92,26 @@ public Object intercept(XposedInterface.Chain chain) throws Throwable {
9092
private void hookLandscapeOverviewGestureView() {
9193
findAndChainMethod("com.miui.home.recents.views.RecentsContainer",
9294
"showLandscapeOverviewGestureView",
95+
boolean.class,
9396
new XposedInterface.Hooker() {
9497
@Override
95-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
98+
public Object intercept(@NonNull XposedInterface.Chain chain) throws Throwable {
9699
Context context = resolveContext(chain.getThisObject());
97100
if (getLockApp(context) == -1) return chain.proceed();
98101
return null;
99102
}
100-
},
101-
boolean.class
103+
}
102104
);
103105
}
104106

105107
private void hookHomeStartScreenPinningDirectly() {
106108
findAndChainMethod("com.miui.home.recents.SystemUiProxyWrapper",
107109
"startScreenPinning",
110+
int.class,
108111
new XposedInterface.Hooker() {
109112
@Override
110-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
111-
if (!PrefsBridge.getBoolean("system_framework_guided_access", false)) {
113+
public Object intercept(@NonNull XposedInterface.Chain chain) throws Throwable {
114+
if (!PrefsBridge.getBoolean("system_framework_guided_access_block_dialog", false)) {
112115
return chain.proceed();
113116
}
114117
int taskId = (int) chain.getArg(0);
@@ -124,20 +127,23 @@ public Object intercept(XposedInterface.Chain chain) throws Throwable {
124127
return chain.proceed();
125128
}
126129
}
127-
},
128-
int.class
130+
}
129131
);
130132
}
131133

132134
private void hookScreenPinnedHelperStartDirectly() {
133135
findAndChainMethod("com.miui.home.recents.ScreenPinnedHelper",
134136
"startScreenPinning",
137+
int.class,
135138
new XposedInterface.Hooker() {
136139
@Override
137-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
140+
public Object intercept(@NonNull XposedInterface.Chain chain) throws Throwable {
138141
if (!PrefsBridge.getBoolean("system_framework_guided_access", false)) {
139142
return chain.proceed();
140143
}
144+
if (!PrefsBridge.getBoolean("system_framework_guided_access_block_dialog", false)) {
145+
return chain.proceed();
146+
}
141147
int taskId = (int) chain.getArg(0);
142148
if (taskId < 0) return chain.proceed();
143149
try {
@@ -152,8 +158,7 @@ public Object intercept(XposedInterface.Chain chain) throws Throwable {
152158
return chain.proceed();
153159
}
154160
}
155-
},
156-
int.class
161+
}
157162
);
158163
}
159164

library/libhook/src/main/java/com/sevtinge/hyperceiler/libhook/rules/systemui/controlcenter/tiles/GuidedAccessTile.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import androidx.annotation.Nullable;
2929

3030
import com.sevtinge.hyperceiler.common.log.XposedLog;
31+
import com.sevtinge.hyperceiler.common.utils.PrefsBridge;
3132
import com.sevtinge.hyperceiler.libhook.R;
3233
import com.sevtinge.hyperceiler.libhook.appbase.systemui.TileConfig;
3334
import com.sevtinge.hyperceiler.libhook.appbase.systemui.TileContext;
@@ -85,7 +86,11 @@ protected void onTileClick(TileContext ctx) {
8586
ctx.refreshState();
8687
return;
8788
}
88-
startSystemLockTaskMode(targetTaskId);
89+
if (isBlockDialogEnabled()) {
90+
startSystemLockTaskMode(targetTaskId);
91+
} else {
92+
showScreenPinningRequest(context, targetTaskId);
93+
}
8994
ctx.refreshState();
9095
}, ENTER_DELAY_MS);
9196
}
@@ -139,6 +144,20 @@ private void startSystemLockTaskMode(int taskId) {
139144
}
140145
}
141146

147+
private void showScreenPinningRequest(Context context, int taskId) {
148+
try {
149+
Object statusBar = context.getSystemService("statusbar");
150+
if (statusBar != null) {
151+
callMethod(statusBar, "showScreenPinningRequest", taskId);
152+
return;
153+
}
154+
} catch (Throwable e) {
155+
XposedLog.w(TAG, getPackageName(), "GuidedAccessTile showScreenPinningRequest E: " + e);
156+
}
157+
// Fallback keeps tile usable on variants without this hidden API.
158+
startSystemLockTaskMode(taskId);
159+
}
160+
142161
private void stopSystemLockTaskMode() {
143162
try {
144163
Class<?> activityTaskManager = findClassIfExists("android.app.ActivityTaskManager");
@@ -153,6 +172,10 @@ private void stopSystemLockTaskMode() {
153172
}
154173
}
155174

175+
private boolean isBlockDialogEnabled() {
176+
return PrefsBridge.getBoolean("system_framework_guided_access_block_dialog", false);
177+
}
178+
156179
private static int getLockApp(Context context) {
157180
try {
158181
return Settings.Global.getInt(context.getContentResolver(), SETTING_KEY_LOCK_APP);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* This file is part of HyperCeiler.
3+
*
4+
* HyperCeiler is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*
17+
* Copyright (C) 2023-2026 HyperCeiler Contributions
18+
*/
19+
package com.sevtinge.hyperceiler.libhook.rules.systemui.other;
20+
21+
import android.content.Context;
22+
import android.view.View;
23+
24+
import com.sevtinge.hyperceiler.common.log.XposedLog;
25+
import com.sevtinge.hyperceiler.libhook.base.BaseHook;
26+
27+
import io.github.libxposed.api.XposedInterface;
28+
29+
public class GuidedAccessDialogBlock extends BaseHook {
30+
31+
@Override
32+
public void init() {
33+
Class<?> callbacksClass = findClassIfExists(
34+
"com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks");
35+
if (callbacksClass == null) return;
36+
37+
chainAllMethods(callbacksClass, "showScreenPinningRequest", new XposedInterface.Hooker() {
38+
@Override
39+
public Object intercept(XposedInterface.Chain chain) throws Throwable {
40+
int taskId = readIntArg(chain.getArgs().toArray(), 0, -1);
41+
XposedLog.d(TAG, "block showScreenPinningRequest taskId=" + taskId);
42+
startSystemLockTaskModeByTaskId(chain.getThisObject(), taskId);
43+
return null;
44+
}
45+
});
46+
}
47+
48+
private void startSystemLockTaskModeByTaskId(Object callbacks, int taskId) {
49+
if (taskId < 0) return;
50+
Context context = resolveContext(callbacks);
51+
if (context != null && UiLockApp.getLockApp(context) != -1) {
52+
return;
53+
}
54+
try {
55+
Class<?> activityTaskManagerClass = findClassIfExists("android.app.ActivityTaskManager");
56+
if (activityTaskManagerClass == null) return;
57+
Object service = callStaticMethod(activityTaskManagerClass, "getService");
58+
callMethod(service, "startSystemLockTaskMode", taskId);
59+
} catch (Throwable e) {
60+
XposedLog.w(TAG, "startSystemLockTaskMode from dialog block E: " + e);
61+
}
62+
}
63+
64+
private Context resolveContext(Object target) {
65+
if (target instanceof Context) return (Context) target;
66+
if (target instanceof View) return ((View) target).getContext();
67+
if (target == null) return null;
68+
try {
69+
Object context = getObjectField(target, "mContext");
70+
if (context instanceof Context) return (Context) context;
71+
} catch (Throwable ignored) {
72+
}
73+
try {
74+
Object context = getObjectField(target, "context");
75+
if (context instanceof Context) return (Context) context;
76+
} catch (Throwable ignored) {
77+
}
78+
try {
79+
Object outer = getObjectField(target, "this$0");
80+
if (outer != null && outer != target) {
81+
return resolveContext(outer);
82+
}
83+
} catch (Throwable ignored) {
84+
}
85+
return null;
86+
}
87+
88+
private int readIntArg(Object[] args, int index, int defValue) {
89+
if (args == null || index < 0 || index >= args.length) return defValue;
90+
Object value = args[index];
91+
if (value instanceof Integer) return (Integer) value;
92+
if (value instanceof Boolean) return (Boolean) value ? 1 : 0;
93+
return defValue;
94+
}
95+
}

library/libhook/src/main/java/com/sevtinge/hyperceiler/libhook/rules/systemui/other/UiLockApp.java

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ public Object intercept(XposedInterface.Chain chain) throws Throwable {
106106
for (String className : TASKBAR_DELEGATE_CLASS_CANDIDATES) {
107107
hookTaskbarDelegateClass(className);
108108
}
109-
hookScreenPinningDialogBlock();
110109
if (isPad()) {
111110
hookLauncherProxyStopScreenPinning();
112111
}
@@ -259,22 +258,6 @@ private void registerTaskbarDelegate(Object taskbarDelegate) {
259258
}
260259
}
261260

262-
private void hookScreenPinningDialogBlock() {
263-
Class<?> centralSurfacesCallbacksClass = findClassIfExists(
264-
"com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks");
265-
if (centralSurfacesCallbacksClass != null) {
266-
chainAllMethods(centralSurfacesCallbacksClass, "showScreenPinningRequest", new XposedInterface.Hooker() {
267-
@Override
268-
public Object intercept(XposedInterface.Chain chain) throws Throwable {
269-
int taskId = readIntArg(chain.getArgs().toArray(), 0, -1);
270-
XposedLog.d(TAG, "trace CentralSurfaces.showScreenPinningRequest taskId=" + taskId);
271-
startSystemLockTaskModeByTaskId(chain.getThisObject(), taskId);
272-
return null;
273-
}
274-
});
275-
}
276-
}
277-
278261
private void hookLauncherProxyStopScreenPinning() {
279262
Class<?> launcherProxyClass = findClassIfExists("com.android.systemui.recents.LauncherProxyService$1");
280263
if (launcherProxyClass == null) return;
@@ -295,23 +278,6 @@ public Object intercept(XposedInterface.Chain chain) throws Throwable {
295278
});
296279
}
297280

298-
private void startSystemLockTaskModeByTaskId(Object callbacks, int taskId) {
299-
if (taskId < 0) return;
300-
Context context = resolveContext(callbacks);
301-
if (context != null && getLockApp(context) != -1) {
302-
return;
303-
}
304-
try {
305-
Class<?> activityTaskManagerClass = findClassIfExists("android.app.ActivityTaskManager");
306-
if (activityTaskManagerClass == null) return;
307-
Object service = callStaticMethod(activityTaskManagerClass, "getService");
308-
callMethod(service, "startSystemLockTaskMode", taskId);
309-
XposedLog.d(TAG, "trace startSystemLockTaskMode taskId=" + taskId);
310-
} catch (Throwable e) {
311-
XposedLog.w(TAG, "startSystemLockTaskMode from dialog hook E: " + e);
312-
}
313-
}
314-
315281
private void updateStatusBarVisibility(Context context) {
316282
boolean isLocked = getLockApp(context) != -1;
317283
boolean stateChanged = mLastLockedState == null || mLastLockedState != isLocked;
@@ -554,14 +520,6 @@ private Context resolveContext(Object target) {
554520
return null;
555521
}
556522

557-
private int readIntArg(Object[] args, int index, int defValue) {
558-
if (args == null || index < 0 || index >= args.length) return defValue;
559-
Object value = args[index];
560-
if (value instanceof Integer) return (Integer) value;
561-
if (value instanceof Boolean) return (Boolean) value ? 1 : 0;
562-
return defValue;
563-
}
564-
565523
public static int getLockApp(Context context) {
566524
try {
567525
return Settings.Global.getInt(context.getContentResolver(), SETTING_KEY_LOCK_APP);

0 commit comments

Comments
 (0)