diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index cae4e965..eb0fe7d6 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -801,7 +801,7 @@ class BaresipService: Service() { "incoming call" -> { val peerUri = ev[1] val bevent = ev[2].toLong() - val toastMsg = if (Utils.isAnyCallActive(applicationContext)) + val toastMsg = if (Call.isAnyCallActive(applicationContext)) String.format(getString(R.string.call_auto_rejected), Utils.friendlyUri(this, peerUri, ua.account)) else if (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) diff --git a/app/src/main/kotlin/com/tutpro/baresip/Call.kt b/app/src/main/kotlin/com/tutpro/baresip/Call.kt index 8f74a7a0..3762fb6e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Call.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Call.kt @@ -1,5 +1,7 @@ package com.tutpro.baresip +import android.content.Context +import android.media.AudioManager import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf @@ -55,11 +57,15 @@ class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir: Str } fun hold(): Boolean { - return Api.call_hold(callp, true) == 0 + if (Api.call_hold(callp, true) == 0) + onhold = true + return onhold } fun resume(): Boolean { - return Api.call_hold(callp, false) == 0 + if (Api.call_hold(callp, false) == 0) + onhold = false + return !onhold } fun transfer(uri: String): Boolean { @@ -142,5 +148,13 @@ class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir: Str fun inCall(): Boolean { return BaresipService.calls.isNotEmpty() } + + fun isAnyCallActive(ctx: Context): Boolean { + // Check if there exist SIP calls that are not onhold or held + if (BaresipService.calls.any { !it.onhold && !it.held }) 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 + } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ConnectionService.kt b/app/src/main/kotlin/com/tutpro/baresip/ConnectionService.kt index 36a61d02..6019b658 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ConnectionService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ConnectionService.kt @@ -206,23 +206,17 @@ class ConnectionService : ConnectionService() { override fun onHold() { Log.d(TAG, "Telecom Connection onHold $callp") - val call = Call.ofCallp(callp) - if (call == null || !call.conferenceCall) { - Api.call_hold(callp, true) - } else { - Log.d(TAG, "Call $callp is in conference, skipping baresip hold") - } + val c = Call.ofCallp(callp) + if (c?.conferenceCall != true) + c?.hold() setOnHold() } override fun onUnhold() { Log.d(TAG, "Telecom Connection onUnhold $callp") - val call = Call.ofCallp(callp) - if (call == null || !call.conferenceCall) { - Api.call_hold(callp, false) - } else { - Log.d(TAG, "Call $callp is in conference, skipping baresip resume") - } + val c = Call.ofCallp(callp) + if (c?.conferenceCall != true) + c?.resume() setActive() } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt index 111af184..7ae3d0dc 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt @@ -1534,43 +1534,42 @@ private fun CallRow( ) } - IconButton( - modifier = Modifier.size(48.dp), - onClick = { - val connection = ConnectionService.connections[call.callp] - if (call.onhold) { - Log.d( - TAG, - "AoR ${call.ua.account.aor} resuming call ${call.callp} with ${call.callUri.value}" - ) - if (connection != null) - connection.onUnhold() + if (!call.conferenceCall) + IconButton( + modifier = Modifier.size(48.dp), + onClick = { + val connection = ConnectionService.connections[call.callp] + if (call.onhold) { + Log.d( + TAG, + "AoR ${call.ua.account.aor} resuming call ${call.callp} with ${call.callUri.value}" + ) + if (connection != null) + connection.onUnhold() + else + call.resume() + } else { + Log.d( + TAG, + "AoR ${call.ua.account.aor} holding call ${call.callp} with ${call.callUri.value}" + ) + if (connection != null) + connection.onHold() + else + call.hold() + } + }, + ) { + Icon( + imageVector = Icons.Outlined.PauseCircle, + modifier = Modifier.size(42.dp), + tint = if (call.callOnHold.value) + MaterialTheme.colorScheme.error else - call.resume() - call.onhold = false - } else { - Log.d( - TAG, - "AoR ${call.ua.account.aor} holding call ${call.callp} with ${call.callUri.value}" - ) - if (connection != null) - connection.onHold() - else - call.hold() - call.onhold = true - } - }, - ) { - Icon( - imageVector = Icons.Outlined.PauseCircle, - modifier = Modifier.size(42.dp), - tint = if (call.callOnHold.value) - MaterialTheme.colorScheme.error - else - MaterialTheme.colorScheme.secondary, - contentDescription = null, - ) - } + MaterialTheme.colorScheme.secondary, + contentDescription = null, + ) + } var showTransferDialog by remember { mutableStateOf(false) } @@ -2129,6 +2128,7 @@ private fun transfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, uriText: call.onhold = true call.referTo = uri makeCall(ctx, viewModel, uri, false, call.callp) + showCall(ctx, viewModel, ua, call) } } else { diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 97e3431c..200cb427 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -842,10 +842,6 @@ object Utils { Configuration.UI_MODE_NIGHT_YES } - fun isAnyCallActive(ctx: Context): Boolean { - return inCall() || isPSTNCallActive(ctx) - } - fun isPSTNCallActive(ctx: Context): Boolean { // MODE_IN_CALL indicates a PSTN call is active val am = ctx.getSystemService(Context.AUDIO_SERVICE) as AudioManager