From 01c079440d928471054200427988ca3a21b57622 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 26 Feb 2025 10:53:28 +0100 Subject: [PATCH] Do not follow telecom manager audio routing requests if not connected to Android Auto and concerns Speaker or Earpiece --- .../notifications/NotificationsManager.kt | 2 +- .../telecom/TelecomCallControlCallback.kt | 28 ++++++++++++++++--- .../java/org/linphone/utils/LinphoneUtils.kt | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 93a0b3299..8b9fe3126 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -1124,7 +1124,7 @@ class NotificationsManager } Log.i( - "Creating notification for [${if (isIncoming) "incoming" else "outgoing"}] [${if (isConference) "conference" else "call"}] with video [${if (isVideo) "enabled" else "disabled"}] on channel [$channel]" + "Creating notification for ${if (isIncoming) "[incoming] " else ""}[${if (isConference) "conference" else "call"}] with video [${if (isVideo) "enabled" else "disabled"}] on channel [$channel]" ) val builder = NotificationCompat.Builder( diff --git a/app/src/main/java/org/linphone/telecom/TelecomCallControlCallback.kt b/app/src/main/java/org/linphone/telecom/TelecomCallControlCallback.kt index 1addc4c6b..6d551839d 100644 --- a/app/src/main/java/org/linphone/telecom/TelecomCallControlCallback.kt +++ b/app/src/main/java/org/linphone/telecom/TelecomCallControlCallback.kt @@ -31,6 +31,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.core.AudioDevice import org.linphone.core.Call import org.linphone.core.CallListenerStub @@ -51,6 +52,7 @@ class TelecomCallControlCallback( private var availableEndpoints: List = arrayListOf() private var currentEndpoint = CallEndpointCompat.TYPE_UNKNOWN + private var endpointUpdateRequestFromLinphone: Boolean = false private val callListener = object : CallListenerStub() { @WorkerThread @@ -65,9 +67,14 @@ class TelecomCallControlCallback( CallAttributesCompat.Companion.CALL_TYPE_AUDIO_CALL } scope.launch { - Log.i("$TAG Answering ${if (isVideo) "video" else "audio"} call") + Log.i("$TAG Answering [${if (isVideo) "video" else "audio"}] call") callControl.answer(type) } + + if (isVideo && corePreferences.routeAudioToSpeakerWhenVideoIsEnabled) { + Log.i("$TAG Answering video call, routing audio to speaker") + AudioUtils.routeAudioToSpeaker(call) + } } else { scope.launch { Log.i("$TAG Setting call active") @@ -156,11 +163,23 @@ class TelecomCallControlCallback( }.launchIn(scope) callControl.currentCallEndpoint.onEach { endpoint -> - Log.i("$TAG We're asked to use [${endpoint.name}] audio endpoint") + val type = endpoint.type + currentEndpoint = type + if (endpointUpdateRequestFromLinphone) { + Log.i("$TAG Linphone requests to use [${endpoint.name}] audio endpoint with type [$type]") + } else { + Log.i("$TAG Android requests us to use [${endpoint.name}] audio endpoint with type [$type]") + } + + if (!endpointUpdateRequestFromLinphone && !coreContext.isConnectedToAndroidAuto && (type == CallEndpointCompat.Companion.TYPE_EARPIECE || type == CallEndpointCompat.Companion.TYPE_SPEAKER)) { + Log.w("$TAG Device isn't connected to Android Auto, do not follow system request to change audio endpoint to either earpiece or speaker") + return@onEach + } + // Change audio route in SDK, this way the usual listener will trigger // and we'll be able to update the UI accordingly val route = arrayListOf() - when (endpoint.type) { + when (type) { CallEndpointCompat.Companion.TYPE_EARPIECE -> { route.add(AudioDevice.Type.Earpiece) } @@ -176,7 +195,6 @@ class TelecomCallControlCallback( } } if (route.isNotEmpty()) { - currentEndpoint = endpoint.type coreContext.postOnCoreThread { if (!AudioUtils.applyAudioRouteChangeInLinphone(call, route)) { Log.w("$TAG Failed to apply audio route change, trying again in 200ms") @@ -186,6 +204,7 @@ class TelecomCallControlCallback( } } } + endpointUpdateRequestFromLinphone = false }.launchIn(scope) callControl.isMuted.onEach { muted -> @@ -215,6 +234,7 @@ class TelecomCallControlCallback( } fun applyAudioRouteToCallWithId(routes: List): Boolean { + endpointUpdateRequestFromLinphone = true Log.i("$TAG Looking for audio endpoint with type [${routes.first()}]") var wiredHeadsetFound = false diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index 4a3e15724..fe594e7fd 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -231,7 +231,7 @@ class LinphoneUtils { val isIncoming = isCallIncoming(call.state) return if (isConference || getConferenceInfoIfAny(call) != null) { true - } else if (isIncoming) { + } else if (isIncoming || call.state == Call.State.Connected) { // In connected state call.currentParams.isVideoEnabled will return false... call.remoteParams?.isVideoEnabled == true && call.remoteParams?.videoDirection != MediaDirection.Inactive } else { call.currentParams.isVideoEnabled && call.currentParams.videoDirection != MediaDirection.Inactive