Await Telecom cleanup before restoring the previous radio session
This commit is contained in:
1 parent
870f1b5914
commit
e81138e3d1
3 files changed
+16
-8
No files matched your search
@@ -334,6 +334,7 @@ object CallController : TelecomCallManager.Listener {
|
||||
scope.launch {
|
||||
serviceReleased?.await()
|
||||
released?.join()
|
||||
TelecomCallManager.awaitReleased()
|
||||
if (!coreReady || !NativeLib.isReady() || blocksMedia()) return@launch
|
||||
val group = radioToRestore ?: return@launch
|
||||
radioToRestore = null
|
||||
|
||||
@@ -11,6 +11,8 @@ import android.telecom.PhoneAccountHandle
|
||||
import android.telecom.TelecomManager
|
||||
import com.utun.chat.ChatApplication
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
||||
/**
|
||||
* Мост между жизненным циклом P2P-звонка (CallController) и Telecom.
|
||||
@@ -50,7 +52,7 @@ object TelecomCallManager {
|
||||
private val disconnected = mutableSetOf<UtunConnection>()
|
||||
private var cleanupQueued = false
|
||||
private var cleanupDelay = 250L
|
||||
@Volatile private var retiring = false
|
||||
private val retiring = MutableStateFlow(false)
|
||||
private val cleanupRetry = Runnable { cleanupQueued = false; cleanupConnections() }
|
||||
|
||||
@Volatile private var phoneAccountHandle: PhoneAccountHandle? = null
|
||||
@@ -85,11 +87,14 @@ object TelecomCallManager {
|
||||
fun isReady(): Boolean = ready
|
||||
|
||||
/** Не передавать глобальную аудиополитику другому media/core, пока SDK удерживает старый Connection. */
|
||||
fun cleanupPending(): Boolean = retiring
|
||||
fun cleanupPending(): Boolean = retiring.value
|
||||
|
||||
/** Ожидание не отменяет SDK cleanup; восстановление рации ждёт подтверждённого освобождения Telecom. */
|
||||
suspend fun awaitReleased() { retiring.first { !it } }
|
||||
|
||||
fun requireReleased() {
|
||||
checkMain(); cleanupConnections()
|
||||
check(!retiring) {
|
||||
check(!retiring.value) {
|
||||
LogManager.addLog("ERROR", TAG, "Telecom cleanup still pending connections=${closing.size}")
|
||||
"Telecom connection cleanup pending"
|
||||
}
|
||||
@@ -208,12 +213,12 @@ object TelecomCallManager {
|
||||
checkMain()
|
||||
val conn = connections.remove(callId)
|
||||
if (conn != null) retire(callId, conn, reasons[conn] ?: 0) else cleanupConnections()
|
||||
LogManager.addLog("DEBUG", TAG, "connection removal requested id=$callId pending=$retiring")
|
||||
LogManager.addLog("DEBUG", TAG, "connection removal requested id=$callId pending=${retiring.value}")
|
||||
}
|
||||
|
||||
private fun retire(callId: Long, conn: UtunConnection, reason: Int) {
|
||||
closing.putIfAbsent(conn, Closing(callId, reason, conn in disconnected))
|
||||
retiring = true
|
||||
retiring.value = true
|
||||
LogManager.addLog("DEBUG", TAG, "connection retiring id=$callId owner=${System.identityHashCode(conn)} reason=$reason")
|
||||
reasons.remove(conn); disconnected.remove(conn); cleanupConnections()
|
||||
}
|
||||
@@ -230,8 +235,8 @@ object TelecomCallManager {
|
||||
LogManager.addLog("ERROR", TAG, "connection destroy failed id=${owner.id} owner=${System.identityHashCode(conn)}; retained: $e")
|
||||
}
|
||||
}
|
||||
retiring = closing.isNotEmpty()
|
||||
if (!retiring) { mainHandler.removeCallbacks(cleanupRetry); cleanupQueued = false; cleanupDelay = 250; return }
|
||||
retiring.value = closing.isNotEmpty()
|
||||
if (!retiring.value) { 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")
|
||||
|
||||
+3
-1
@@ -63,9 +63,11 @@ class CallVideoEngine(context: Context, val id: Long) {
|
||||
}
|
||||
|
||||
object TelecomCallManager {
|
||||
var pending = false
|
||||
private val closing = MutableStateFlow(false)
|
||||
var pending: Boolean get() = closing.value; set(value) { closing.value = value }
|
||||
fun cleanupPending() = pending
|
||||
fun requireReleased() { check(!pending) { "Telecom connection cleanup pending" } }
|
||||
suspend fun awaitReleased() { closing.first { !it } }
|
||||
interface Listener {
|
||||
fun onConnectionAvailable(callId: Long, connection: UtunConnection)
|
||||
fun onAnswer(callId: Long)
|
||||
|
||||
Reference in new issue
Block a user