Skip to content

Commit f1bf7bd

Browse files
authored
Merge pull request #18 from sameerasw/develop
Screen locked security, Improved permission flow, Fix widget haptics
2 parents 6bab804 + 08bcf9a commit f1bf7bd

File tree

11 files changed

+466
-22
lines changed

11 files changed

+466
-22
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
applicationId = "com.sameerasw.essentials"
1515
minSdk = 23
1616
targetSdk = 36
17-
versionCode = 9
18-
versionName = "7.0"
17+
versionCode = 10
18+
versionName = "7.1"
1919

2020
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2121
}

app/src/main/AndroidManifest.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,18 @@
229229
android:enabled="true"
230230
android:exported="true"
231231
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
232+
233+
<receiver
234+
android:name=".services.receivers.SecurityDeviceAdminReceiver"
235+
android:permission="android.permission.BIND_DEVICE_ADMIN"
236+
android:exported="true">
237+
<meta-data
238+
android:name="android.app.device_admin"
239+
android:resource="@xml/device_admin_rules" />
240+
<intent-filter>
241+
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
242+
</intent-filter>
243+
</receiver>
232244
</application>
233245

234246
</manifest>

app/src/main/java/com/sameerasw/essentials/FeatureSettingsActivity.kt

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.compose.material3.MaterialTheme
2121
import androidx.compose.material3.Scaffold
2222
import androidx.compose.material3.TopAppBarDefaults
2323
import androidx.compose.material3.rememberTopAppBarState
24+
import androidx.compose.runtime.DisposableEffect
2425
import androidx.compose.runtime.LaunchedEffect
2526
import androidx.compose.runtime.getValue
2627
import androidx.compose.runtime.mutableStateOf
@@ -31,6 +32,9 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
3132
import androidx.compose.ui.platform.LocalContext
3233
import androidx.compose.ui.unit.dp
3334
import androidx.core.net.toUri
35+
import androidx.lifecycle.Lifecycle
36+
import androidx.lifecycle.LifecycleEventObserver
37+
import androidx.lifecycle.compose.LocalLifecycleOwner
3438
import com.sameerasw.essentials.ui.components.ReusableTopAppBar
3539
import com.sameerasw.essentials.ui.theme.EssentialsTheme
3640
import com.sameerasw.essentials.utils.HapticFeedbackType
@@ -70,7 +74,8 @@ class FeatureSettingsActivity : ComponentActivity() {
7074
"Snooze system notifications" to "Automatically snooze persistent notifications",
7175
"Quick Settings Tiles" to "All available QS tiles",
7276
"Pixel IMS" to "Force enable IMS for Pixels",
73-
"Button remap" to "Remap hardware buttons"
77+
"Button remap" to "Remap hardware buttons",
78+
"Screen locked security" to "Protect network settings from lock screen"
7479
)
7580
val description = featureDescriptions[feature] ?: ""
7681
setContent {
@@ -86,6 +91,29 @@ class FeatureSettingsActivity : ComponentActivity() {
8691
}
8792

8893
val viewModel: MainViewModel = viewModel()
94+
val statusBarViewModel: StatusBarIconViewModel = viewModel()
95+
val caffeinateViewModel: CaffeinateViewModel = viewModel()
96+
97+
// Automatic refresh on resume
98+
val lifecycleOwner = LocalLifecycleOwner.current
99+
DisposableEffect(lifecycleOwner) {
100+
val observer = LifecycleEventObserver { _, event ->
101+
if (event == Lifecycle.Event.ON_RESUME) {
102+
viewModel.check(context)
103+
if (feature == "Statusbar icons") {
104+
statusBarViewModel.check(context)
105+
}
106+
if (feature == "Caffeinate") {
107+
caffeinateViewModel.check(context)
108+
}
109+
}
110+
}
111+
lifecycleOwner.lifecycle.addObserver(observer)
112+
onDispose {
113+
lifecycleOwner.lifecycle.removeObserver(observer)
114+
}
115+
}
116+
89117
LaunchedEffect(Unit) {
90118
viewModel.check(context)
91119
}
@@ -118,6 +146,7 @@ class FeatureSettingsActivity : ComponentActivity() {
118146
"Button remap" -> !isAccessibilityEnabled
119147
"Dynamic night light" -> !isAccessibilityEnabled || !isWriteSecureSettingsEnabled
120148
"Snooze system notifications" -> !isNotificationListenerEnabled
149+
"Screen locked security" -> !isAccessibilityEnabled || !isWriteSecureSettingsEnabled || !viewModel.isDeviceAdminEnabled.value
121150
else -> false
122151
}
123152
showPermissionSheet = hasMissingPermissions
@@ -252,6 +281,44 @@ class FeatureSettingsActivity : ComponentActivity() {
252281
isGranted = isNotificationListenerEnabled
253282
)
254283
)
284+
"Screen locked security" -> listOf(
285+
PermissionItem(
286+
iconRes = R.drawable.rounded_settings_accessibility_24,
287+
title = "Accessibility Service",
288+
description = "Required to detect lock screen interactions and dismiss panel",
289+
dependentFeatures = PermissionRegistry.getFeatures("ACCESSIBILITY"),
290+
actionLabel = "Enable in Settings",
291+
action = {
292+
context.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
293+
},
294+
isGranted = isAccessibilityEnabled
295+
),
296+
PermissionItem(
297+
iconRes = R.drawable.rounded_security_24,
298+
title = "Write Secure Settings",
299+
description = "Required to temporarily adjust animation scale for spam prevention",
300+
dependentFeatures = PermissionRegistry.getFeatures("WRITE_SECURE_SETTINGS"),
301+
actionLabel = "Copy ADB",
302+
action = {
303+
val adbCommand = "adb shell pm grant com.sameerasw.essentials android.permission.WRITE_SECURE_SETTINGS"
304+
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
305+
val clip = ClipData.newPlainText("adb_command", adbCommand)
306+
clipboard.setPrimaryClip(clip)
307+
},
308+
isGranted = isWriteSecureSettingsEnabled
309+
),
310+
PermissionItem(
311+
iconRes = R.drawable.rounded_security_24,
312+
title = "Device Administrator",
313+
description = "Required to hard-lock the device (disabling biometrics) on unauthorized access attempts",
314+
dependentFeatures = PermissionRegistry.getFeatures("DEVICE_ADMIN"),
315+
actionLabel = "Enable Admin",
316+
action = {
317+
viewModel.requestDeviceAdmin(context)
318+
},
319+
isGranted = viewModel.isDeviceAdminEnabled.value
320+
)
321+
)
255322
else -> emptyList()
256323
}
257324

@@ -298,20 +365,12 @@ class FeatureSettingsActivity : ComponentActivity() {
298365
)
299366
}
300367
"Statusbar icons" -> {
301-
val statusBarViewModel: StatusBarIconViewModel = viewModel()
302-
LaunchedEffect(Unit) {
303-
statusBarViewModel.check(context)
304-
}
305368
StatusBarIconSettingsUI(
306369
viewModel = statusBarViewModel,
307370
modifier = Modifier.padding(top = 16.dp)
308371
)
309372
}
310373
"Caffeinate" -> {
311-
val caffeinateViewModel: CaffeinateViewModel = viewModel()
312-
LaunchedEffect(Unit) {
313-
caffeinateViewModel.check(context)
314-
}
315374
CaffeinateSettingsUI(
316375
viewModel = caffeinateViewModel,
317376
modifier = Modifier.padding(top = 16.dp)
@@ -341,6 +400,12 @@ class FeatureSettingsActivity : ComponentActivity() {
341400
modifier = Modifier.padding(top = 16.dp)
342401
)
343402
}
403+
"Screen locked security" -> {
404+
com.sameerasw.essentials.ui.composables.configs.ScreenLockedSecuritySettingsUI(
405+
viewModel = viewModel,
406+
modifier = Modifier.padding(top = 16.dp)
407+
)
408+
}
344409
"Quick Settings Tiles" -> {
345410
QuickSettingsTilesSettingsUI(
346411
modifier = Modifier.padding(top = 16.dp)

app/src/main/java/com/sameerasw/essentials/PermissionRegistry.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ fun initPermissionRegistry() {
1818
PermissionRegistry.register("ACCESSIBILITY", "Edge lighting")
1919
PermissionRegistry.register("ACCESSIBILITY", "Flashlight toggle")
2020
PermissionRegistry.register("ACCESSIBILITY", "Dynamic night light")
21+
PermissionRegistry.register("ACCESSIBILITY", "Screen locked security")
2122

2223
// Write secure settings permission
2324
PermissionRegistry.register("WRITE_SECURE_SETTINGS", "Statusbar icons")
2425
PermissionRegistry.register("WRITE_SECURE_SETTINGS", "Sound Mode")
2526
PermissionRegistry.register("WRITE_SECURE_SETTINGS", "Dynamic night light")
27+
PermissionRegistry.register("WRITE_SECURE_SETTINGS", "Screen locked security")
2628

2729
// Shizuku permission
2830
PermissionRegistry.register("SHIZUKU", "Maps power saving mode")
@@ -43,4 +45,7 @@ fun initPermissionRegistry() {
4345

4446
// Default browser permission
4547
PermissionRegistry.register("DEFAULT_BROWSER", "Link picker - open with")
48+
49+
// Device Admin permission
50+
PermissionRegistry.register("DEVICE_ADMIN", "Screen locked security")
4651
}

0 commit comments

Comments
 (0)