Merge "Make Camera2RequestMetaData unwrap as CameraCaptureSession" into androidx-main
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
index 267b739..b658684 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
@@ -196,6 +196,7 @@
 
             @Suppress("SyntheticAccessor")
             val metadata = Camera2RequestMetadata(
+                session,
                 captureRequest,
                 defaultParameters,
                 requiredParameters,
@@ -280,6 +281,7 @@
 @RequiresApi(21)
 @Suppress("SyntheticAccessor") // Using an inline class generates a synthetic constructor
 internal class Camera2RequestMetadata(
+    private val cameraCaptureSessionWrapper: CameraCaptureSessionWrapper,
     private val captureRequest: CaptureRequest,
     private val defaultParameters: Map<*, Any?>,
     private val requiredParameters: Map<*, Any?>,
@@ -298,9 +300,11 @@
         requiredParameters.containsKey(key) -> {
             requiredParameters[key] as T?
         }
+
         request.extras.containsKey(key) -> {
             request.extras[key] as T?
         }
+
         else -> {
             defaultParameters[key] as T?
         }
@@ -311,6 +315,9 @@
     @Suppress("UNCHECKED_CAST")
     override fun <T : Any> unwrapAs(type: KClass<T>): T? = when (type) {
         CaptureRequest::class -> captureRequest as T
+        CameraCaptureSession::class ->
+            cameraCaptureSessionWrapper.unwrapAs(CameraCaptureSession::class) as? T
+
         else -> null
     }
 }
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt
index 1bf84cc..1cb7e71 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessorTest.kt
@@ -17,6 +17,7 @@
 package androidx.camera.camera2.pipe.compat
 
 import android.graphics.SurfaceTexture
+import android.hardware.camera2.CameraCaptureSession
 import android.hardware.camera2.CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL
 import android.hardware.camera2.CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL
 import android.hardware.camera2.CaptureRequest
@@ -98,7 +99,8 @@
     private val stream2 = streamGraph[stream2Config]!!
 
     private val fakeCameraDevice = FakeCameraDeviceWrapper(testCamera)
-    private val fakeCaptureSession = fakeCameraDevice.createFakeCaptureSession()
+    private val fakeCaptureSessionWrapper =
+        fakeCameraDevice.createFakeCaptureSession(null)
 
     @After
     fun teardown() {
@@ -137,7 +139,7 @@
     @Test
     fun requestIsCreatedAndSubmitted() = runTest {
         val captureSequenceProcessor = Camera2CaptureSequenceProcessor(
-            fakeCaptureSession,
+            fakeCaptureSessionWrapper,
             FakeThreads.fromTestScope(this),
             RequestTemplate(1),
             mapOf(
@@ -163,8 +165,8 @@
         val result = captureSequenceProcessor.submit(sequence!!)
 
         assertThat(result).isGreaterThan(0)
-        assertThat(fakeCaptureSession.lastCapture).hasSize(1)
-        assertThat(fakeCaptureSession.lastRepeating).isNull()
+        assertThat(fakeCaptureSessionWrapper.lastCapture).hasSize(1)
+        assertThat(fakeCaptureSessionWrapper.lastRepeating).isNull()
 
         // TODO: Add support for checking parameters when robolectric supports it.
     }
@@ -172,7 +174,7 @@
     @Test
     fun requestIsSubmittedWithPartialSurfaces() = runTest {
         val captureSequenceProcessor = Camera2CaptureSequenceProcessor(
-            fakeCaptureSession,
+            fakeCaptureSessionWrapper,
             FakeThreads.fromTestScope(this),
             RequestTemplate(1),
             mapOf(
@@ -196,7 +198,7 @@
     @Test
     fun requestIsNotSubmittedWithEmptySurfaceList() = runTest {
         val captureSequenceProcessor = Camera2CaptureSequenceProcessor(
-            fakeCaptureSession,
+            fakeCaptureSessionWrapper,
             FakeThreads.fromTestScope(this),
             RequestTemplate(1),
             mapOf(
@@ -216,4 +218,32 @@
 
         assertThat(captureSequence).isNull()
     }
+
+    @Test
+    fun requestMetaDataUnwrapsAsCameraCaptureSession() = runTest {
+        val captureSequenceProcessor = Camera2CaptureSequenceProcessor(
+            fakeCaptureSessionWrapper,
+            FakeThreads.fromTestScope(this),
+            RequestTemplate(1),
+            mapOf(
+                stream1.id to surface1
+            )
+        )
+        val captureSequence = captureSequenceProcessor.build(
+            isRepeating = false,
+            requests = listOf(Request(listOf(stream1.id, stream2.id))),
+            defaultParameters = mapOf<Any, Any?>(),
+            requiredParameters = mapOf<Any, Any?>(),
+            listeners = emptyList(),
+            sequenceListener = FakeCaptureSequenceListener()
+        )
+
+        assertThat(captureSequence).isNotNull()
+        assertThat(captureSequence!!.captureMetadataList).isNotEmpty()
+        captureSequence.captureMetadataList[0].unwrapAs(CameraCaptureSession::class)
+
+        assertThat(fakeCaptureSessionWrapper.unwrappedClasses.size).isEqualTo(1)
+        assertThat(fakeCaptureSessionWrapper.unwrappedClasses[0])
+            .isEqualTo(CameraCaptureSession::class)
+    }
 }
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
index 63ba737..60b41dd 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
@@ -28,7 +28,7 @@
 internal class FakeCaptureSessionWrapper(
     override val device: CameraDeviceWrapper,
     override val isReprocessable: Boolean = false,
-    override val inputSurface: Surface? = null
+    override val inputSurface: Surface? = null,
 ) : CameraCaptureSessionWrapper {
     var closed = false
     var lastSequenceNumber = 0
@@ -41,6 +41,8 @@
     var stopRepeatingInvoked = false
     var abortCapturesInvoked = false
 
+    val unwrappedClasses = arrayListOf<Any>()
+
     override fun abortCaptures() {
         abortCapturesInvoked = true
     }
@@ -103,7 +105,11 @@
         )
     }
 
-    override fun <T : Any> unwrapAs(type: KClass<T>): T? = null
+    override fun <T : Any> unwrapAs(type: KClass<T>): T? {
+        unwrappedClasses.add(type)
+        return null
+    }
+
     override fun close() {
         closed = true
     }