Call hold/resume improvements
This commit is contained in:
@ -801,7 +801,7 @@ 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 toastMsg = if (Utils.isAnyCallActive(applicationContext))
|
val toastMsg = if (Call.isAnyCallActive(applicationContext))
|
||||||
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 (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri)
|
else if (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri)
|
||||||
|
|||||||
@ -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
|
||||||
@ -55,11 +57,15 @@ class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir: Str
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun hold(): Boolean {
|
fun hold(): Boolean {
|
||||||
return Api.call_hold(callp, true) == 0
|
if (Api.call_hold(callp, true) == 0)
|
||||||
|
onhold = true
|
||||||
|
return onhold
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resume(): Boolean {
|
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 {
|
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 {
|
fun inCall(): Boolean {
|
||||||
return BaresipService.calls.isNotEmpty()
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -206,23 +206,17 @@ class ConnectionService : ConnectionService() {
|
|||||||
|
|
||||||
override fun onHold() {
|
override fun onHold() {
|
||||||
Log.d(TAG, "Telecom Connection onHold $callp")
|
Log.d(TAG, "Telecom Connection onHold $callp")
|
||||||
val call = Call.ofCallp(callp)
|
val c = Call.ofCallp(callp)
|
||||||
if (call == null || !call.conferenceCall) {
|
if (c?.conferenceCall != true)
|
||||||
Api.call_hold(callp, true)
|
c?.hold()
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Call $callp is in conference, skipping baresip hold")
|
|
||||||
}
|
|
||||||
setOnHold()
|
setOnHold()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnhold() {
|
override fun onUnhold() {
|
||||||
Log.d(TAG, "Telecom Connection onUnhold $callp")
|
Log.d(TAG, "Telecom Connection onUnhold $callp")
|
||||||
val call = Call.ofCallp(callp)
|
val c = Call.ofCallp(callp)
|
||||||
if (call == null || !call.conferenceCall) {
|
if (c?.conferenceCall != true)
|
||||||
Api.call_hold(callp, false)
|
c?.resume()
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Call $callp is in conference, skipping baresip resume")
|
|
||||||
}
|
|
||||||
setActive()
|
setActive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1534,43 +1534,42 @@ private fun CallRow(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
IconButton(
|
if (!call.conferenceCall)
|
||||||
modifier = Modifier.size(48.dp),
|
IconButton(
|
||||||
onClick = {
|
modifier = Modifier.size(48.dp),
|
||||||
val connection = ConnectionService.connections[call.callp]
|
onClick = {
|
||||||
if (call.onhold) {
|
val connection = ConnectionService.connections[call.callp]
|
||||||
Log.d(
|
if (call.onhold) {
|
||||||
TAG,
|
Log.d(
|
||||||
"AoR ${call.ua.account.aor} resuming call ${call.callp} with ${call.callUri.value}"
|
TAG,
|
||||||
)
|
"AoR ${call.ua.account.aor} resuming call ${call.callp} with ${call.callUri.value}"
|
||||||
if (connection != null)
|
)
|
||||||
connection.onUnhold()
|
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
|
else
|
||||||
call.resume()
|
MaterialTheme.colorScheme.secondary,
|
||||||
call.onhold = false
|
contentDescription = null,
|
||||||
} 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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var showTransferDialog by remember { mutableStateOf(false) }
|
var showTransferDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
@ -2129,6 +2128,7 @@ private fun transfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, uriText:
|
|||||||
call.onhold = true
|
call.onhold = true
|
||||||
call.referTo = uri
|
call.referTo = uri
|
||||||
makeCall(ctx, viewModel, uri, false, call.callp)
|
makeCall(ctx, viewModel, uri, false, call.callp)
|
||||||
|
showCall(ctx, viewModel, ua, call)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -842,10 +842,6 @@ object Utils {
|
|||||||
Configuration.UI_MODE_NIGHT_YES
|
Configuration.UI_MODE_NIGHT_YES
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isAnyCallActive(ctx: Context): Boolean {
|
|
||||||
return inCall() || isPSTNCallActive(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isPSTNCallActive(ctx: Context): Boolean {
|
fun isPSTNCallActive(ctx: Context): Boolean {
|
||||||
// MODE_IN_CALL indicates a PSTN call is active
|
// MODE_IN_CALL indicates a PSTN call is active
|
||||||
val am = ctx.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
val am = ctx.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
|
|||||||
Reference in New Issue
Block a user