Don't start ImapBackendPusher when the app doesn't have permission to schedule exact alarms

This commit is contained in:
cketti 2023-12-01 15:11:59 +01:00
parent ebf03d3a01
commit 2160a759e4
8 changed files with 34 additions and 1 deletions

View file

@ -5,6 +5,14 @@ import android.app.PendingIntent
import android.os.Build
class AlarmManagerCompat(private val alarmManager: AlarmManager) {
fun canScheduleExactAlarms(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
alarmManager.canScheduleExactAlarms()
} else {
true
}
}
fun scheduleAlarm(triggerAtMillis: Long, operation: PendingIntent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtMillis, operation)

View file

@ -57,6 +57,10 @@ class AndroidAlarmManager(
)
}
override fun canScheduleExactAlarms(): Boolean {
return alarmManager.canScheduleExactAlarms()
}
override fun setAlarm(triggerTime: Long, callback: Callback) {
this.callback.set(callback)
alarmManager.scheduleAlarm(triggerTime, pendingIntent)

View file

@ -19,6 +19,10 @@ class BackendIdleRefreshManager(private val alarmManager: SystemAlarmManager) :
private var minTimeout = Long.MAX_VALUE
private var minTimeoutTimestamp = 0L
override fun canScheduleTimers(): Boolean {
return alarmManager.canScheduleExactAlarms()
}
@Synchronized
override fun startTimer(timeout: Long, callback: Callback): IdleRefreshTimer {
require(timeout > MIN_TIMER_DELTA) { "Timeout needs to be greater than $MIN_TIMER_DELTA ms" }

View file

@ -50,6 +50,11 @@ internal class ImapBackendPusher(
private var currentIdleRefreshMs = 15 * 60 * 1000L
override fun start() {
if (!idleRefreshManager.canScheduleTimers()) {
Timber.v("Not starting ImapBackendPusher for %s because the app can't schedule timers", accountName)
return
}
coroutineScope.launch {
pushConfigProvider.maxPushFoldersFlow.collect { maxPushFolders ->
currentMaxPushFolders = maxPushFolders

View file

@ -1,6 +1,7 @@
package com.fsck.k9.backend.imap
interface SystemAlarmManager {
fun canScheduleExactAlarms(): Boolean
fun setAlarm(triggerTime: Long, callback: () -> Unit)
fun cancelAlarm()
fun now(): Long

View file

@ -156,6 +156,10 @@ class MockSystemAlarmManager(startTime: Long) : SystemAlarmManager {
var callback: Callback? = null
val alarmTimes = mutableListOf<Long>()
override fun canScheduleExactAlarms(): Boolean {
throw UnsupportedOperationException("not implemented")
}
override fun setAlarm(triggerTime: Long, callback: () -> Unit) {
this.triggerTime = triggerTime
this.callback = callback

View file

@ -1,6 +1,7 @@
package com.fsck.k9.mail.store.imap
interface IdleRefreshManager {
fun canScheduleTimers(): Boolean
fun startTimer(timeout: Long, callback: () -> Unit): IdleRefreshTimer
fun resetTimers()
}

View file

@ -1,8 +1,14 @@
package com.fsck.k9.mail.store.imap
class TestIdleRefreshManager : IdleRefreshManager {
class TestIdleRefreshManager(
private val areTimersSupported: Boolean = true,
) : IdleRefreshManager {
private val timers = mutableListOf<TestIdleRefreshTimer>()
override fun canScheduleTimers(): Boolean {
return areTimersSupported
}
@Synchronized
override fun startTimer(timeout: Long, callback: () -> Unit): TestIdleRefreshTimer {
return TestIdleRefreshTimer(timeout, callback).also { timer -> timers.add(timer) }