Contain call notification and route persistence failures
This commit is contained in:
1 parent
7e328b3908
commit
236dbd3e84
3 files changed
+23
-7
No files matched your search
@@ -32,6 +32,8 @@ data class OutgoingCallRequest(val channelId: String, val peerNodeId: Long, val
|
||||
* Единственный владелец звонковой сессии в процессе приложения. Все операции — main thread.
|
||||
* Сервис владеет аудио и wake lock, ядро — сигналингом, ViewModel только читает StateFlow.
|
||||
* События поступают напрямую из AppEventHandler без replay старых звонков новым подписчикам.
|
||||
* Start/accept ждут освобождения чужих media и успешного enqueue; hangup/decline при отказе очереди
|
||||
* повторяются независимо от UI/audio cleanup. Core reset отменяет такие повторы до остановки worker.
|
||||
*/
|
||||
object CallController : TelecomCallManager.Listener {
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||
@@ -229,8 +231,9 @@ object CallController : TelecomCallManager.Listener {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
LogManager.addLog("ERROR", "Call", "media release failed id=$id: $e")
|
||||
Toast.makeText(ChatApplication.instance, R.string.call_media_stop_failed, Toast.LENGTH_LONG).show()
|
||||
end(id, 7)
|
||||
try { Toast.makeText(ChatApplication.instance, R.string.call_media_stop_failed, Toast.LENGTH_LONG).show() }
|
||||
catch (notify: Exception) { LogManager.addLog("ERROR", "Call", "Cannot show media release failure id=$id: $notify") }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,17 +385,17 @@ object CallController : TelecomCallManager.Listener {
|
||||
radioToRestore = null
|
||||
RadioAudioEngine.instance().restoreAfterCall(group)
|
||||
}
|
||||
if (reason == 8 && st.phase != CallPhase.INCOMING && st.phase != CallPhase.PENDING_INCOMING) {
|
||||
if (reason == 8 && st.phase != CallPhase.INCOMING && st.phase != CallPhase.PENDING_INCOMING) try {
|
||||
val app = ChatApplication.instance
|
||||
val text = AppLanguage.text(R.string.phone_busy_warning)
|
||||
if (activityVisible) Toast.makeText(app, text, Toast.LENGTH_LONG).show()
|
||||
else try {
|
||||
else {
|
||||
requireNotNull(app.getSystemService(NotificationManager::class.java)) { "notification manager unavailable" }.notify(1003,
|
||||
NotificationCompat.Builder(app, IncomingCallManager.CHANNEL_CALL)
|
||||
.setSmallIcon(android.R.drawable.ic_dialog_info).setContentTitle(st.peerName)
|
||||
.setContentText(text).setAutoCancel(true).build())
|
||||
} catch (e: Exception) { LogManager.addLog("ERROR", "Call", "Busy outcome notification failed id=$id: $e") }
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) { LogManager.addLog("ERROR", "Call", "Busy outcome notification failed id=$id: $e") }
|
||||
scope.launch {
|
||||
delay(2500)
|
||||
if (_state.value?.callId == id && _state.value?.phase == CallPhase.ENDED) _state.value = null
|
||||
@@ -429,10 +432,21 @@ object CallController : TelecomCallManager.Listener {
|
||||
|
||||
fun setRoute(route: AudioRoute) {
|
||||
checkMain()
|
||||
if (_state.value?.phase != CallPhase.ACTIVE || service == null) {
|
||||
LogManager.addLog("WARN", "Call", "route ignored outside active call route=$route phase=${_state.value?.phase}")
|
||||
return
|
||||
}
|
||||
videoSpeakerPending = false // Явный выбор пользователя отменяет ожидающее автоматическое переключение.
|
||||
service?.audio?.router?.setRoute(route)
|
||||
syncProximity()
|
||||
scope.launch { ChatApplication.instance.configProvider.setCallAudioRoute(route) }
|
||||
scope.launch {
|
||||
try { ChatApplication.instance.configProvider.setCallAudioRoute(route) }
|
||||
catch (e: CancellationException) { throw e }
|
||||
catch (e: Exception) {
|
||||
LogManager.addLog("ERROR", "Call", "Cannot save preferred route=$route: $e")
|
||||
Toast.makeText(ChatApplication.instance, R.string.call_route_save_failed, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun routeChanged(route: AudioRoute, headset: Boolean) {
|
||||
@@ -466,7 +480,7 @@ object CallController : TelecomCallManager.Listener {
|
||||
audio.router.fallbackRoute = AudioRoute.SPEAKER
|
||||
audio.router.setRoute(AudioRoute.SPEAKER, automatic = true)
|
||||
syncProximity()
|
||||
LogManager.addLog("INFO", "call", "video speaker enabled after confirmed FAR id=${st.callId}")
|
||||
LogManager.addLog("INFO", "call", "video speaker requested after confirmed FAR id=${st.callId}")
|
||||
}
|
||||
|
||||
/** Только живые события ядра, сериализованные AppEventHandler на main thread. */
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<string name="call_incoming_stop_media">При принятии звонка рация выключится, трансляция или её просмотр завершится. После звонка рация включится снова.</string>
|
||||
<string name="call_preparing_audio">Освобождаем аудиоустройства…</string>
|
||||
<string name="call_media_stop_failed">Не удалось освободить аудиоустройства для звонка.</string>
|
||||
<string name="call_route_save_failed">Не удалось сохранить предпочтительное аудиоустройство звонков.</string>
|
||||
<string name="call_media_busy">Во время звонка звук рации недоступен.</string>
|
||||
<string name="call_video_settings">Настройки видео</string>
|
||||
<string name="call_video_unavailable">Не удалось включить передачу видео</string>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<string name="call_incoming_stop_media">Answering will turn off the radio and end the broadcast or stream playback. The radio will turn back on after the call.</string>
|
||||
<string name="call_preparing_audio">Releasing audio devices…</string>
|
||||
<string name="call_media_stop_failed">Could not release the audio devices for the call.</string>
|
||||
<string name="call_route_save_failed">Could not save the preferred call audio device.</string>
|
||||
<string name="call_media_busy">Radio audio is unavailable during a call.</string>
|
||||
<string name="call_video_settings">Video settings</string>
|
||||
<string name="call_video_unavailable">Unable to send video</string>
|
||||
|
||||
Reference in new issue
Block a user