From 8fbb73a21c2c6c7a72c6127458a14d938995254f Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Tue, 12 May 2026 10:17:34 +0300 Subject: [PATCH] Fixed adding of mobile call to history Fixed outgoing mobile call event Do not show new call card when mobile call is placed on hold --- .../com/tutpro/baresip/AccountScreen.kt | 5 ++--- .../com/tutpro/baresip/BaresipService.kt | 20 ++++++++++++++----- .../kotlin/com/tutpro/baresip/MainScreen.kt | 8 +++++++- .../main/kotlin/com/tutpro/baresip/Utils.kt | 9 ++++++--- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt index b53c1a5f..df40a49d 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/AccountScreen.kt @@ -1291,10 +1291,9 @@ private fun AccountContent( Answer() } Voicemail() - if (!ua.account.isMobile) { - CountryCode() + CountryCode() + if (!ua.account.isMobile) TelProvider() - } NumericKeypad() DefaultAccount() if (!ua.account.isMobile) diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 5aee597f..a968e6ab 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -68,6 +68,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.IconCompat import androidx.core.net.toUri import androidx.lifecycle.MutableLiveData +import com.tutpro.baresip.Utils.e164Uri import com.tutpro.baresip.Utils.toCircle import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -1703,8 +1704,12 @@ class BaresipService: Service() { } fun handleExternalCall(telecomCall: android.telecom.Call, preferredAor: String? = null) { - val uri = telecomCall.details.handle?.schemeSpecificPart ?: "Unknown" - Log.d(TAG, "Handling external call from $uri (preferredAor=$preferredAor)") + val rawUri = telecomCall.details.handle?.toString() ?: "Unknown" + val uri = try { + java.net.URLDecoder.decode(rawUri, "UTF-8") + } catch (_: Exception) { + rawUri + } if (uas.value.isEmpty()) { Log.e(TAG, "No User Agents available to handle external call") @@ -1719,13 +1724,17 @@ class BaresipService: Service() { telecomCall.details.state else @Suppress("DEPRECATION") telecomCall.state + + val isIncoming = telecomState == android.telecom.Call.STATE_RINGING + Log.d(TAG, "Handling external call ${if (isIncoming) "from" else "to"} $uri (preferredAor=$preferredAor)") + val initialStatus = when (telecomState) { android.telecom.Call.STATE_RINGING -> "incoming" android.telecom.Call.STATE_DIALING, android.telecom.Call.STATE_CONNECTING -> "outgoing" else -> "connected" } - if (initialStatus == "incoming") { + if (isIncoming) { if (ua.account.blockUnknown && Contact.contactName(uri) == uri) { Log.d(TAG, "Auto-rejecting incoming PSTN call from $uri") telecomCall.disconnect() @@ -1786,7 +1795,7 @@ class BaresipService: Service() { setCallVolume() ensureCommunicationMode() postServiceEvent(ServiceEvent( - "call incoming", + if (isIncoming) "call incoming" else "call outgoing", arrayListOf(ua.uap, call.callp), System.nanoTime()) ) @@ -1797,7 +1806,8 @@ class BaresipService: Service() { 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) + val historyPeerUri = e164Uri(call.peerUri, call.ua.account.countryCode) + val history = CallHistoryNew(call.ua.account.aor, historyPeerUri, call.dir) history.stopTime = GregorianCalendar() history.startTime = call.startTime history.rejected = call.rejected diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt index 6e320541..d721b0ed 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt @@ -916,6 +916,7 @@ private fun MainContent(navController: NavController, viewModel: ViewModel, cont val calls by viewModel.calls.collectAsState() val selectedAor by viewModel.selectedAor.collectAsState() + val ua = uas.value.find { it.account.aor == selectedAor } val aorCalls = calls.filter { it.ua.account.aor == selectedAor } val hasActiveCalls = aorCalls.any { !it.callOnHold.value } val conferenceCall = aorCalls.any { it.conferenceCall } @@ -1027,7 +1028,12 @@ private fun MainContent(navController: NavController, viewModel: ViewModel, cont } } - if (!hasActiveCalls || conferenceCall) + val showEmptyCard = if (ua?.account?.isMobile == true) + aorCalls.isEmpty() + else + !hasActiveCalls || conferenceCall + + if (showEmptyCard) CallCard(ctx = ctx, viewModel = viewModel, call = null, dialerState = viewModel.dialerState) Indicator( diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 3dd7de9b..a6dbbd83 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -133,7 +133,10 @@ object Utils { return if (uri.contains("@")) uri.substringAfter(":").substringBefore("@") else - "" + if (isTelUri(uri)) + uri.substringAfter(":").substringBefore(";") + else + "" } fun uriMatch(firstUri: String, secondUri: String): Boolean { @@ -185,14 +188,14 @@ object Utils { return u } - private fun e164Uri(uri: String, countryCode: String): String { + fun e164Uri(uri: String, countryCode: String): String { if (countryCode == "") return uri val scheme = uri.take(4) val userPart = uriUserPart(uri) return if (userPart.isDigitsOnly()) { when { userPart.startsWith("00") -> uri.replace("$scheme$userPart", - scheme + userPart.substring(2)) + scheme + "+" + userPart.substring(2)) userPart.startsWith("0") -> uri.replace("${scheme}0", "$scheme$countryCode") else -> uri.replace(scheme, "$scheme$countryCode")