Handle failed Camera2 sessions without waiting for an absent callback
This commit is contained in:
1 parent
53340db0e3
commit
4d559dc08b
2 files changed
+17
-4
No files matched your search
@@ -591,6 +591,7 @@ class CallVideoEngine(private val context: Context, private val id: Long) {
|
||||
}
|
||||
}
|
||||
sessions[serial] = device to ::complete
|
||||
var submitted = false
|
||||
try {
|
||||
val c = manager.getCameraCharacteristics(device.id)
|
||||
var previewFormat: StreamPreviewFormat? = null
|
||||
@@ -605,6 +606,7 @@ class CallVideoEngine(private val context: Context, private val id: Long) {
|
||||
preview.update(previewFormat)
|
||||
} else if (withPreview) preview.update(null)
|
||||
val targets = listOfNotNull(source.surface, output?.surface)
|
||||
submitted = true
|
||||
device.createCaptureSession(targets, object : CameraCaptureSession.StateCallback() {
|
||||
override fun onConfigured(s: CameraCaptureSession) {
|
||||
if (completed) { try { s.close() } catch (e: Exception) { LogManager.addLog("WARN", "call", "closed camera session callback id=$id: $e") }; return }
|
||||
@@ -624,7 +626,8 @@ class CallVideoEngine(private val context: Context, private val id: Long) {
|
||||
} catch (e: Exception) { closingSessions.add(s); queueCleanup(0); rejected("Camera request: ${e.message}") }
|
||||
}
|
||||
override fun onConfigureFailed(s: CameraCaptureSession) {
|
||||
ownedSessions[s] = device; closingSessions.add(s); queueCleanup(0)
|
||||
// SDK уже закрыл сессию; onClosed после этого callback не гарантируется.
|
||||
ownedSessions.remove(s); closingSessions.remove(s); complete()
|
||||
rejected("Camera session configuration failed")
|
||||
}
|
||||
override fun onClosed(s: CameraCaptureSession) {
|
||||
@@ -633,7 +636,15 @@ class CallVideoEngine(private val context: Context, private val id: Long) {
|
||||
complete(); queueCleanup(0)
|
||||
}
|
||||
}, handler)
|
||||
} catch (e: Exception) { complete(); rejected("Camera session: ${e.message}") }
|
||||
} catch (e: Exception) {
|
||||
if (!submitted) { complete(); rejected("Camera session: ${e.message}") }
|
||||
else {
|
||||
// SDK может одновременно бросить CameraAccessException и назначить callback сессии.
|
||||
// До camera.onClosed сохраняем все выходы даже при отсутствии callback сессии.
|
||||
LogManager.addLog("ERROR", "call", "camera session submission failed id=$id session=$serial; awaiting device closure: $e")
|
||||
fail("Camera session: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun drain(finish: Boolean = false) {
|
||||
val codec = encoder ?: return; val f = format ?: return
|
||||
|
||||
+4
-2
@@ -89,9 +89,10 @@ class CameraDevice(val id: String, private val owner: CameraManager, private val
|
||||
val session = CameraCaptureSession(this, callback, delivery).also { it.failures = owner.nextSessionFailures }
|
||||
owner.sessions.add(session)
|
||||
if (owner.autoConfigured) delivery.post {
|
||||
if ("configure" in session.failures) callback.onConfigureFailed(session) else callback.onConfigured(session)
|
||||
if ("configure" in session.failures || "session after" in failures) session.failConfiguration()
|
||||
else callback.onConfigured(session)
|
||||
}
|
||||
check("session after" !in failures) { "session creation failed after effect" }
|
||||
if ("session after" in failures) throw CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED)
|
||||
}
|
||||
fun close() {
|
||||
closeCalls++; check("close" !in failures) { "camera close failed" }
|
||||
@@ -118,6 +119,7 @@ class CameraCaptureSession(val device: CameraDevice, val callback: StateCallback
|
||||
check("request" !in failures) { "repeating request failed" }; repeating = true
|
||||
}
|
||||
fun close() { check("close" !in failures) { "session close failed" }; forceClose(); check("close after" !in failures) }
|
||||
internal fun failConfiguration() { closed = true; callback.onConfigureFailed(this) }
|
||||
internal fun forceClose() {
|
||||
if (closed) return
|
||||
closed = true; repeating = false; handler.post { callback.onClosed(this) }
|
||||
|
||||
Reference in new issue
Block a user