Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c31d3890 authored by Moez Bhatti's avatar Moez Bhatti
Browse files

Ensure exact alarm permission before sending scheduled/delayed messages

parent c1483d2c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
package com.moez.QKSMS.manager

import android.Manifest
import android.app.AlarmManager
import android.app.NotificationManager
import android.app.role.RoleManager
import android.content.Context
@@ -71,6 +72,15 @@ class PermissionManagerImpl @Inject constructor(private val context: Context) :
        return hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    }

    override fun hasExactAlarms(): Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
            return true
        }

        val alarmManager = context.getSystemService(AlarmManager::class.java)
        return alarmManager.canScheduleExactAlarms()
    }

    private fun hasPermission(permission: String): Boolean {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
    }
+2 −0
Original line number Diff line number Diff line
@@ -36,4 +36,6 @@ interface PermissionManager {

    fun hasStorage(): Boolean

    fun hasExactAlarms(): Boolean

}
+8 −0
Original line number Diff line number Diff line
@@ -309,4 +309,12 @@ class Navigator @Inject constructor(
        }
    }

    fun showExactAlarmsSettings() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)
                    .setData(Uri.parse("package:${context.packageName}"))
            startActivity(intent)
        }
    }

}
+21 −8
Original line number Diff line number Diff line
@@ -634,23 +634,36 @@ class ComposeViewModel @Inject constructor(

        // Send a message when the send button is clicked, and disable editing mode if it's enabled
        view.sendIntent
                .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } }
                .filter { permissionManager.hasSendSms().also { if (!it) view.requestSmsPermission() } }
                .withLatestFrom(view.textChangedIntent) { _, body -> body }
                .map { body -> body.toString() }
                .withLatestFrom(view.textChangedIntent) { _, body -> body.toString() }
                .withLatestFrom(state, attachments, conversation, selectedChips) { body, state, attachments,
                                                                                   conversation, chips ->
                    val subId = state.subscription?.subscriptionId ?: -1
                    val addresses = when (conversation.recipients.isNotEmpty()) {
                        true -> conversation.recipients.map { it.address }
                        false -> chips.map { chip -> chip.address }
                    if (!permissionManager.isDefaultSms()) {
                        view.requestDefaultSms()
                        return@withLatestFrom
                    }

                    if (!permissionManager.hasSendSms()) {
                        view.requestSmsPermission()
                        return@withLatestFrom
                    }

                    val delay = when (prefs.sendDelay.get()) {
                        Preferences.SEND_DELAY_SHORT -> 3000
                        Preferences.SEND_DELAY_MEDIUM -> 5000
                        Preferences.SEND_DELAY_LONG -> 10000
                        else -> 0
                    }

                    if ((delay != 0 || state.scheduled != 0L) && !permissionManager.hasExactAlarms()) {
                        navigator.showExactAlarmsSettings()
                        return@withLatestFrom
                    }

                    val subId = state.subscription?.subscriptionId ?: -1
                    val addresses = when (conversation.recipients.isNotEmpty()) {
                        true -> conversation.recipients.map { it.address }
                        false -> chips.map { chip -> chip.address }
                    }
                    val sendAsGroup = !state.editingMode || state.sendAsGroup

                    when {