From 45e86b12a2a1042c50bbd568c3e22c4c733a4a85 Mon Sep 17 00:00:00 2001 From: Yacine Rezgui Date: Thu, 16 Jul 2026 22:08:13 +0000 Subject: [PATCH] Fix audio dropping issues in Jetpack Telecom integration - Replaced `setActive()` with `answer(callType)` for incoming calls in `TelecomCallController`'s `Activate` command block, as Jetpack Telecom requires incoming calls to be explicitly answered. - Enforced waiting for a successful `CallControlResult.Success` before dispatching `AudioManagerCommand.Start` to the `ActiveCallManager`, ensuring that the WebRTC audio engine does not begin recording or playing before Telecom has actually initialized the active media route. --- .../service/webrtc/TelecomCallController.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/TelecomCallController.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/TelecomCallController.kt index 02567849620..4510cac78d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/TelecomCallController.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/TelecomCallController.kt @@ -7,6 +7,7 @@ import android.telecom.DisconnectCause import androidx.annotation.RequiresApi import androidx.core.app.NotificationManagerCompat import androidx.core.telecom.CallAttributesCompat +import androidx.core.telecom.CallControlResult import androidx.core.telecom.CallEndpointCompat import androidx.core.telecom.CallsManager import kotlinx.coroutines.channels.Channel @@ -21,6 +22,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder +import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCommand import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager sealed class TelecomCommand { @@ -179,8 +181,17 @@ class TelecomCallController( for (command in commandChannel) { when (command) { is TelecomCommand.Activate -> { - val result = setActive() - Log.i(TAG, "setActive result: $result") + val result = if (isOutgoing) { + setActive() + } else { + val callType = if (isVideoCall) CallAttributesCompat.CALL_TYPE_VIDEO_CALL else CallAttributesCompat.CALL_TYPE_AUDIO_CALL + answer(callType) + } + Log.i(TAG, "activate result: $result") + if (result is CallControlResult.Success) { + ActiveCallManager.sendAudioManagerCommand(context, AudioManagerCommand.Start()) + Log.i(TAG, "AudioManagerCommand.Start fired for callId=$callId recipientId=$recipientId") + } needToResetAudioRoute = false } is TelecomCommand.Disconnect -> {