Handle mobile call answer/hangup/reject/history

This commit is contained in:
Juha Heinanen
2026-05-10 12:22:02 +03:00
parent cb0b87950f
commit 84edc5e124
3 changed files with 68 additions and 69 deletions

View File

@ -545,18 +545,15 @@ class BaresipService: Service() {
} }
"Call Answer" -> { "Call Answer" -> {
val uap = intent!!.getLongExtra("uap", 0L) val callp = intent!!.getLongExtra("callp", 0L)
val callp = intent.getLongExtra("callp", 0L) val call = Call.ofCallp(callp)
stopRinging() stopRinging()
stopMediaPlayer() stopMediaPlayer()
setCallVolume() setCallVolume()
proximitySensing(proximitySensing) proximitySensing(proximitySensing)
if (telecom) call?.answer()
Api.ua_answer(uap, callp, Api.VIDMODE_OFF) if (!telecom)
else {
Api.ua_answer(uap, callp, Api.VIDMODE_OFF)
ensureCommunicationMode() ensureCommunicationMode()
}
} }
"Call Reject" -> { "Call Reject" -> {
@ -569,20 +566,15 @@ class BaresipService: Service() {
val aor = call.ua.account.aor val aor = call.ua.account.aor
Log.d(TAG, "Aor $aor rejected incoming call $callp from $peerUri") Log.d(TAG, "Aor $aor rejected incoming call $callp from $peerUri")
call.rejected = true call.rejected = true
Api.ua_hangup(call.ua.uap, callp, 486, "Rejected") call.reject()
} }
} }
"Call Hangup" -> { "Call Hangup" -> {
val callp = intent!!.getLongExtra("callp", 0L) val callp = intent!!.getLongExtra("callp", 0L)
Log.d(TAG, "onStartCommand Hangup action for $callp") Log.d(TAG, "onStartCommand Hangup action for $callp")
val connection = ConnectionService.connections[callp] val call = Call.ofCallp(callp)
if (connection != null) { call?.hangup(0, "")
connection.onDisconnect() // This calls Api.ua_hangup(..., 0, "")
} else {
val call = Call.ofCallp(callp)
if (call != null) Api.ua_hangup(call.ua.uap, callp, 0, "")
}
} }
"Transfer Deny" -> { "Transfer Deny" -> {
@ -1798,6 +1790,8 @@ class BaresipService: Service() {
calls.find { it.callp == call.hashCode().toLong() }?.let { calls.find { it.callp == call.hashCode().toLong() }?.let {
if (it.status.value != newStatus) { if (it.status.value != newStatus) {
it.status.value = newStatus it.status.value = newStatus
if (newStatus == "connected")
it.startTime = GregorianCalendar()
postServiceEvent(ServiceEvent( postServiceEvent(ServiceEvent(
"call update", "call update",
arrayListOf(it.ua.uap, it.callp), arrayListOf(it.ua.uap, it.callp),
@ -1820,7 +1814,23 @@ class BaresipService: Service() {
fun handleExternalCallRemoved(telecomCall: android.telecom.Call) { fun handleExternalCallRemoved(telecomCall: android.telecom.Call) {
val callp = telecomCall.hashCode().toLong() val callp = telecomCall.hashCode().toLong()
calls.removeAll { it.callp == callp } val call = calls.find { it.callp == callp }
if (call != null) {
if (call.ua.account.callHistory) {
val history = CallHistoryNew(call.ua.account.aor, call.peerUri, call.dir)
history.stopTime = GregorianCalendar()
history.startTime = call.startTime
history.rejected = call.rejected
history.add()
if (call.dir == "in" && call.startTime == null && !call.rejected)
call.ua.account.missedCalls = true
}
calls.remove(call)
}
if (!Call.inCall()) {
proximitySensing(false)
stopMediaPlayer()
}
messageUpdate.postValue(System.currentTimeMillis()) messageUpdate.postValue(System.currentTimeMillis())
} }

View File

@ -150,6 +150,26 @@ open class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir
Api.call_destroy(callp) Api.call_destroy(callp)
} }
open fun hangup(code: Int, reason: String) {
if (BaresipService.telecom) {
val connection = ConnectionService.connections[callp]
if (connection != null)
connection.onDisconnect()
else
Api.ua_hangup(ua.uap, callp, code, reason)
} else {
Api.ua_hangup(ua.uap, callp, code, reason)
}
}
open fun answer() {
Api.ua_answer(ua.uap, callp, Api.VIDMODE_OFF)
}
open fun reject() {
hangup(486, "Busy Here")
}
class ExternalCall( class ExternalCall(
val telecomCall: android.telecom.Call, val telecomCall: android.telecom.Call,
ua: UserAgent, ua: UserAgent,
@ -163,6 +183,10 @@ open class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir
return true return true
} }
override fun answer() {
telecomCall.answer(android.telecom.VideoProfile.STATE_AUDIO_ONLY)
}
override fun hold(): Boolean { override fun hold(): Boolean {
telecomCall.hold() telecomCall.hold()
onhold = true onhold = true
@ -177,6 +201,14 @@ open class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir
return true return true
} }
override fun hangup(code: Int, reason: String) {
telecomCall.disconnect()
}
override fun reject() {
telecomCall.disconnect()
}
override fun destroy() { override fun destroy() {
telecomCall.disconnect() telecomCall.disconnect()
} }

View File

@ -1532,18 +1532,8 @@ private fun CallRow(
onClick = { onClick = {
if (call.terminated.value) return@IconButton if (call.terminated.value) return@IconButton
call.terminated.value = true call.terminated.value = true
if (BaresipService.telecom) { Log.d(TAG, "AoR ${call.ua.account.aor} canceling call ${call.callp}")
val connection = ConnectionService.connections[call.callp] call.hangup(487, "Request Terminated")
if (connection != null)
connection.onDisconnect()
else {
Log.d(TAG, "AoR ${call.ua.account.aor} canceling call ${call.callp}")
Api.ua_hangup(call.ua.uap, call.callp, 487, "Request Terminated")
}
} else {
Log.d(TAG, "AoR ${call.ua.account.aor} canceling call ${call.callp}")
Api.ua_hangup(call.ua.uap, call.callp, 487, "Request Terminated")
}
}, },
) { ) {
Icon( Icon(
@ -1564,18 +1554,8 @@ private fun CallRow(
onClick = { onClick = {
if (call.terminated.value) return@IconButton if (call.terminated.value) return@IconButton
call.terminated.value = true call.terminated.value = true
if (BaresipService.telecom) { Log.d(TAG, "AoR ${call.ua.account.aor} hanging up call ${call.callp}")
val connection = ConnectionService.connections[call.callp] call.hangup(487, "Request Terminated")
if (connection != null)
connection.onDisconnect()
else {
Log.d(TAG, "AoR ${call.ua.account.aor} hanging up call ${call.callp}")
Api.ua_hangup(call.ua.uap, call.callp, 487, "Request Terminated")
}
} else {
Log.d(TAG, "AoR ${call.ua.account.aor} hanging up call ${call.callp}")
Api.ua_hangup(call.ua.uap, call.callp, 487, "Request Terminated")
}
} }
) { ) {
Icon( Icon(
@ -1623,8 +1603,7 @@ private fun CallRow(
showAlert.value = true showAlert.value = true
} }
else { else {
val connection = ConnectionService.connections[call.callp] call.hold()
connection?.onHold()
if (!call.executeTransfer()) { if (!call.executeTransfer()) {
alertTitle.value = ctx.getString(R.string.notice) alertTitle.value = ctx.getString(R.string.notice)
alertMessage.value = ctx.getString(R.string.transfer_failed) alertMessage.value = ctx.getString(R.string.transfer_failed)
@ -2197,8 +2176,6 @@ private fun makeCall(ctx: Context, viewModel: ViewModel, uriText: String,
private fun answer(ctx: Context, call: Call) { private fun answer(ctx: Context, call: Call) {
Log.d(TAG, "AoR ${call.ua.account.aor} answering call from ${call.callUri.value}") Log.d(TAG, "AoR ${call.ua.account.aor} answering call from ${call.callUri.value}")
if (BaresipService.telecom)
ConnectionService.connections[call.callp]?.setActive()
val intent = Intent(ctx, BaresipService::class.java) val intent = Intent(ctx, BaresipService::class.java)
intent.action = "Call Answer" intent.action = "Call Answer"
intent.putExtra("uap", call.ua.uap) intent.putExtra("uap", call.ua.uap)
@ -2208,19 +2185,7 @@ private fun answer(ctx: Context, call: Call) {
private fun reject(call: Call) { private fun reject(call: Call) {
Log.d(TAG, "AoR ${call.ua.account.aor} rejecting call ${call.callp} from ${call.callUri.value}") Log.d(TAG, "AoR ${call.ua.account.aor} rejecting call ${call.callp} from ${call.callUri.value}")
if (BaresipService.telecom) { call.reject()
val connection = ConnectionService.connections[call.callp]
if (connection != null)
connection.onReject()
else {
call.rejected = true
Api.ua_hangup(call.ua.uap, call.callp, 486, "Busy Here")
}
}
else {
call.rejected = true
Api.ua_hangup(call.ua.uap, call.callp, 486, "Busy Here")
}
} }
private fun transfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, uriText: String, attended: Boolean) { private fun transfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, uriText: String, attended: Boolean) {
@ -2237,14 +2202,7 @@ private fun transfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, uriText:
val call = ua.currentCall() val call = ua.currentCall()
if (call != null) { if (call != null) {
if (attended) { if (attended) {
val connection = ConnectionService.connections[call.callp] if (call.hold()) {
val success = if (connection != null) {
connection.onHold()
true
} else {
call.hold()
}
if (success) {
call.onhold = true call.onhold = true
call.referTo = uri call.referTo = uri
makeCall(ctx, viewModel, uri, viewModel.dialerState, call.callp) makeCall(ctx, viewModel, uri, viewModel.dialerState, call.callp)
@ -2252,8 +2210,7 @@ private fun transfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, uriText:
} }
} }
else { else {
val connection = ConnectionService.connections[call.callp] call.hold()
connection?.onHold()
if (!call.transfer(uri)) { if (!call.transfer(uri)) {
alertTitle.value = ctx.getString(R.string.notice) alertTitle.value = ctx.getString(R.string.notice)
alertMessage.value = ctx.getString(R.string.transfer_failed) alertMessage.value = ctx.getString(R.string.transfer_failed)
@ -2353,7 +2310,7 @@ private fun showCall(ctx: Context, viewModel: ViewModel, ua: UserAgent?, showCal
call.callUriLabel.value = ctx.getString(R.string.incoming_call_from_dots) call.callUriLabel.value = ctx.getString(R.string.incoming_call_from_dots)
call.callUri.value = Utils.friendlyUri(ctx, call.peerUri, ua.account) call.callUri.value = Utils.friendlyUri(ctx, call.peerUri, ua.account)
} }
call.transferButtonEnabled.value = true call.transferButtonEnabled.value = !ua.account.isMobile
} }
call.callUri2.value = "" call.callUri2.value = ""
call.callTransfer.value = call.onHoldCall != null call.callTransfer.value = call.onHoldCall != null
@ -2569,7 +2526,7 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params
val callp = params[1] as Long val callp = params[1] as Long
val call = Call.ofCallp(callp) val call = Call.ofCallp(callp)
if (call in Call.calls()) if (call in Call.calls())
Api.ua_hangup(uap, callp, 487, "Request Terminated") call!!.hangup(487, "Request Terminated")
makeCall(ctx, viewModel, ev[1], viewModel.dialerState) makeCall(ctx, viewModel, ev[1], viewModel.dialerState)
showCall(ctx, viewModel, ua) showCall(ctx, viewModel, ua)
} }