From a7c67ee488a39b260a7af2e1189367de0ef3bfb8 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 15 Oct 2026 03:11:45 +0200 Subject: [PATCH] Activate Telecom before call audio and adopt late connections --- .../main/java/com/utun/chat/data/CallController.kt | 11 ++++++++--- .../java/com/utun/chat/data/TelecomCallManager.kt | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallController.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallController.kt index 4fddb772..db64f2e8 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallController.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallController.kt @@ -269,7 +269,6 @@ object CallController : TelecomCallManager.Listener { videoSpeakerPending = false // Явный выбор пользователя отменяет ожидающее автоматическое переключение. service?.audio?.router?.setRoute(route) syncProximity() - _state.value?.let { TelecomCallManager.setRoute(it.callId, route) } scope.launch { ChatApplication.instance.configProvider.setCallAudioRoute(route) } } @@ -281,6 +280,12 @@ object CallController : TelecomCallManager.Listener { service?.audio?.syncAecForRoute(route) } + override fun onConnectionAvailable(callId: Long, connection: UtunConnection) { + checkMain() + if (_state.value?.callId == callId && _state.value?.phase == CallPhase.ACTIVE) + service?.audio?.bindTelecom(connection) + } + private fun syncProximity() { if (_state.value?.phase == CallPhase.ACTIVE && _route.value == AudioRoute.EARPIECE && (!_videoActive.value || videoSpeakerPending)) proximity.start() else proximity.stop() @@ -295,7 +300,6 @@ object CallController : TelecomCallManager.Listener { // Сохранённый маршрут аудиозвонков не меняем; автоследование за гарнитурой сохраняется. audio.router.fallbackRoute = AudioRoute.SPEAKER audio.router.setRoute(AudioRoute.SPEAKER, automatic = true) - TelecomCallManager.setRoute(st.callId, AudioRoute.SPEAKER) syncProximity() LogManager.addLog("INFO", "call", "video speaker enabled after confirmed FAR id=${st.callId}") } @@ -361,6 +365,8 @@ object CallController : TelecomCallManager.Listener { // Убираем гудки до переключения режима и запуска звонкового аудиотракта. CallRingback.stop() IncomingCallManager.stopRinging() + // Telecom переводит аудиополитику в VoIP до создания AudioRecord/AudioTrack. + TelecomCallManager.setActive(id) val owner = service if (owner == null || !owner.startAudio(id)) { LogManager.addLog("ERROR", "Call", "accepted without working audio/service id=$id") @@ -369,7 +375,6 @@ object CallController : TelecomCallManager.Listener { } accepting = false _video.value = owner.video - TelecomCallManager.setActive(id) _state.value = st.copy(phase = CallPhase.ACTIVE, durationSeconds = 0, startedAtElapsedRealtime = SystemClock.elapsedRealtime()) owner.audio.router.onChanged = { route, headset -> routeChanged(route, headset) } _earpiece.value = owner.audio.router.hasEarpiece diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/TelecomCallManager.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/TelecomCallManager.kt index 95b68f37..2915ad9a 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/TelecomCallManager.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/TelecomCallManager.kt @@ -29,6 +29,7 @@ object TelecomCallManager { fun onAnswer(callId: Long) fun onReject(callId: Long) fun onDisconnect(callId: Long) + fun onConnectionAvailable(callId: Long, connection: UtunConnection) } const val EXTRA_CALL_ID = "com.utun.chat.extra.CALL_ID" @@ -137,6 +138,7 @@ object TelecomCallManager { else -> conn.setDialing() } LogManager.addLog("INFO", TAG, "connection registered id=$callId phase=${st.phase}") + listener?.onConnectionAvailable(callId, conn) } fun connectionFor(callId: Long): UtunConnection? = connections[callId] @@ -159,8 +161,6 @@ object TelecomCallManager { fun setDisconnected(callId: Long, reason: Int) = connections[callId]?.markDisconnected(reason) - fun setRoute(callId: Long, route: AudioRoute) = connections[callId]?.routeTo(route) - fun removeConnection(callId: Long) { connections.remove(callId)?.destroy() LogManager.addLog("DEBUG", TAG, "connection removed id=0x%016x".format(callId))