From 5167e6ef2834c850148f9051dd825784cb585d41 Mon Sep 17 00:00:00 2001 From: Anirudh Lakhotia Date: Thu, 21 May 2026 20:57:52 +0530 Subject: [PATCH 1/2] fix: catch SecurityException reading hidden settings in ShutUpShortcut show_key_presses and other @hide keys aren't @Readable on Android 12+, so the backup pass in ShutUpShortcutActivity crashes before launchApp runs. WRITE_SECURE_SETTINGS only covers writes, which is why having Shizuku doesn't help. Reads now go through a try/catch helper that returns null on failure. Closes #443 --- .../essentials/ShutUpShortcutActivity.kt | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt b/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt index 93c7d74c1..40cfb6924 100644 --- a/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt +++ b/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt @@ -1,8 +1,10 @@ package com.sameerasw.essentials +import android.content.ContentResolver import android.content.Intent import android.os.Bundle import android.provider.Settings +import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -139,15 +141,15 @@ class ShutUpShortcutActivity : ComponentActivity() { ) secureSettings.forEach { key -> - Settings.Secure.getString(contentResolver, key) + safeReadSetting(contentResolver, SettingsTable.SECURE, key) ?.let { originalSettings["secure:$key"] = it } } systemSettings.forEach { key -> - Settings.System.getString(contentResolver, key) + safeReadSetting(contentResolver, SettingsTable.SYSTEM, key) ?.let { originalSettings["system:$key"] = it } } globalSettings.forEach { key -> - Settings.Global.getString(contentResolver, key) + safeReadSetting(contentResolver, SettingsTable.GLOBAL, key) ?.let { originalSettings["global:$key"] = it } } @@ -163,7 +165,8 @@ class ShutUpShortcutActivity : ComponentActivity() { // as some apps check this specific setting directly. if (config.disableUsbDebugging) { val current = - Settings.Global.getString(contentResolver, Settings.Global.ADB_ENABLED) ?: "0" + safeReadSetting(contentResolver, SettingsTable.GLOBAL, Settings.Global.ADB_ENABLED) + ?: "0" if (current == "1") { if (!originalSettings.containsKey("global:${Settings.Global.ADB_ENABLED}")) { originalSettings["global:${Settings.Global.ADB_ENABLED}"] = "1" @@ -173,7 +176,8 @@ class ShutUpShortcutActivity : ComponentActivity() { } if (config.disableWirelessDebugging) { - val current = Settings.Global.getString(contentResolver, "adb_wifi_enabled") ?: "0" + val current = + safeReadSetting(contentResolver, SettingsTable.GLOBAL, "adb_wifi_enabled") ?: "0" if (current == "1") { if (!originalSettings.containsKey("global:adb_wifi_enabled")) { originalSettings["global:adb_wifi_enabled"] = "1" @@ -183,8 +187,9 @@ class ShutUpShortcutActivity : ComponentActivity() { } if (config.disableAccessibility) { - val current = Settings.Secure.getString( + val current = safeReadSetting( contentResolver, + SettingsTable.SECURE, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES ) if (!current.isNullOrEmpty()) { @@ -204,6 +209,28 @@ class ShutUpShortcutActivity : ComponentActivity() { } } + private enum class SettingsTable { SYSTEM, SECURE, GLOBAL } + + // Android 12+ throws SecurityException reading @hide settings that aren't + // @Readable (e.g. show_key_presses). WRITE_SECURE_SETTINGS doesn't cover reads. + private fun safeReadSetting( + resolver: ContentResolver, + table: SettingsTable, + key: String + ): String? = try { + when (table) { + SettingsTable.SYSTEM -> Settings.System.getString(resolver, key) + SettingsTable.SECURE -> Settings.Secure.getString(resolver, key) + SettingsTable.GLOBAL -> Settings.Global.getString(resolver, key) + } + } catch (e: SecurityException) { + Log.w("ShutUpShortcut", "Skipping unreadable setting $table:$key", e) + null + } catch (e: Exception) { + Log.w("ShutUpShortcut", "Failed to read setting $table:$key", e) + null + } + private fun launchApp(packageName: String) { val intent = packageManager.getLaunchIntentForPackage(packageName) if (intent != null) { From af05a93aa62c408ed4617db95f3f7d2cef1d42c4 Mon Sep 17 00:00:00 2001 From: Anirudh Lakhotia Date: Thu, 21 May 2026 21:40:42 +0530 Subject: [PATCH 2/2] fix: drop generic Exception catch from safeReadSetting SecurityException is the only failure we know how to handle here. Other exceptions are real bugs and shouldn't fail silently. --- .../java/com/sameerasw/essentials/ShutUpShortcutActivity.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt b/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt index 40cfb6924..263bf0fb3 100644 --- a/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt +++ b/app/src/main/java/com/sameerasw/essentials/ShutUpShortcutActivity.kt @@ -226,9 +226,6 @@ class ShutUpShortcutActivity : ComponentActivity() { } catch (e: SecurityException) { Log.w("ShutUpShortcut", "Skipping unreadable setting $table:$key", e) null - } catch (e: Exception) { - Log.w("ShutUpShortcut", "Failed to read setting $table:$key", e) - null } private fun launchApp(packageName: String) {