Improved checking if there already is an active call

This commit is contained in:
Juha Heinanen
2026-04-02 09:12:07 +03:00
parent d20b1adcc2
commit f64e1bd982
3 changed files with 13 additions and 35 deletions
@@ -65,9 +65,7 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.IconCompat import androidx.core.graphics.drawable.IconCompat
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.media.AudioAttributesCompat
import androidx.media.AudioFocusRequestCompat import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat
import com.tutpro.baresip.Utils.toCircle import com.tutpro.baresip.Utils.toCircle
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -804,18 +802,14 @@ class BaresipService: Service() {
"incoming call" -> { "incoming call" -> {
val peerUri = ev[1] val peerUri = ev[1]
val bevent = ev[2].toLong() val bevent = ev[2].toLong()
val blockUnknown = ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri val toastMsg = if (Call.isAnyCallActive(applicationContext))
val toastMsg = if (Call.inCall())
String.format(getString(R.string.call_auto_rejected), String.format(getString(R.string.call_auto_rejected),
Utils.friendlyUri(this, peerUri, ua.account)) Utils.friendlyUri(this, peerUri, ua.account))
else if (blockUnknown) else if (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri)
String.format(getString(R.string.call_blocked), String.format(getString(R.string.call_blocked),
Utils.friendlyUri(this, peerUri, ua.account)) Utils.friendlyUri(this, peerUri, ua.account))
else if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO))) else if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO)))
getString(R.string.no_calls) getString(R.string.no_calls)
else if (!requestAudioFocus(applicationContext))
// request fails if there is an active telephony call
getString(R.string.audio_focus_denied)
else else
"" ""
if (toastMsg != "") { if (toastMsg != "") {
@@ -823,7 +817,7 @@ class BaresipService: Service() {
Api.sip_treply(callp, 486, "Busy Here") Api.sip_treply(callp, 486, "Busy Here")
Api.bevent_stop(bevent) Api.bevent_stop(bevent)
toast(toastMsg) toast(toastMsg)
if (blockUnknown) { if (toastMsg.contains(getString(R.string.call_blocked))) {
if (ua.account.callHistory) if (ua.account.callHistory)
Blocked( Blocked(
ua.account.aor, ua.account.aor,
@@ -2110,30 +2104,5 @@ class BaresipService: Service() {
Log.d(TAG, "Added service event ${event.event}") Log.d(TAG, "Added service event ${event.event}")
} }
} }
fun requestAudioFocus(ctx: Context): Boolean {
Log.d(TAG, "Requesting audio focus")
if (audioFocusRequest != null) {
Log.d(TAG, "Already focused")
return true
}
val am = ctx.getSystemService(AUDIO_SERVICE) as AudioManager
val attributes = AudioAttributesCompat.Builder()
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
.setContentType(AudioAttributesCompat.CONTENT_TYPE_SPEECH)
.build()
audioFocusRequest = AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)
.setAudioAttributes(attributes)
.setOnAudioFocusChangeListener { }
.build()
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d(TAG, "requestAudioFocus granted")
} else {
Log.w(TAG, "requestAudioFocus denied")
audioFocusRequest = null
}
return audioFocusRequest != null
}
} }
} }
@@ -1,5 +1,7 @@
package com.tutpro.baresip package com.tutpro.baresip
import android.content.Context
import android.media.AudioManager
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@@ -143,5 +145,12 @@ class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir: Str
return BaresipService.calls.isNotEmpty() return BaresipService.calls.isNotEmpty()
} }
fun isAnyCallActive(ctx: Context): Boolean {
// Check SIP calls managed by baresip
if (inCall()) return true
// MODE_IN_CALL indicates a PSTN call is active
val am = ctx.getSystemService(Context.AUDIO_SERVICE) as AudioManager
return am.mode == AudioManager.MODE_IN_CALL
}
} }
} }
@@ -2061,7 +2061,7 @@ private fun makeCall(ctx: Context, viewModel: ViewModel, uriText: String, confer
alertMessage.value = String.format(ctx.getString(R.string.invalid_sip_or_tel_uri), uri) alertMessage.value = String.format(ctx.getString(R.string.invalid_sip_or_tel_uri), uri)
showAlert.value = true showAlert.value = true
} }
else if (Call.calls().any { it.ua.account.aor != ua.account.aor }) else if (Call.isAnyCallActive(ctx))
Toast.makeText(ctx, R.string.call_already_active, Toast.LENGTH_SHORT).show() Toast.makeText(ctx, R.string.call_already_active, Toast.LENGTH_SHORT).show()
else { else {
val tm = ctx.getSystemService(Context.TELECOM_SERVICE) as android.telecom.TelecomManager val tm = ctx.getSystemService(Context.TELECOM_SERVICE) as android.telecom.TelecomManager