Keep cancelled media preparation inside the native teardown barrier
This commit is contained in:
1 parent
ca7b23909b
commit
aefca81444
3 files changed
+18
-1
No files matched your search
@@ -73,6 +73,10 @@ object NativeLib {
|
||||
RadioCallController.reset()
|
||||
StreamController.reset(); CallController.reset(); ChatApplication.instance.avatars.stop(); ChatApplication.instance.memberFiles.cancel()
|
||||
CallService.requireReleased() // Не останавливать native при неподтверждённой очистке его media-владельца.
|
||||
check(!CallController.blocksMedia()) {
|
||||
LogManager.addLog("ERROR", "Call", "Core teardown blocked: call media preparation still running")
|
||||
"Call media preparation still running"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -105,5 +105,5 @@ class RadioAudioEngine {
|
||||
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() {} }
|
||||
object MediaAudioController { var beforeIdle: () -> Unit = {}; fun awaitIdle() { beforeIdle() } }
|
||||
enum class MediaAudioProfile { AUTO, PHONE, WIRED, BLUETOOTH }
|
||||
+13
@@ -13,6 +13,7 @@ import com.utun.chat.ChatApplication
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -30,6 +31,7 @@ class CallServiceLifecycleTest {
|
||||
private lateinit var context: Context
|
||||
private val dispatcher = StandardTestDispatcher()
|
||||
private val services = mutableListOf<CallService>()
|
||||
private val gates = mutableListOf<CountDownLatch>()
|
||||
private val main get() = Looper.getMainLooper()
|
||||
private val power get() = requireNotNull(context.powerManager)
|
||||
private val manager get() = requireNotNull(context.notificationManager)
|
||||
@@ -41,6 +43,7 @@ class CallServiceLifecycleTest {
|
||||
NativeLib.ready = true; NativeLib.failActivityRequest = false; NativeLib.acceptActivityRequest = true
|
||||
AppLanguage.failText = false; AppLanguage.language = "en"; NotificationCompat.failBuild = false
|
||||
Handler.rejectImmediate = false; Handler.rejectDelayed = false; PendingIntent.reset()
|
||||
MediaAudioController.beforeIdle = {}
|
||||
CallVideoEngine.failCreate = false; CallVideoEngine.created.clear()
|
||||
CallController.reset(); RadioAudioEngine.instance().activeGroup.value = null; RadioAudioEngine.instance().restored.clear()
|
||||
NativeLib.callCommands.clear(); LogManager.entries.clear(); LogManager.console = true
|
||||
@@ -48,6 +51,7 @@ class CallServiceLifecycleTest {
|
||||
}
|
||||
|
||||
@After fun release() {
|
||||
gates.forEach { it.countDown() }; MediaAudioController.beforeIdle = {}
|
||||
NativeLib.failActivityRequest = false
|
||||
Handler.rejectImmediate = false; Handler.rejectDelayed = false
|
||||
AppLanguage.failText = false; NotificationCompat.failBuild = false; CallVideoEngine.failCreate = false
|
||||
@@ -335,4 +339,13 @@ class CallServiceLifecycleTest {
|
||||
assertEquals(CallPhase.ENDED, state?.phase); assertTrue(service.stops > 0)
|
||||
assertFalse(manager.active.containsKey(1002)); diagnostic("start failed operation=wake lock")
|
||||
}
|
||||
|
||||
@Test fun aCancelledCallStillBlocksCoreTeardownUntilMediaPreparationLeavesNative() {
|
||||
val entered = CountDownLatch(1); val gate = CountDownLatch(1).also { gates.add(it) }
|
||||
MediaAudioController.beforeIdle = { entered.countDown(); check(gate.await(5, TimeUnit.SECONDS)) }
|
||||
request(); dispatcher.scheduler.runCurrent(); assertTrue(entered.await(5, TimeUnit.SECONDS))
|
||||
CallController.reset()
|
||||
assertNull(state); assertFalse(CallService.cleanupPending()); assertTrue(CallController.blocksMedia())
|
||||
gate.countDown(); await("cancelled media preparation finished") { !CallController.blocksMedia() }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user