mirror of
https://github.com/gkd-kit/gkd.git
synced 2026-06-03 21:01:49 +08:00
perf: blockA11yAppList topAppId
This commit is contained in:
parent
836f29933c
commit
33b1cfef06
@ -8,6 +8,7 @@ import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.provider.Settings
|
||||
import android.view.WindowManager
|
||||
@ -23,6 +24,7 @@ import li.songe.gkd.service.initA11yWhiteAppList
|
||||
import li.songe.gkd.shizuku.initShizuku
|
||||
import li.songe.gkd.store.initStore
|
||||
import li.songe.gkd.util.AndroidTarget
|
||||
import li.songe.gkd.util.PKG_FLAGS
|
||||
import li.songe.gkd.util.SafeR
|
||||
import li.songe.gkd.util.initAppState
|
||||
import li.songe.gkd.util.initSubsState
|
||||
@ -111,6 +113,12 @@ class App : Application() {
|
||||
return intent.resolveActivity(packageManager)?.packageName
|
||||
}
|
||||
|
||||
fun getPkgInfo(appId: String): PackageInfo? = try {
|
||||
packageManager.getPackageInfo(appId, PKG_FLAGS)
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
|
||||
fun resolveAppId(action: String, category: String? = null): String? {
|
||||
val intent = Intent(action)
|
||||
if (category != null) {
|
||||
|
||||
@ -192,7 +192,9 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
watchKeyboardVisible()
|
||||
StatusService.autoStart()
|
||||
topAppIdFlow.value = META.appId
|
||||
if (storeFlow.value.enableBlockA11yAppList) {
|
||||
topAppIdFlow.value = META.appId
|
||||
}
|
||||
setContent {
|
||||
val latestInsets = TopAppBarDefaults.windowInsets
|
||||
val density = LocalDensity.current
|
||||
|
||||
@ -20,15 +20,19 @@ import li.songe.gkd.data.AttrInfo
|
||||
import li.songe.gkd.data.ResetMatchType
|
||||
import li.songe.gkd.data.ResolvedRule
|
||||
import li.songe.gkd.data.RuleStatus
|
||||
import li.songe.gkd.data.isSystem
|
||||
import li.songe.gkd.db.DbSet
|
||||
import li.songe.gkd.shizuku.safeInvokeMethod
|
||||
import li.songe.gkd.store.actionCountFlow
|
||||
import li.songe.gkd.store.blockA11yAppListFlow
|
||||
import li.songe.gkd.store.blockMatchAppListFlow
|
||||
import li.songe.gkd.store.storeFlow
|
||||
import li.songe.gkd.util.AndroidTarget
|
||||
import li.songe.gkd.util.PKG_FLAGS
|
||||
import li.songe.gkd.util.RuleSummary
|
||||
import li.songe.gkd.util.launchTry
|
||||
import li.songe.gkd.util.ruleSummaryFlow
|
||||
import li.songe.gkd.util.systemUiAppId
|
||||
|
||||
data class TopActivity(
|
||||
val appId: String = "",
|
||||
@ -52,6 +56,10 @@ data class TopActivity(
|
||||
fun sameAs(a: String, b: String?): Boolean {
|
||||
return appId == a && activityId == b
|
||||
}
|
||||
|
||||
fun sameAs(cn: ComponentName): Boolean {
|
||||
return appId == cn.packageName && activityId == cn.className
|
||||
}
|
||||
}
|
||||
|
||||
val topActivityFlow = MutableStateFlow(TopActivity())
|
||||
@ -242,11 +250,32 @@ var appChangeTime = 0L
|
||||
|
||||
var imeAppId = ""
|
||||
var launcherAppId = ""
|
||||
var systemRecentCn = ComponentName("", "")
|
||||
|
||||
fun updateSystemDefaultAppId() {
|
||||
launcherAppId = app.resolveAppId(Intent.ACTION_MAIN, Intent.CATEGORY_HOME) ?: ""
|
||||
imeAppId = app.getSecureString(Settings.Secure.DEFAULT_INPUT_METHOD)
|
||||
?.let(ComponentName::unflattenFromString)?.packageName ?: ""
|
||||
val launcherCn = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
|
||||
.resolveActivity(app.packageManager)
|
||||
launcherAppId = launcherCn.packageName
|
||||
if (app.getPkgInfo(launcherAppId)?.applicationInfo?.isSystem == true) {
|
||||
systemRecentCn = launcherCn
|
||||
} else {
|
||||
safeInvokeMethod {
|
||||
if (AndroidTarget.P) {
|
||||
systemRecentCn = ComponentName.unflattenFromString(
|
||||
app.getString(com.android.internal.R.string.config_recentsComponentName)
|
||||
) ?: systemRecentCn
|
||||
}
|
||||
}
|
||||
if (systemRecentCn.packageName.isEmpty()) {
|
||||
// https://github.com/android-cs/8/blob/main/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
|
||||
systemRecentCn = ComponentName(
|
||||
systemUiAppId,
|
||||
"$systemUiAppId.recents.RecentsActivity",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val actionLogMutex = Mutex()
|
||||
|
||||
@ -55,6 +55,9 @@ private val PackageInfo.isOverlay: Boolean
|
||||
false
|
||||
}
|
||||
|
||||
val ApplicationInfo.isSystem: Boolean
|
||||
get() = flags and ApplicationInfo.FLAG_SYSTEM != 0
|
||||
|
||||
fun PackageInfo.toAppInfo(
|
||||
userId: Int = currentUserId,
|
||||
) = AppInfo(
|
||||
@ -63,7 +66,7 @@ fun PackageInfo.toAppInfo(
|
||||
versionCode = compatVersionCode,
|
||||
versionName = versionName,
|
||||
mtime = lastUpdateTime,
|
||||
isSystem = applicationInfo?.let { it.flags and ApplicationInfo.FLAG_SYSTEM != 0 } ?: false,
|
||||
isSystem = applicationInfo?.isSystem ?: false,
|
||||
name = applicationInfo?.run { loadLabel(app.packageManager).toString() } ?: packageName,
|
||||
hidden = activities?.isEmpty() != false || isOverlay,
|
||||
enabled = applicationInfo?.enabled ?: true,
|
||||
|
||||
@ -10,7 +10,8 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import li.songe.gkd.META
|
||||
import li.songe.gkd.a11y.launcherAppId
|
||||
import li.songe.gkd.a11y.systemRecentCn
|
||||
import li.songe.gkd.a11y.topActivityFlow
|
||||
import li.songe.gkd.a11y.topAppIdFlow
|
||||
import li.songe.gkd.accessRestrictedSettingsShowFlow
|
||||
import li.songe.gkd.app
|
||||
@ -22,7 +23,6 @@ import li.songe.gkd.store.blockA11yAppListFlow
|
||||
import li.songe.gkd.store.storeFlow
|
||||
import li.songe.gkd.util.launchTry
|
||||
import li.songe.gkd.util.mapState
|
||||
import li.songe.gkd.util.systemUiAppId
|
||||
import li.songe.gkd.util.toast
|
||||
|
||||
class GkdTileService : BaseTileService() {
|
||||
@ -141,15 +141,13 @@ val a11yPartDisabledFlow by lazy {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun initA11yWhiteAppList() {
|
||||
val actualFlow = a11yPartDisabledFlow.drop(1)
|
||||
val actualFlow = topAppIdFlow.drop(1)
|
||||
appScope.launch(Dispatchers.Main) {
|
||||
actualFlow.collect { disabled ->
|
||||
if (!disabled) {
|
||||
val appId = topAppIdFlow.value
|
||||
if (appId == launcherAppId || appId == systemUiAppId) {
|
||||
// 检测最近任务界面,开启或关闭无障碍会造成卡顿
|
||||
actualFlow.collect { appId ->
|
||||
if (!blockA11yAppListFlow.value.contains(appId)) {
|
||||
if (topActivityFlow.value.sameAs(systemRecentCn)) {
|
||||
// 切换无障碍会造成卡顿,在最近任务界面时,延迟这个卡顿
|
||||
appScope.launch {
|
||||
delay(A11Y_WHITE_APP_AWAIT_TIME)
|
||||
if (appId == topAppIdFlow.value) {
|
||||
@ -163,8 +161,8 @@ fun initA11yWhiteAppList() {
|
||||
}
|
||||
}
|
||||
appScope.launch(Dispatchers.Main) {
|
||||
actualFlow.debounce(A11Y_WHITE_APP_AWAIT_TIME).collect { disabled ->
|
||||
if (disabled) {
|
||||
actualFlow.debounce(A11Y_WHITE_APP_AWAIT_TIME).collect { appId ->
|
||||
if (blockA11yAppListFlow.value.contains(appId)) {
|
||||
forcedUpdateA11yService(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ import rikka.shizuku.Shizuku
|
||||
import rikka.shizuku.ShizukuBinderWrapper
|
||||
import rikka.shizuku.SystemServiceHelper
|
||||
|
||||
// shizuku 会概率断开
|
||||
inline fun <T> safeInvokeMethod(
|
||||
block: () -> T
|
||||
): T? = try {
|
||||
|
||||
@ -4,7 +4,6 @@ import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -99,12 +98,6 @@ private val packageReceiver by lazy {
|
||||
|
||||
const val PKG_FLAGS = PackageManager.MATCH_UNINSTALLED_PACKAGES or PackageManager.GET_ACTIVITIES
|
||||
|
||||
private fun getPkgInfo(appId: String): PackageInfo? = try {
|
||||
app.packageManager.getPackageInfo(appId, PKG_FLAGS)
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
|
||||
val updateAppMutex = MutexState()
|
||||
|
||||
private fun updateOtherUserAppInfo(userAppInfoMap: Map<String, AppInfo>? = null) {
|
||||
@ -146,7 +139,7 @@ private fun updatePartAppInfo(
|
||||
val newAppMap = HashMap(userAppInfoMapFlow.value)
|
||||
val newIconMap = HashMap(userAppIconMapFlow.value)
|
||||
appIds.forEach { appId ->
|
||||
val info = getPkgInfo(appId)
|
||||
val info = app.getPkgInfo(appId)
|
||||
if (info != null) {
|
||||
newAppMap[appId] = info.toAppInfo()
|
||||
} else {
|
||||
@ -184,7 +177,7 @@ fun updateAllAppInfo(
|
||||
)
|
||||
}.flatten()
|
||||
.map { it.activityInfo.packageName }.toSet()
|
||||
.filter { !newAppMap.contains(it) }.mapNotNull { getPkgInfo(it) }
|
||||
.filter { !newAppMap.contains(it) }.mapNotNull { app.getPkgInfo(it) }
|
||||
visiblePkgList.forEach { packageInfo ->
|
||||
newAppMap[packageInfo.packageName] = packageInfo.toAppInfo()
|
||||
packageInfo.pkgIcon?.let { icon ->
|
||||
|
||||
15
hidden_api/src/main/java/com/android/internal/R.java
Normal file
15
hidden_api/src/main/java/com/android/internal/R.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.android.internal;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
/**
|
||||
* @noinspection unused
|
||||
*/
|
||||
public class R {
|
||||
public static final class string {
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public static int config_recentsComponentName;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user