Merge "Cancel graph state collection after UseCaseCamera is closed" into androidx-main
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
index 9ab3c3c..3c3ebe9 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCamera.kt
@@ -23,6 +23,7 @@
import android.hardware.camera2.params.MeteringRectangle
import androidx.annotation.RequiresApi
import androidx.camera.camera2.pipe.CameraGraph
+import androidx.camera.camera2.pipe.GraphState.GraphStateStopped
import androidx.camera.camera2.pipe.Result3A
import androidx.camera.camera2.pipe.core.Log.debug
import androidx.camera.camera2.pipe.integration.adapter.SessionConfigAdapter
@@ -35,8 +36,10 @@
import dagger.Module
import javax.inject.Inject
import kotlinx.atomicfu.atomic
+import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
internal val useCaseCameraIds = atomic(0)
@@ -85,7 +88,7 @@
override val requestControl: UseCaseCameraRequestControl,
) : UseCaseCamera {
private val debugId = useCaseCameraIds.incrementAndGet()
- private val graphStateJob: Job
+ private val closed = atomic(false)
override var runningUseCases = setOf<UseCase>()
set(value) {
@@ -109,21 +112,27 @@
useCaseGraphConfig.apply {
cameraStateAdapter.onGraphUpdated(graph)
}
- graphStateJob = threads.scope.launch {
+ threads.scope.launch {
useCaseGraphConfig.apply {
graph.graphState.collect {
cameraStateAdapter.onGraphStateUpdated(graph, it)
+ if (closed.value && it is GraphStateStopped) {
+ cancel()
+ }
}
}
}
}
override fun close(): Job {
- graphStateJob.cancel()
- return threads.scope.launch {
- debug { "Closing $this" }
- useCaseGraphConfig.graph.close()
- useCaseSurfaceManager.stopAsync().await()
+ return if (closed.compareAndSet(expect = false, update = true)) {
+ threads.scope.launch {
+ debug { "Closing $this" }
+ useCaseGraphConfig.graph.close()
+ useCaseSurfaceManager.stopAsync().await()
+ }
+ } else {
+ CompletableDeferred(Unit)
}
}