Skip to content

Commit

Permalink
perf: shizuku
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Mar 14, 2024
1 parent 9aa2382 commit b820d90
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 19 deletions.
3 changes: 2 additions & 1 deletion app/src/main/kotlin/li/songe/gkd/data/GkdAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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()
Expand Down
27 changes: 20 additions & 7 deletions app/src/main/kotlin/li/songe/gkd/service/GkdAbService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -90,17 +90,29 @@ 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
}

// 当锁屏/上拉通知栏时, 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)
Expand Down Expand Up @@ -143,6 +155,7 @@ class GkdAbService : CompositionAbService({
val events = mutableListOf<AccessibilityNodeInfo>()
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
Expand Down Expand Up @@ -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) {
Expand Down
7 changes: 4 additions & 3 deletions app/src/main/kotlin/li/songe/gkd/shizuku/ShizukuApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -111,12 +110,14 @@ fun CanOnDestroy.useShizukuAliveState(): StateFlow<Boolean> {
fun getShizukuCanUsedFlow(
scope: CoroutineScope,
shizukuGrantFlow: StateFlow<Boolean>,
shizukuAliveFlow: StateFlow<Boolean>
shizukuAliveFlow: StateFlow<Boolean>,
shizukuEnableFlow: StateFlow<Boolean>,
): StateFlow<Boolean> {
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)
}
Expand Down
36 changes: 29 additions & 7 deletions app/src/main/kotlin/li/songe/gkd/ui/DebugPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
}

Expand Down
3 changes: 2 additions & 1 deletion app/src/main/kotlin/li/songe/gkd/util/Store.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit b820d90

Please sign in to comment.