From 7a7ad4f02e4c693653cf3c4d6268020881483ed2 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Wed, 3 Jun 2026 17:57:48 +0300 Subject: [PATCH] Improved mobile account's airplane mode handling in APIs < 31 --- .../com/tutpro/baresip/BaresipService.kt | 61 ++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 24ed9136..1b5b1300 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -1,3 +1,4 @@ +@file:Suppress("DEPRECATION") package com.tutpro.baresip import android.Manifest.permission.RECORD_AUDIO @@ -55,6 +56,7 @@ import android.telecom.Connection import android.telecom.DisconnectCause import android.telecom.PhoneAccountHandle import android.telecom.TelecomManager +import android.telephony.PhoneStateListener import android.telephony.ServiceState import android.telephony.TelephonyCallback import android.telephony.TelephonyManager @@ -89,6 +91,7 @@ import java.util.Timer import java.util.TimerTask import kotlin.concurrent.schedule import kotlin.math.roundToInt +import kotlin.time.Duration.Companion.milliseconds class BaresipService: Service() { @@ -104,6 +107,8 @@ class BaresipService: Service() { private lateinit var btm: BluetoothManager private lateinit var telephonyManager: TelephonyManager private lateinit var telephonyCallback: TelephonyCallback + @Suppress("DEPRECATION") + private lateinit var phoneStateListener: PhoneStateListener private lateinit var vibrator: Vibrator private lateinit var partialWakeLock: PowerManager.WakeLock private lateinit var proximityWakeLock: PowerManager.WakeLock @@ -390,15 +395,15 @@ class BaresipService: Service() { if (VERSION.SDK_INT >= 31) { telephonyCallback = object : TelephonyCallback(), TelephonyCallback.ServiceStateListener { override fun onServiceStateChanged(serviceState: ServiceState) { - val isAirplaneModeOn = Utils.isAirplaneModeOn(this@BaresipService) - val status = if (isAirplaneModeOn) - R.drawable.circle_white - else if (serviceState.state == ServiceState.STATE_IN_SERVICE) - circleGreen.getValue(colorblind) - else - circleRed.getValue(colorblind) - Log.d(TAG, "Mobile service state changed: ${serviceState.state}, updating status to $status") - updateMobileStatus(status) + updateMobileStatusFromServiceState(serviceState.state) + } + } + } else { + @Suppress("DEPRECATION") + phoneStateListener = object : PhoneStateListener() { + @Deprecated("Deprecated in Java") + override fun onServiceStateChanged(serviceState: ServiceState) { + updateMobileStatusFromServiceState(serviceState.state) } } } @@ -1064,7 +1069,7 @@ class BaresipService: Service() { // transaction (the re-INVITE from the peer) finish // before trying to hold the other call and resume this one. CoroutineScope(Dispatchers.Main).launch { - delay(100) + delay(100.milliseconds) call.resume() } } @@ -1260,7 +1265,7 @@ class BaresipService: Service() { } history.add() if (call.startTime != null && call.dumpfiles[0] != "") { - delay(500) + delay(500.milliseconds) val rxFile = File(call.dumpfiles[0]) val txFile = File(call.dumpfiles[1]) val mergedFileName = rxFile.name @@ -1643,6 +1648,11 @@ class BaresipService: Service() { } catch (e: Exception) { Log.e(TAG, "Failed to register TelephonyCallback: ${e.message}") } + } else if (!telephonyCallbackRegistered) { + @Suppress("DEPRECATION") + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE) + telephonyCallbackRegistered = true + Log.d(TAG, "Registered PhoneStateListener") } Api.net_debug() postServiceEvent( @@ -2094,6 +2104,7 @@ class BaresipService: Service() { Log.d(TAG, "Removing Mobile account (role lost or SIM missing)") existingMobileUa.remove() Account.saveAccounts() + updateStatusNotification() } return } @@ -2121,6 +2132,7 @@ class BaresipService: Service() { uasStatus.value = UserAgent.statusMap() Account.saveAccounts() + updateStatusNotification() } private fun toast(message: String, length: Int = Toast.LENGTH_SHORT) { @@ -2133,10 +2145,16 @@ class BaresipService: Service() { uas.value.find { it.account.isMobile }?.let { ua -> val isAirplaneModeOn = Utils.isAirplaneModeOn(this) val status = newStatus - ?: if (isAirplaneModeOn) + ?: if (isAirplaneModeOn) { R.drawable.circle_white - else - ua.status + } else { + if (ua.status == R.drawable.circle_white) { + // Show "Red" (not yet in service) + circleRed.getValue(colorblind) + } else { + ua.status + } + } if (ua.status != status) { Log.d(TAG, "Updating Mobile status to $status") ua.updateStatus(status) @@ -2147,6 +2165,18 @@ class BaresipService: Service() { } } + private fun updateMobileStatusFromServiceState(state: Int) { + val isAirplaneModeOn = Utils.isAirplaneModeOn(this) + val status = if (isAirplaneModeOn) + R.drawable.circle_white + else if (state == ServiceState.STATE_IN_SERVICE) + circleGreen.getValue(colorblind) + else + circleRed.getValue(colorblind) + Log.d(TAG, "Mobile service state changed: $state, updating status to $status") + updateMobileStatus(status) + } + @SuppressLint("FullScreenIntentPolicy") fun handleIncomingCall(call: Call) { val ua = call.ua @@ -2751,6 +2781,9 @@ class BaresipService: Service() { try { telephonyManager.unregisterTelephonyCallback(telephonyCallback) } catch (_: Exception) {} + } else { + @Suppress("DEPRECATION") + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE) } telephonyCallbackRegistered = false }