Retain the media teardown barrier while Telecom cleanup is pending

This commit is contained in:
evgeny committed 2026-10-29 13:34:25 +01:00
1 parent e7a03f33fb
commit b71f992a45
3 files changed
+18 -4

No files matched your search

@@ -43,7 +43,7 @@ object CallController : TelecomCallManager.Listener {
/** Подготовка, разговор и неподтверждённый cleanup сервиса запрещают запуск чужого media.
* Predicate читается также media workers; CallService публикует retained-владельца через volatile. */
fun blocksMedia(): Boolean = CallService.cleanupPending() || mediaPreparation?.isActive == true || _state.value?.let {
fun blocksMedia(): Boolean = CallService.cleanupPending() || TelecomCallManager.cleanupPending() || mediaPreparation?.isActive == true || _state.value?.let {
it.preparing || it.phase == CallPhase.OUTGOING || it.phase == CallPhase.RINGING ||
it.phase == CallPhase.WAIT_DECISION || it.phase == CallPhase.ACTIVE
} == true
@@ -52,8 +52,8 @@ class CallService : Service() {
/** На main повторить незавершённую очистку. Ошибка запрещает заменять владельца или останавливать ядро. */
fun requireReleased() {
checkMain()
val previous = pendingCleanup ?: return
previous.shutdown()
pendingCleanup?.shutdown()
TelecomCallManager.requireReleased()
check(pendingCleanup == null) {
val message = "Call service cleanup still pending id=${previous.callId}"
LogManager.addLog("ERROR", "CallService", message)
@@ -50,6 +50,7 @@ object TelecomCallManager {
private val disconnected = mutableSetOf<UtunConnection>()
private var cleanupQueued = false
private var cleanupDelay = 250L
@Volatile private var retiring = false
private val cleanupRetry = Runnable { cleanupQueued = false; cleanupConnections() }
@Volatile private var phoneAccountHandle: PhoneAccountHandle? = null
@@ -84,6 +85,17 @@ object TelecomCallManager {
fun isReady(): Boolean = ready
/** Не передавать глобальную аудиополитику другому media/core, пока SDK удерживает старый Connection. */
fun cleanupPending(): Boolean = retiring
fun requireReleased() {
checkMain(); cleanupConnections()
check(!retiring) {
LogManager.addLog("ERROR", TAG, "Telecom cleanup still pending connections=${closing.size}")
"Telecom connection cleanup pending"
}
}
/** Создать исходящий вызов в Telecom. Возвращает false, если Telecom недоступен. */
fun placeCall(callId: Long, peerNodeId: Long, displayName: String): Boolean {
val tm = telecomManager() ?: return false
@@ -202,6 +214,7 @@ object TelecomCallManager {
private fun retire(callId: Long, conn: UtunConnection, reason: Int) {
closing.putIfAbsent(conn, Closing(callId, reason, conn in disconnected))
retiring = true
reasons.remove(conn); disconnected.remove(conn); cleanupConnections()
}
@@ -214,7 +227,8 @@ object TelecomCallManager {
LogManager.addLog("ERROR", TAG, "connection destroy failed id=${owner.id}; retained: $e")
}
}
if (closing.isEmpty()) { mainHandler.removeCallbacks(cleanupRetry); cleanupQueued = false; cleanupDelay = 250; return }
retiring = closing.isNotEmpty()
if (!retiring) { mainHandler.removeCallbacks(cleanupRetry); cleanupQueued = false; cleanupDelay = 250; return }
if (!cleanupQueued) {
cleanupQueued = mainHandler.postDelayed(cleanupRetry, cleanupDelay)
if (!cleanupQueued) LogManager.addLog("ERROR", TAG, "connection cleanup retry rejected count=${closing.size}; owners retained")