diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallAudioRouter.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallAudioRouter.kt index f17ebd75..f7f01d23 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallAudioRouter.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallAudioRouter.kt @@ -52,8 +52,7 @@ class CallAudioRouter { /** Куда откатываться при потере гарнитуры (звонок — EARPIECE, рация — SPEAKER). */ @Volatile var fallbackRoute = AudioRoute.EARPIECE - /** Автоматически следовать за гарнитурой: появилась → HEADSET, исчезла → fallbackRoute. - * Ручной setRoute() сбрасывает в false. */ + /** Следовать за подключением/отключением гарнитуры. Ручной выбор действует до следующего изменения доступности. */ @Volatile var autoHeadset = false private set @@ -143,7 +142,7 @@ class CallAudioRouter { applyRoute(desiredRoute) val applyMs = SystemClock.elapsedRealtime() - stageAt stageAt = SystemClock.elapsedRealtime() - refresh() + refresh(forceAuto = true) val refreshMs = SystemClock.elapsedRealtime() - stageAt LogManager.addLog("INFO", "CallAudioRouter", "started totalMs=${SystemClock.elapsedRealtime() - startedAt} callbackMs=$callbackMs btProfileMs=$btProfileMs " + @@ -178,12 +177,12 @@ class CallAudioRouter { LogManager.addLog("WARN", "CallAudioRouter", "setRoute HEADSET rejected: no headset available") return } - if (!automatic) autoHeadset = false val preferenceChanged = preferWiredHeadset != preferWired preferWiredHeadset = preferWired if (desiredRoute == r && route == r && !preferenceChanged) return desiredRoute = r preferredRoute = r + if (!automatic && r != AudioRoute.HEADSET) fallbackRoute = r applyRoute(r) LogManager.addLog("INFO", "CallAudioRouter", "requested route=$r actual=$route headsetAvailable=$headsetAvailable automatic=$automatic") if (telecom == null) onChanged?.invoke(route, headsetAvailable) @@ -195,7 +194,7 @@ class CallAudioRouter { LogManager.addLog("INFO", "CallAudioRouter", "preferredRoute -> $r") } - /** Включить/выключить автоследование за гарнитурой (рация включает, звонок — нет). */ + /** Включить/выключить автоследование; reapply немедленно применяет авторежим к текущим устройствам. */ fun setAutoHeadset(enabled: Boolean) { val resetPreference = enabled && preferWiredHeadset autoHeadset = enabled @@ -208,7 +207,7 @@ class CallAudioRouter { fun reapply() { if (!started) return devices = am.getDevices(AudioManager.GET_DEVICES_ALL) - refresh() + refresh(forceAuto = true) } /* ── применение маршрута ── */ @@ -341,7 +340,7 @@ class CallAudioRouter { refresh() } - private fun refresh() { + private fun refresh(forceAuto: Boolean = false) { val now = isHeadsetConnected() val prev = headsetAvailable headsetAvailable = now @@ -349,14 +348,14 @@ class CallAudioRouter { LogManager.addLog("INFO", "CallAudioRouter", "headsetAvailable -> $now") } /* авторежим: маршрут следует за гарнитурой */ - if (autoHeadset) { + if (autoHeadset && (forceAuto || now != prev)) { val want = if (now) AudioRoute.HEADSET else fallbackRoute if (desiredRoute != want) { desiredRoute = want applyRoute(want) LogManager.addLog("INFO", "CallAudioRouter", "auto route -> $want") } - } else { + } else if (!autoHeadset) { /* гарнитуру отключили — откатываемся на fallback-маршрут */ if (!now && desiredRoute == AudioRoute.HEADSET) { desiredRoute = fallbackRoute diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/RadioAudioEngine.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/RadioAudioEngine.kt index 65758da1..f7f1119e 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/RadioAudioEngine.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/RadioAudioEngine.kt @@ -131,7 +131,10 @@ class RadioAudioEngine { fun headsetAvailable(): Boolean = router.headsetAvailable /** Ручной выбор выхода (отключает автоследование за гарнитурой). */ - fun setRoute(r: AudioRoute, preferWired: Boolean = false) = router.setRoute(r, preferWired) + fun setRoute(r: AudioRoute, preferWired: Boolean = false) { + router.setAutoHeadset(false) + router.setRoute(r, preferWired) + } /** Начать прослушивание канала (переключатель рации вкл). * Тяжёлая инициализация аудио выполняется на io-потоке, не блокируя main. */