Control audio and video cleanup effects around the real call service controller

This commit is contained in:
evgeny committed 2026-10-29 13:34:23 +01:00
1 parent be3a2d2325
commit 15a2a7bb70
2 files changed
+109

No files matched your search

@@ -0,0 +1,108 @@
package com.utun.chat.data
import android.content.Context
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
import kotlinx.coroutines.flow.MutableStateFlow
/** Только DSP/camera/Telecom и чужие media. CallService/CallController/CoreActivity компилируются из приложения. */
object AppLanguage {
var language = "en"
var failText = false
fun context() = com.utun.chat.ChatApplication.instance
fun text(id: Int): String { check(!failText) { "language unavailable" }; return "$language:$id" }
}
class CallAudioEngine {
val router = CallAudioRouter()
var onFailure: ((Long, String) -> Unit)? = null
var failures = emptySet<String>()
var active = false
var starts = 0; var stops = 0
private var muted = false
val diagnostics: String get() { check("diagnostics" !in failures); return "host active=$active" }
fun start(id: Long): Boolean {
starts++
if ("reject" in failures) return false
active = true
check("start" !in failures) { "audio start failed after effect" }
return true
}
fun stop() {
stops++
check("stop" !in failures) { "audio stop unavailable" }
active = false
check("stop after" !in failures) { "audio stop failed after effect" }
}
fun isActive() = active
fun setMuted(value: Boolean) { muted = value }
fun isMuted() = muted
fun bindTelecom(connection: UtunConnection) {}
fun syncAecForRoute(route: AudioRoute) {}
fun outputLatency(id: Long) = CallOutputLatency()
}
data class CallVideoSettings(val enabled: Boolean = false)
data class CallVideoState(val settings: CallVideoSettings = CallVideoSettings())
class CallVideoEngine(context: Context, val id: Long) {
companion object { var failCreate = false; val created = mutableListOf<CallVideoEngine>() }
init { check(!failCreate) { "video constructor unavailable" }; created.add(this) }
var failures = emptySet<String>()
var stopped = false; var stops = 0
val state = MutableStateFlow(CallVideoState())
val display = MutableStateFlow<Any?>(null)
fun select(settings: CallVideoSettings) { state.value = CallVideoState(settings) }
fun stop() {
stops++
check("stop" !in failures) { "video stop unavailable" }
stopped = true
check("stop after" !in failures) { "video stop failed after effect" }
}
}
object TelecomCallManager {
interface Listener {
fun onConnectionAvailable(callId: Long, connection: UtunConnection)
fun onAnswer(callId: Long)
fun onReject(callId: Long)
fun onDisconnect(callId: Long)
fun onIncomingUiAllowed(callId: Long)
fun onConnectionFailed(callId: Long)
}
fun setListener(listener: Listener) {}
fun isReady() = false
fun placeCall(id: Long, peer: Long, name: String) {}
fun addIncomingCall(id: Long, peer: Long, name: String) = true
fun setActive(id: Long) {}
fun setDisconnected(id: Long, reason: Int) {}
fun removeConnection(id: Long) {}
}
class ProximityManager(context: Context) {
val near = MutableStateFlow<Boolean?>(null)
fun start() {}
fun stop() { near.value = null }
}
object RadioCallController { fun busy() = false }
object IncomingCallManager {
const val EXTRA_CALL_ID = "call_id"
const val CHANNEL_CALL = "incoming_call"
fun show(id: Long, channel: String, peer: Long) {}
fun stopRinging() {}
}
object CallRingback { fun stop() {}; fun startConnecting() {}; fun startRinging() {} }
object MicrophonePermission {
fun granted() = true
fun request(reason: String, callback: () -> Unit = {}) { callback() }
}
class RadioAudioEngine {
companion object { private val shared = RadioAudioEngine(); fun instance() = shared }
val activeGroup = MutableStateFlow<Long?>(null)
val restored = mutableListOf<Long>()
fun stopForCall(): Future<*> { activeGroup.value = null; return CompletableFuture.completedFuture(Unit) }
fun restoreAfterCall(group: Long) { restored.add(group); activeGroup.value = group }
}
data class HostMediaState(val ongoing: Boolean)
object StreamController { val state = MutableStateFlow<HostMediaState?>(null); fun stopForCall() { state.value = null } }
object StreamPlayerEngine { val viewing = MutableStateFlow(false); fun stopForCall() { viewing.value = false } }
object MediaAudioController { fun awaitIdle() {} }
@@ -8,6 +8,7 @@ class Toast private constructor(val text: String) {
const val LENGTH_LONG = 1
val shown = mutableListOf<String>()
fun makeText(context: Context, text: String, duration: Int) = Toast(text)
fun makeText(context: Context, resource: Int, duration: Int) = Toast("resource:$resource")
}
fun show() { shown.add(text) }
}