fix(permissions): Offer battery optimization card in AUTOMATIC mode

This commit is contained in:
Matthias Urhahn
2026-07-17 17:24:48 +02:00
parent 2672dbdcf6
commit 911a09c743
2 changed files with 24 additions and 8 deletions
@@ -64,8 +64,10 @@ class PermissionTool @Inject constructor(
/**
* Whether [permission] is applicable for the user's current configuration.
* Three permissions are conditional on monitor mode or popup usage:
* - [Permission.IGNORE_BATTERY_OPTIMIZATION] only when always-on scanning is needed
* - [Permission.ACCESS_BACKGROUND_LOCATION] same
* - [Permission.IGNORE_BATTERY_OPTIMIZATION] whenever the monitor service is expected to
* run unattended (AUTOMATIC and ALWAYS) — those users depend on a long-lived foreground
* service that aggressive vendor battery management may otherwise kill
* - [Permission.ACCESS_BACKGROUND_LOCATION] only when always-on scanning is needed
* - [Permission.SYSTEM_ALERT_WINDOW] only when at least one popup reaction is enabled
* Everything else is unconditionally applicable.
*/
@@ -74,7 +76,7 @@ class PermissionTool @Inject constructor(
monitorMode: MonitorMode,
anyPopupEnabled: Boolean,
): Boolean = when (permission) {
Permission.IGNORE_BATTERY_OPTIMIZATION,
Permission.IGNORE_BATTERY_OPTIMIZATION -> monitorMode != MonitorMode.MANUAL
Permission.ACCESS_BACKGROUND_LOCATION -> monitorMode == MonitorMode.ALWAYS
Permission.SYSTEM_ALERT_WINDOW -> anyPopupEnabled
else -> true
@@ -8,7 +8,7 @@ import testhelpers.BaseTest
class PermissionToolTest : BaseTest() {
@Test
fun `IGNORE_BATTERY_OPTIMIZATION is applicable only in ALWAYS mode`() {
fun `IGNORE_BATTERY_OPTIMIZATION is applicable in ALWAYS and AUTOMATIC modes`() {
PermissionTool.isApplicable(
Permission.IGNORE_BATTERY_OPTIMIZATION,
MonitorMode.ALWAYS,
@@ -18,7 +18,7 @@ class PermissionToolTest : BaseTest() {
Permission.IGNORE_BATTERY_OPTIMIZATION,
MonitorMode.AUTOMATIC,
anyPopupEnabled = false,
) shouldBe false
) shouldBe true
PermissionTool.isApplicable(
Permission.IGNORE_BATTERY_OPTIMIZATION,
MonitorMode.MANUAL,
@@ -73,13 +73,27 @@ class PermissionToolTest : BaseTest() {
@Test
fun `mode-gated permissions don't depend on popup state`() {
// IGNORE_BATTERY_OPTIMIZATION and ACCESS_BACKGROUND_LOCATION gate on mode only.
// IGNORE_BATTERY_OPTIMIZATION and ACCESS_BACKGROUND_LOCATION gate on mode only
// but on different modes: battery optimization applies to all unattended modes,
// background location only to ALWAYS.
listOf(Permission.IGNORE_BATTERY_OPTIMIZATION, Permission.ACCESS_BACKGROUND_LOCATION).forEach { perm ->
PermissionTool.isApplicable(perm, MonitorMode.ALWAYS, anyPopupEnabled = true) shouldBe true
PermissionTool.isApplicable(perm, MonitorMode.ALWAYS, anyPopupEnabled = false) shouldBe true
PermissionTool.isApplicable(perm, MonitorMode.AUTOMATIC, anyPopupEnabled = true) shouldBe false
PermissionTool.isApplicable(perm, MonitorMode.AUTOMATIC, anyPopupEnabled = false) shouldBe false
PermissionTool.isApplicable(perm, MonitorMode.MANUAL, anyPopupEnabled = true) shouldBe false
PermissionTool.isApplicable(perm, MonitorMode.MANUAL, anyPopupEnabled = false) shouldBe false
}
PermissionTool.isApplicable(
Permission.IGNORE_BATTERY_OPTIMIZATION, MonitorMode.AUTOMATIC, anyPopupEnabled = true,
) shouldBe true
PermissionTool.isApplicable(
Permission.IGNORE_BATTERY_OPTIMIZATION, MonitorMode.AUTOMATIC, anyPopupEnabled = false,
) shouldBe true
PermissionTool.isApplicable(
Permission.ACCESS_BACKGROUND_LOCATION, MonitorMode.AUTOMATIC, anyPopupEnabled = true,
) shouldBe false
PermissionTool.isApplicable(
Permission.ACCESS_BACKGROUND_LOCATION, MonitorMode.AUTOMATIC, anyPopupEnabled = false,
) shouldBe false
}
@Test