From b820d90527212a7bf40465b8cbb120caccf4ebb1 Mon Sep 17 00:00:00 2001 From: lisonge Date: Thu, 14 Mar 2024 22:07:57 +0800 Subject: [PATCH] perf: shizuku --- .../kotlin/li/songe/gkd/data/GkdAction.kt | 3 +- .../li/songe/gkd/service/GkdAbService.kt | 27 ++++++++++---- .../kotlin/li/songe/gkd/shizuku/ShizukuApi.kt | 7 ++-- .../main/kotlin/li/songe/gkd/ui/DebugPage.kt | 36 +++++++++++++++---- .../main/kotlin/li/songe/gkd/util/Store.kt | 3 +- 5 files changed, 57 insertions(+), 19 deletions(-) diff --git a/app/src/main/kotlin/li/songe/gkd/data/GkdAction.kt b/app/src/main/kotlin/li/songe/gkd/data/GkdAction.kt index 1ebf8d319..be847b9fc 100644 --- a/app/src/main/kotlin/li/songe/gkd/data/GkdAction.kt +++ b/app/src/main/kotlin/li/songe/gkd/data/GkdAction.kt @@ -21,6 +21,7 @@ data class GkdAction( data class ActionResult( val action: String?, val result: Boolean, + val shizuku: Boolean = false, ) sealed class ActionPerformer(val action: String) { @@ -63,7 +64,7 @@ sealed class ActionPerformer(val action: String) { result = if (0 <= x && 0 <= y && x <= ScreenUtils.getScreenWidth() && y <= ScreenUtils.getScreenHeight()) { val result = shizukuClickFc?.invoke(x, y) if (result != null) { - return ActionResult(action, result) + return ActionResult(action, result, true) } val gestureDescription = GestureDescription.Builder() val path = Path() diff --git a/app/src/main/kotlin/li/songe/gkd/service/GkdAbService.kt b/app/src/main/kotlin/li/songe/gkd/service/GkdAbService.kt index 71f9d428c..2790957b1 100644 --- a/app/src/main/kotlin/li/songe/gkd/service/GkdAbService.kt +++ b/app/src/main/kotlin/li/songe/gkd/service/GkdAbService.kt @@ -75,10 +75,10 @@ class GkdAbService : CompositionAbService({ val shizukuAliveFlow = useShizukuAliveState() val shizukuGrantFlow = MutableStateFlow(false) var lastCheckShizukuTime = 0L - onAccessibilityEvent { // 借助无障碍轮询校验 shizuku 权限 - if (storeFlow.value.enableShizuku && it.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {// 筛选降低判断频率 + onAccessibilityEvent { // 借助无障碍轮询校验 shizuku 权限, 因为 shizuku 可能无故被关闭 + if ((storeFlow.value.enableShizukuActivity || storeFlow.value.enableShizukuClick) && it.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {// 筛选降低判断频率 val t = System.currentTimeMillis() - if (t - lastCheckShizukuTime > 30_000L) { + if (t - lastCheckShizukuTime > 60_000L) { lastCheckShizukuTime = t scope.launchTry(Dispatchers.IO) { shizukuGrantFlow.value = if (shizukuAliveFlow.value) { @@ -90,9 +90,21 @@ class GkdAbService : CompositionAbService({ } } } - val shizukuCanUsedFlow = getShizukuCanUsedFlow(scope, shizukuGrantFlow, shizukuAliveFlow) + val shizukuCanUsedFlow = getShizukuCanUsedFlow( + scope, + shizukuGrantFlow, + shizukuAliveFlow, + storeFlow.map(scope) { s -> s.enableShizukuActivity } + ) val safeGetTasksFc = useSafeGetTasksFc(scope, shizukuCanUsedFlow) - val safeInjectClickEventFc = useSafeInjectClickEventFc(scope, shizukuCanUsedFlow) + + val shizukuClickCanUsedFlow = getShizukuCanUsedFlow( + scope, + shizukuGrantFlow, + shizukuAliveFlow, + storeFlow.map(scope) { s -> s.enableShizukuClick } + ) + val safeInjectClickEventFc = useSafeInjectClickEventFc(scope, shizukuClickCanUsedFlow) injectClickEventFc = safeInjectClickEventFc onDestroy { injectClickEventFc = null @@ -100,7 +112,7 @@ class GkdAbService : CompositionAbService({ // 当锁屏/上拉通知栏时, safeActiveWindow 没有 activityId, 但是此时 shizuku 获取到是前台 app 的 appId 和 activityId fun getShizukuTopActivity(): TopActivity? { - if (!storeFlow.value.enableShizuku) return null + if (!storeFlow.value.enableShizukuActivity) return null // 平均耗时 5 ms val top = safeGetTasksFc()?.lastOrNull()?.topActivity ?: return null return TopActivity(appId = top.packageName, activityId = top.className) @@ -143,6 +155,7 @@ class GkdAbService : CompositionAbService({ val events = mutableListOf() var queryTaskJob: Job? = null fun newQueryTask(byEvent: Boolean = false, byForced: Boolean = false) { + if (!storeFlow.value.enableService) return queryTaskJob = scope.launchTry(queryThread) { var latestEvent = synchronized(events) { val size = events.size @@ -322,7 +335,7 @@ class GkdAbService : CompositionAbService({ ) } } else { - if (storeFlow.value.enableShizuku && fixedEvent.time - lastTriggerShizukuTime > 300) { + if (storeFlow.value.enableShizukuActivity && fixedEvent.time - lastTriggerShizukuTime > 300) { val shizukuTop = getShizukuTopActivity() if (shizukuTop != null && shizukuTop.appId == rightAppId) { if (shizukuTop.activityId == evActivityId) { diff --git a/app/src/main/kotlin/li/songe/gkd/shizuku/ShizukuApi.kt b/app/src/main/kotlin/li/songe/gkd/shizuku/ShizukuApi.kt index 6c68d6b7c..af8fe06ed 100644 --- a/app/src/main/kotlin/li/songe/gkd/shizuku/ShizukuApi.kt +++ b/app/src/main/kotlin/li/songe/gkd/shizuku/ShizukuApi.kt @@ -18,7 +18,6 @@ import kotlinx.coroutines.flow.stateIn import li.songe.gkd.composition.CanOnDestroy import li.songe.gkd.data.DeviceInfo import li.songe.gkd.util.map -import li.songe.gkd.util.storeFlow import li.songe.gkd.util.toast import rikka.shizuku.Shizuku import rikka.shizuku.ShizukuBinderWrapper @@ -111,12 +110,14 @@ fun CanOnDestroy.useShizukuAliveState(): StateFlow { fun getShizukuCanUsedFlow( scope: CoroutineScope, shizukuGrantFlow: StateFlow, - shizukuAliveFlow: StateFlow + shizukuAliveFlow: StateFlow, + shizukuEnableFlow: StateFlow, ): StateFlow { return combine( shizukuAliveFlow, shizukuGrantFlow, - storeFlow.map(scope) { s -> s.enableShizuku }) { shizukuAlive, shizukuGrant, enableShizuku -> + shizukuEnableFlow + ) { shizukuAlive, shizukuGrant, enableShizuku -> enableShizuku && shizukuAlive && shizukuGrant }.stateIn(scope, SharingStarted.Eagerly, false) } diff --git a/app/src/main/kotlin/li/songe/gkd/ui/DebugPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/DebugPage.kt index 388577d8e..94e325324 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/DebugPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/DebugPage.kt @@ -135,27 +135,49 @@ fun DebugPage() { }) HorizontalDivider() } else { - TextSwitch(name = "Shizuku模式", - desc = "高级模式:准确识别界面ID,强制模拟点击", - checked = store.enableShizuku, + TextSwitch(name = "Shizuku-界面识别", + desc = "更准确识别界面ID", + checked = store.enableShizukuActivity, onCheckedChange = { enableShizuku -> if (enableShizuku) { appScope.launchTry(Dispatchers.IO) { // 校验方法是否适配, 再允许使用 shizuku val tasks = newActivityTaskManager()?.safeGetTasks()?.firstOrNull() + if (tasks != null) { + storeFlow.value = store.copy( + enableShizukuActivity = true + ) + } else { + toast("Shizuku-界面识别校验失败,无法使用") + } + } + } else { + storeFlow.value = store.copy( + enableShizukuActivity = false + ) + } + }) + HorizontalDivider() + TextSwitch( + name = "Shizuku-模拟点击", + desc = "变更 clickCenter 为强制模拟点击", + checked = store.enableShizukuClick, + onCheckedChange = { enableShizuku -> + if (enableShizuku) { + appScope.launchTry(Dispatchers.IO) { val result = newInputManager()?.safeClick(0f, 0f) - if (tasks != null && result != null) { + if (result != null) { storeFlow.value = store.copy( - enableShizuku = true + enableShizukuClick = true ) } else { - toast("Shizuku方法校验失败,无法使用") + toast("Shizuku-模拟点击校验失败,无法使用") } } } else { storeFlow.value = store.copy( - enableShizuku = false + enableShizukuClick = false ) } diff --git a/app/src/main/kotlin/li/songe/gkd/util/Store.kt b/app/src/main/kotlin/li/songe/gkd/util/Store.kt index 0b446eb23..fd617bc36 100644 --- a/app/src/main/kotlin/li/songe/gkd/util/Store.kt +++ b/app/src/main/kotlin/li/songe/gkd/util/Store.kt @@ -52,7 +52,8 @@ data class Store( val clickToast: String = "GKD", val autoClearMemorySubs: Boolean = true, val hideSnapshotStatusBar: Boolean = false, - val enableShizuku: Boolean = false, + val enableShizukuActivity: Boolean = false, + val enableShizukuClick: Boolean = false, val log2FileSwitch: Boolean = true, val enableDarkTheme: Boolean? = null, val enableAbFloatWindow: Boolean = true,