Skip to content

Commit 4916b0b

Browse files
committed
perf: adapt ITaskStackListener method (#941)
1 parent da6a8bf commit 4916b0b

File tree

6 files changed

+59
-14
lines changed

6 files changed

+59
-14
lines changed

app/src/main/kotlin/li/songe/gkd/MainViewModel.kt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,3 @@ class MainViewModel : ViewModel() {
172172
}
173173
}
174174
}
175-
176-
//private fun saveObjectClass(clazz: KClass<*>) {
177-
// val declaredFunctionText = clazz.declaredFunctions.map {
178-
// "${it.name}\n(${it.parameters.joinToString { p -> "${p.name}:${p.type}" }}):${it.returnType}"
179-
// }.joinToString("\n\n")
180-
// filesDir.resolve("object_class.txt").writeText(declaredFunctionText)
181-
//}

app/src/main/kotlin/li/songe/gkd/shizuku/ActivityTaskManager.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,13 @@ private val taskListener by lazy {
124124

125125
val activityTaskManagerFlow by lazy<StateFlow<SafeActivityTaskManager?>> {
126126
val stateFlow = MutableStateFlow<SafeActivityTaskManager?>(null)
127-
appScope.launchTry(Dispatchers.IO) {
128-
shizukuActivityUsedFlow.collect {
129-
stateFlow.value?.unregisterTaskStackListener(taskListener)
130-
stateFlow.value = if (it) newActivityTaskManager() else null
131-
stateFlow.value?.registerTaskStackListener(taskListener)
127+
if (TaskListener.unadaptedMethodList.isEmpty()) {
128+
appScope.launchTry(Dispatchers.IO) {
129+
shizukuActivityUsedFlow.collect {
130+
stateFlow.value?.unregisterTaskStackListener(taskListener)
131+
stateFlow.value = if (it) newActivityTaskManager() else null
132+
stateFlow.value?.registerTaskStackListener(taskListener)
133+
}
132134
}
133135
}
134136
stateFlow

app/src/main/kotlin/li/songe/gkd/shizuku/TaskListener.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,26 @@ import android.app.ITaskStackListener
66
import android.content.ComponentName
77
import android.os.IBinder
88
import android.window.TaskSnapshot
9+
import java.lang.reflect.Modifier
10+
import kotlin.reflect.full.declaredFunctions
911

1012
class TaskListener(private val onStackChanged: () -> Unit) : ITaskStackListener.Stub() {
13+
companion object {
14+
// https://github.com/gkd-kit/gkd/issues/941
15+
val unadaptedMethodList by lazy {
16+
val allAdaptedMethodList = TaskListener::class.declaredFunctions
17+
val currentSystemMethodList =
18+
Class.forName("android.app.ITaskStackListener").methods.filter {
19+
it.returnType == Void.TYPE && !it.isDefault && Modifier.isAbstract(it.modifiers) && !Modifier.isStatic(
20+
it.modifiers
21+
)
22+
}
23+
currentSystemMethodList.filterNot { v1 ->
24+
allAdaptedMethodList.any { v2 -> v1.name == v2.name && v1.parameters.size == v2.parameters.size - 1 }
25+
}
26+
}
27+
}
28+
1129
override fun onTaskStackChanged() = onStackChanged()
1230

1331
override fun onActivityPinned(
@@ -137,4 +155,6 @@ class TaskListener(private val onStackChanged: () -> Unit) : ITaskStackListener.
137155
}
138156

139157
override fun onTaskWindowingModeChanged(i: Int) {}
158+
override fun onRecentTaskRemovedForAddTask(taskId: Int) {}
159+
override fun onActivityDismissingDockedTask() {}
140160
}

app/src/main/kotlin/li/songe/gkd/ui/AdvancedPage.kt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import com.blankj.utilcode.util.LogUtils
5656
import com.dylanc.activityresult.launcher.launchForResult
5757
import com.ramcosta.composedestinations.annotation.Destination
5858
import com.ramcosta.composedestinations.annotation.RootGraph
59+
import com.ramcosta.composedestinations.generated.destinations.AboutPageDestination
5960
import com.ramcosta.composedestinations.generated.destinations.ActivityLogPageDestination
6061
import com.ramcosta.composedestinations.generated.destinations.SnapshotPageDestination
6162
import com.ramcosta.composedestinations.utils.toDestinationsNavigator
@@ -70,6 +71,7 @@ import li.songe.gkd.permission.canDrawOverlaysState
7071
import li.songe.gkd.permission.notificationState
7172
import li.songe.gkd.permission.requiredPermission
7273
import li.songe.gkd.permission.shizukuOkState
74+
import li.songe.gkd.shizuku.TaskListener
7375
import li.songe.gkd.shizuku.shizukuCheckActivity
7476
import li.songe.gkd.shizuku.shizukuCheckUserService
7577
import li.songe.gkd.shizuku.shizukuCheckWorkProfile
@@ -125,7 +127,9 @@ fun AdvancedPage() {
125127
value = it.filter { c -> c.isDigit() }.take(5)
126128
},
127129
singleLine = true,
128-
modifier = Modifier.fillMaxWidth().autoFocus(),
130+
modifier = Modifier
131+
.fillMaxWidth()
132+
.autoFocus(),
129133
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
130134
supportingText = {
131135
Text(
@@ -468,6 +472,8 @@ fun AdvancedPage() {
468472

469473
@Composable
470474
private fun ShizukuFragment(enabled: Boolean = true) {
475+
val mainVm = LocalMainViewModel.current
476+
val navController = LocalNavController.current
471477
val shizukuStore by shizukuStoreFlow.collectAsState()
472478
TextSwitch(
473479
title = "界面识别",
@@ -483,6 +489,25 @@ private fun ShizukuFragment(enabled: Boolean = true) {
483489
toast("检测失败,无法使用")
484490
return@launchAsFn
485491
}
492+
if (TaskListener.unadaptedMethodList.isNotEmpty()) {
493+
LogUtils.d(
494+
"TaskListener.unadaptedMethodList",
495+
*TaskListener.unadaptedMethodList.map {
496+
"${it.name}(${it.parameters.joinToString { p -> "${p.name}:${p.type}" }}):${it.returnType}"
497+
}.toTypedArray()
498+
)
499+
mainVm.dialogFlow.updateDialogOptions(
500+
onDismissRequest = {},
501+
title = "适配提示",
502+
text = "检测到未适配的 API, 已自动禁用部分功能, 请带上日志反馈",
503+
dismissText = "取消",
504+
confirmText = "去反馈",
505+
confirmAction = {
506+
mainVm.dialogFlow.value = null
507+
navController.toDestinationsNavigator().navigate(AboutPageDestination)
508+
}
509+
)
510+
}
486511
toast("已启用")
487512
}
488513
shizukuStoreFlow.update { s -> s.copy(enableActivity = it) }

app/src/main/kotlin/li/songe/gkd/ui/component/DialogOptions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fun MutableStateFlow<AlertDialogOptions?>.updateDialogOptions(
9494
confirmText = confirmText,
9595
confirmAction = confirmAction ?: { value = null },
9696
dismissText = dismissText,
97-
dismissAction = dismissAction,
97+
dismissAction = dismissAction ?: { value = null },
9898
onDismissRequest = onDismissRequest,
9999
error = error,
100100
)

hidden_api/src/main/java/android/app/ITaskStackListener.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,4 +282,9 @@ void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean home
282282

283283
void onTaskWindowingModeChanged(int taskId);
284284

285+
// https://github.com/gkd-kit/gkd/issues/943
286+
void onRecentTaskRemovedForAddTask(int taskId);
287+
288+
void onActivityDismissingDockedTask();
289+
285290
}

0 commit comments

Comments
 (0)