Reduce per-process hook overhead for resource-constrained devices
Every scoped app's cold start pays whatever cost the hook installation itself takes, so it's the one place worth trimming here — there's no standing service or background work anywhere else in the module. Previously any enabled feature caused both Settings.Secure and Settings.Global to get hooked with the full combined key set, even though each key only ever lives on one of them (accessibility/mock-location keys are Secure-only, adb/dev-options keys are Global-only). Splitting the key maps by actual canonical class means an app that only needs e.g. ADB+dev- options hidden skips hooking Settings.Secure entirely, roughly halving the reflective hook-install calls for that case. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,17 +14,34 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam
|
|||||||
|
|
||||||
private const val SELF_PACKAGE = "space.bdeshi.veil"
|
private const val SELF_PACKAGE = "space.bdeshi.veil"
|
||||||
|
|
||||||
private val NULL_STRING_KEYS_BY_FEATURE = mapOf(
|
// Keyed by the Settings class each key actually lives on, so we only ever install hooks on
|
||||||
|
// the one class that could plausibly be asked about a given feature — never both.
|
||||||
|
private val SECURE_NULL_STRING_KEYS_BY_FEATURE = mapOf(
|
||||||
Features.ACCESSIBILITY to setOf("enabled_accessibility_services"),
|
Features.ACCESSIBILITY to setOf("enabled_accessibility_services"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ZERO_VALUE_KEYS_BY_FEATURE = mapOf(
|
private val SECURE_ZERO_VALUE_KEYS_BY_FEATURE = mapOf(
|
||||||
Features.ACCESSIBILITY to setOf("accessibility_enabled", "touch_exploration_enabled"),
|
Features.ACCESSIBILITY to setOf("accessibility_enabled", "touch_exploration_enabled"),
|
||||||
Features.ADB to setOf("adb_enabled", "adb_wifi_enabled"),
|
|
||||||
Features.DEV_OPTIONS to setOf("development_settings_enabled"),
|
|
||||||
Features.MOCK_LOCATION to setOf("mock_location", "allow_mock_location"),
|
Features.MOCK_LOCATION to setOf("mock_location", "allow_mock_location"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val GLOBAL_ZERO_VALUE_KEYS_BY_FEATURE = mapOf(
|
||||||
|
Features.ADB to setOf("adb_enabled", "adb_wifi_enabled"),
|
||||||
|
Features.DEV_OPTIONS to setOf("development_settings_enabled"),
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun keysForEnabledFeatures(
|
||||||
|
enabled: Set<String>,
|
||||||
|
byFeature: Map<String, Set<String>>,
|
||||||
|
): Set<String> {
|
||||||
|
if (enabled.isEmpty() || byFeature.isEmpty()) return emptySet()
|
||||||
|
val result = mutableSetOf<String>()
|
||||||
|
for (feature in enabled) {
|
||||||
|
byFeature[feature]?.let { result.addAll(it) }
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
class VeilHook : IXposedHookLoadPackage {
|
class VeilHook : IXposedHookLoadPackage {
|
||||||
|
|
||||||
override fun handleLoadPackage(lpparam: LoadPackageParam) {
|
override fun handleLoadPackage(lpparam: LoadPackageParam) {
|
||||||
@@ -38,11 +55,15 @@ class VeilHook : IXposedHookLoadPackage {
|
|||||||
hookAccessibilityManager(lpparam)
|
hookAccessibilityManager(lpparam)
|
||||||
}
|
}
|
||||||
|
|
||||||
val nullStringKeys = enabled.flatMap { NULL_STRING_KEYS_BY_FEATURE[it].orEmpty() }.toSet()
|
val secureNullKeys = keysForEnabledFeatures(enabled, SECURE_NULL_STRING_KEYS_BY_FEATURE)
|
||||||
val zeroValueKeys = enabled.flatMap { ZERO_VALUE_KEYS_BY_FEATURE[it].orEmpty() }.toSet()
|
val secureZeroKeys = keysForEnabledFeatures(enabled, SECURE_ZERO_VALUE_KEYS_BY_FEATURE)
|
||||||
if (nullStringKeys.isNotEmpty() || zeroValueKeys.isNotEmpty()) {
|
if (secureNullKeys.isNotEmpty() || secureZeroKeys.isNotEmpty()) {
|
||||||
hookSettingsClass("android.provider.Settings\$Secure", lpparam, nullStringKeys, zeroValueKeys)
|
hookSettingsClass("android.provider.Settings\$Secure", lpparam, secureNullKeys, secureZeroKeys)
|
||||||
hookSettingsClass("android.provider.Settings\$Global", lpparam, nullStringKeys, zeroValueKeys)
|
}
|
||||||
|
|
||||||
|
val globalZeroKeys = keysForEnabledFeatures(enabled, GLOBAL_ZERO_VALUE_KEYS_BY_FEATURE)
|
||||||
|
if (globalZeroKeys.isNotEmpty()) {
|
||||||
|
hookSettingsClass("android.provider.Settings\$Global", lpparam, emptySet(), globalZeroKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Features.ROOT_APPS in enabled) {
|
if (Features.ROOT_APPS in enabled) {
|
||||||
|
|||||||
Reference in New Issue
Block a user