Model failed-session acknowledgement and verify live preview fallback

This commit is contained in:
evgeny committed 2026-10-29 13:34:24 +01:00
1 parent 2068774d58
commit ea121ac4e7
2 files changed
+8 -6

No files matched your search

@@ -6,6 +6,7 @@ import android.util.Size
import android.util.Range
import android.view.Surface
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.ConcurrentLinkedQueue
class CameraAccessException(val reason: Int) : Exception("camera access failure reason=$reason") {
companion object { const val CAMERA_IN_USE = 4; const val CAMERA_DISABLED = 1; const val CAMERA_DISCONNECTED = 2 }
@@ -51,6 +52,7 @@ class CameraManager {
var failures = emptySet<String>()
var nextDeviceFailures = emptySet<String>()
var nextSessionFailures = emptySet<String>()
val sessionFailures = ConcurrentLinkedQueue<Set<String>>()
var autoOpened = true
var autoClosed = true
var autoConfigured = true
@@ -86,7 +88,7 @@ class CameraDevice(val id: String, private val owner: CameraManager, private val
fun createCaptureRequest(type: Int): CaptureRequest.Builder { check("request" !in failures); return CaptureRequest.Builder() }
fun createCaptureSession(targets: List<Surface>, callback: CameraCaptureSession.StateCallback, delivery: Handler) {
check("session" !in failures) { "session creation failed" }
val session = CameraCaptureSession(this, callback, delivery).also { it.failures = owner.nextSessionFailures }
val session = CameraCaptureSession(this, callback, delivery).also { it.failures = owner.sessionFailures.poll() ?: owner.nextSessionFailures }
owner.sessions.add(session)
if (owner.autoConfigured) delivery.post {
if ("configure" in session.failures || "session after" in failures) session.failConfiguration()
@@ -168,17 +168,17 @@ class CallVideoEngineLifecycleTest {
val engine = engine()
val target = engine.preview.attach(android.graphics.SurfaceTexture(1))
try {
manager.nextSessionFailures = setOf("configure")
manager.sessionFailures.add(setOf("configure"))
engine.select(engine.state.value.settings.copy(enabled = true))
await("preview configuration failure reported") { engine.preview.state.value.failed }
manager.nextSessionFailures = emptySet()
await("capture failure stops") { engine.stop() }
await("capture fallback without preview") { manager.sessions.size == 2 && manager.sessions.last().repeating }
assertTrue(engine.state.value.settings.enabled)
await("fallback cleanup completes") { engine.stop() }
assertTrue(manager.sessions.all { it.closed })
} finally { engine.preview.detach(target); target.release() }
}
@Test fun synchronousSessionFailureKeepsPreviewOutputsUntilTheDeviceAcknowledgesClosure() {
manager.nextDeviceFailures = setOf("session after"); manager.autoClosed = false
manager.nextDeviceFailures = setOf("session"); manager.autoClosed = false
val engine = engine(); val target = engine.preview.attach(android.graphics.SurfaceTexture(2))
engine.select(engine.state.value.settings.copy(enabled = true))
await("failed session camera close requested") { manager.opened.singleOrNull()?.device?.closed == true }