commit 2b0e4ad09ae0d954f781ba0e00ad5e658f638560
parent b92589fa07c6a6fc496433d0e090bc2375ce8277
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Sat, 14 Oct 2023 15:07:01 +0200
feat(setup/permissions): display over other apps
Diffstat:
3 files changed, 89 insertions(+), 61 deletions(-)
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
@@ -6,5 +6,5 @@
-keep class org.jf.dexlib2.** { *; }
-keep class org.mozilla.javascript.** { *; }
-keep class androidx.compose.material.icons.** { *; }
--keep class androidx.navigation.compose.** { *; }
+-keep class androidx.navigation.** { *; }
-keep class me.rhunk.snapenhance.** { *; }
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/setup/screens/impl/PermissionsScreen.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/setup/screens/impl/PermissionsScreen.kt
@@ -17,7 +17,11 @@ import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.mutableStateMapOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@@ -25,6 +29,12 @@ import kotlinx.coroutines.launch
import me.rhunk.snapenhance.ui.setup.screens.SetupScreen
import me.rhunk.snapenhance.ui.util.ActivityLauncherHelper
+data class PermissionData(
+ val translationKey: String,
+ val isPermissionGranted: () -> Boolean,
+ val requestPermission: (PermissionData) -> Unit,
+)
+
class PermissionsScreen : SetupScreen() {
private lateinit var activityLauncherHelper: ActivityLauncherHelper
@@ -53,27 +63,73 @@ class PermissionsScreen : SetupScreen() {
@SuppressLint("BatteryLife")
@Composable
override fun Content() {
- var notificationPermissionGranted by remember { mutableStateOf(true) }
- var isBatteryOptimisationIgnored by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
-
- if (isBatteryOptimisationIgnored && notificationPermissionGranted) {
- allowNext(true)
- } else {
- allowNext(false)
+ val grantedPermissions = remember {
+ mutableStateMapOf<String, Boolean>()
+ }
+ val permissions = remember {
+ listOf(
+ PermissionData(
+ translationKey = "notification_access",
+ isPermissionGranted = {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ context.androidContext.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
+ } else {
+ true
+ }
+ },
+ requestPermission = { perm ->
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ activityLauncherHelper.requestPermission(Manifest.permission.POST_NOTIFICATIONS) { resultCode, _ ->
+ coroutineScope.launch {
+ grantedPermissions[perm.translationKey] = resultCode == ComponentActivity.RESULT_OK
+ }
+ }
+ }
+ }
+ ),
+ PermissionData(
+ translationKey = "battery_optimization",
+ isPermissionGranted = {
+ val powerManager =
+ context.androidContext.getSystemService(Context.POWER_SERVICE) as PowerManager
+ powerManager.isIgnoringBatteryOptimizations(context.androidContext.packageName)
+ },
+ requestPermission = { perm ->
+ activityLauncherHelper.launch(Intent().apply {
+ action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
+ data = Uri.parse("package:${context.androidContext.packageName}")
+ }) { resultCode, _ ->
+ coroutineScope.launch {
+ grantedPermissions[perm.translationKey] = resultCode == 0
+ }
+ }
+ }
+ ),
+ PermissionData(
+ translationKey = "display_over_other_apps",
+ isPermissionGranted = {
+ Settings.canDrawOverlays(context.androidContext)
+ },
+ requestPermission = { perm ->
+ activityLauncherHelper.launch(Intent().apply {
+ action = Settings.ACTION_MANAGE_OVERLAY_PERMISSION
+ data = Uri.parse("package:${context.androidContext.packageName}")
+ }) { resultCode, _ ->
+ coroutineScope.launch {
+ grantedPermissions[perm.translationKey] = resultCode == 0
+ }
+ }
+ }
+ )
+ )
}
+ allowNext(permissions.all { perm -> grantedPermissions[perm.translationKey] == true })
+
LaunchedEffect(Unit) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- notificationPermissionGranted =
- context.androidContext.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
- }
- val powerManager =
- context.androidContext.getSystemService(Context.POWER_SERVICE) as PowerManager
- isBatteryOptimisationIgnored =
- powerManager.isIgnoringBatteryOptimizations(context.androidContext.packageName)
- if (isBatteryOptimisationIgnored && notificationPermissionGranted) {
- goNext()
+ permissions.forEach { perm ->
+ grantedPermissions[perm.translationKey] = perm.isPermissionGranted()
}
}
@@ -88,52 +144,23 @@ class PermissionsScreen : SetupScreen() {
modifier = Modifier
.padding(all = 16.dp),
) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- ) {
- DialogText(
- text = context.translation["setup.permissions.notification_access"],
- modifier = Modifier.weight(1f)
- )
- if (notificationPermissionGranted) {
- GrantedIcon()
- } else {
- RequestButton {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- activityLauncherHelper.requestPermission(Manifest.permission.POST_NOTIFICATIONS) { resultCode, _ ->
- coroutineScope.launch {
- notificationPermissionGranted =
- resultCode == ComponentActivity.RESULT_OK
- }
- }
+ permissions.forEach { perm ->
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ DialogText(
+ text = context.translation["setup.permissions.${perm.translationKey}"],
+ modifier = Modifier.weight(1f)
+ )
+ if (grantedPermissions[perm.translationKey] == true) {
+ GrantedIcon()
+ } else {
+ RequestButton {
+ perm.requestPermission(perm)
}
}
}
}
-
- Row(
- verticalAlignment = Alignment.CenterVertically,
- ) {
- DialogText(
- text = context.translation["setup.permissions.battery_optimization"],
- modifier = Modifier.weight(1f)
- )
- if (isBatteryOptimisationIgnored) {
- GrantedIcon()
- } else {
- RequestButton {
- activityLauncherHelper.launch(Intent().apply {
- action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
- data = Uri.parse("package:${context.androidContext.packageName}")
- }) { resultCode, _ ->
- coroutineScope.launch {
- isBatteryOptimisationIgnored = resultCode == 0
- }
- }
- }
- }
-
- }
}
}
}
diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json
@@ -16,6 +16,7 @@
"dialog": "To continue you need to fit the following requirements:",
"notification_access": "Notification Access",
"battery_optimization": "Battery Optimization",
+ "display_over_other_apps": "Display Over Other Apps",
"request_button": "Request"
}
},