Reject fresh radio and publisher owners during core cleanup
This commit is contained in:
1 parent
044ff034a6
commit
0568d263e0
3 files changed
+24
-5
No files matched your search
@@ -59,7 +59,7 @@ object StreamController {
|
||||
check(Looper.myLooper() == Looper.getMainLooper())
|
||||
if (mutable.value?.ongoing == true) { LogManager.addLog("WARN", "stream", "publisher already owned"); return }
|
||||
val id = nextId()
|
||||
if (!NativeLib.isReady() || group == 0L || CallController.blocksMedia() || CallController.state.value?.ongoing == true ||
|
||||
if (NativeLib.isCoreStopping() || !NativeLib.isReady() || group == 0L || CallController.blocksMedia() || CallController.state.value?.ongoing == true ||
|
||||
NativeLib.voiceIsActive()) {
|
||||
LogManager.addLog("WARN", "stream", "start rejected: core/call/voice busy group=$group")
|
||||
mutable.value = StreamState(id, group, StreamPhase.FAILED, R.string.stream_resources_busy); return
|
||||
|
||||
+12
-2
@@ -29,14 +29,14 @@ class StreamServiceLifecycleTest {
|
||||
assertSame(main, Looper.myLooper()); Dispatchers.setMain(dispatcher)
|
||||
context = Context().also { ChatApplication.instance = it }
|
||||
Handler.rejectImmediate = false; Handler.rejectDelayed = false; PendingIntent.reset(); NotificationCompat.failBuild = false
|
||||
NativeLib.ready = true; NativeLib.voiceActive = false; NativeLib.streamFailures = emptySet()
|
||||
NativeLib.ready = true; NativeLib.coreStopping = false; NativeLib.voiceActive = false; NativeLib.streamFailures = emptySet()
|
||||
NativeLib.streamStops.clear(); NativeLib.streamEvents.clear(); NativeLib.streamStats = null
|
||||
StreamCaptureEngine.nextFailures = emptySet(); StreamCaptureEngine.created.clear(); AppLanguage.failText = false
|
||||
CallController.reset(); StreamController.reset(); main.dispatchAll()
|
||||
}
|
||||
@After fun release() {
|
||||
Handler.rejectImmediate = false; Handler.rejectDelayed = false; NativeLib.streamFailures = emptySet()
|
||||
NativeLib.ready = true; NativeLib.voiceActive = false; AppLanguage.failText = false; NotificationCompat.failBuild = false
|
||||
NativeLib.ready = true; NativeLib.coreStopping = false; NativeLib.voiceActive = false; AppLanguage.failText = false; NotificationCompat.failBuild = false
|
||||
StreamCaptureEngine.created.forEach { it.failures = emptySet() }
|
||||
context.powerManager?.let { power -> power.failures = emptySet(); power.locks.forEach { it.failures = emptySet() } }
|
||||
context.notificationManager?.failures = emptySet()
|
||||
@@ -66,6 +66,16 @@ class StreamServiceLifecycleTest {
|
||||
StreamController.requireReleased()
|
||||
}
|
||||
|
||||
@Test fun coreCleanupRejectsNewPublisherBeforeForegroundOrCameraAcquisition() {
|
||||
NativeLib.coreStopping = true
|
||||
StreamController.start(7, StreamCaptureConfig(), true)
|
||||
assertEquals(StreamPhase.FAILED, state.phase)
|
||||
assertFalse(StreamController.capturing)
|
||||
assertTrue(context.serviceStarts.isEmpty())
|
||||
assertTrue(StreamCaptureEngine.created.isEmpty())
|
||||
StreamController.requireReleased()
|
||||
}
|
||||
|
||||
@Test fun nullForegroundRequestFailsWithoutLeavingAStartingPublisher() {
|
||||
context.acceptServiceStart = false; request()
|
||||
assertEquals(StreamPhase.FAILED, state.phase); assertFalse(StreamController.capturing)
|
||||
|
||||
+11
-2
@@ -30,7 +30,7 @@ class RadioAudioLifecycleTest {
|
||||
AudioManager.shared = AudioManager(); CallController.blocked = false
|
||||
AndroidMicrophoneCapture.reset(); AudioTrack.created.clear(); AudioTrack.nextFailures = emptySet(); AudioTrack.minimumBuffer = 1920
|
||||
Handler.rejectDelayed = false; Handler.rejectImmediate = false
|
||||
NativeLib.radioFailures = emptySet(); NativeLib.radioCommands.clear()
|
||||
NativeLib.coreStopping = false; NativeLib.radioFailures = emptySet(); NativeLib.radioCommands.clear()
|
||||
LogManager.entries.clear(); LogManager.console = true
|
||||
engine = RadioAudioEngine()
|
||||
io = RadioAudioEngine::class.java.getDeclaredField("io").apply { isAccessible = true }.get(engine) as ExecutorService
|
||||
@@ -39,7 +39,7 @@ class RadioAudioLifecycleTest {
|
||||
@After fun release() {
|
||||
context.receiverFailures = emptySet(); context.failPowerService = false; context.configProvider.failRadioSettings = false
|
||||
AudioTrack.created.forEach { it.failures = emptySet() }; AudioTrack.nextFailures = emptySet(); AudioTrack.minimumBuffer = 1920
|
||||
NativeLib.radioFailures = emptySet(); Handler.rejectDelayed = false; Handler.rejectImmediate = false
|
||||
NativeLib.coreStopping = false; NativeLib.radioFailures = emptySet(); Handler.rejectDelayed = false; Handler.rejectImmediate = false
|
||||
if (!io.isShutdown) {
|
||||
try { engine.stop().get(5, TimeUnit.SECONDS) } catch (e: ExecutionException) {
|
||||
if (e.cause !is IllegalArgumentException || context.receivers.isNotEmpty()) throw e
|
||||
@@ -80,6 +80,15 @@ class RadioAudioLifecycleTest {
|
||||
assertTrue("radio state did not settle", condition())
|
||||
}
|
||||
|
||||
@Test fun coreCleanupRejectsNewRadioBeforeAcquiringAudioDevices() {
|
||||
NativeLib.coreStopping = true
|
||||
start(expected = false)
|
||||
assertFalse(engine.isActive())
|
||||
assertTrue(AudioTrack.created.isEmpty())
|
||||
assertTrue(AndroidMicrophoneCapture.opened.isEmpty())
|
||||
diagnostic("core cleanup")
|
||||
}
|
||||
|
||||
@Test fun receiverCleanupFailureDoesNotSkipCaptureOutputOrNativeStopAndCanBeRetried() {
|
||||
start(); assertTrue(engine.talkBegin()); drain(); await { NativeLib.radioTransmitting() }
|
||||
val track = AudioTrack.created.single()
|
||||
|
||||
Reference in new issue
Block a user