Add unit tests for Camera2CameraController restarts

Add unit tests that covers various scenarios for Camera2CameraController
restarts when encountering camera error or disconnect.

Bug: 372258646
Test: Camera2CameraControllerTest
Change-Id: I133aacbcfab5e6f7b1c0ddc0ca143010d9368ab8
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CameraControllerTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CameraControllerTest.kt
index fffb2bf..5a0bdfd 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CameraControllerTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/Camera2CameraControllerTest.kt
@@ -159,4 +159,108 @@
 
             cameraController.close()
         }
+
+    @Test
+    fun testControllerRestartsWhenCameraAvailableAfterCameraError() =
+        testScope.runTest(20.seconds) {
+            val cameraController = createCamera2CameraController()
+            cameraController.updateSurfaceMap(mapOf(streamId1 to fakeSurface))
+            cameraController.start()
+            fakeCamera2DeviceManager.simulateCameraOpen(cameraId)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraUnavailable()
+            fakeCamera2DeviceManager.simulateCameraError(cameraId, CameraError.ERROR_CAMERA_SERVICE)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraAvailable()
+            testScope.advanceUntilIdle()
+            assertEquals(cameraController.controllerState, ControllerState.STARTED)
+            verify(fakeCaptureSessionFactory, times(1)).create(any(), any(), any())
+
+            cameraController.close()
+        }
+
+    @Test
+    fun testControllerRestartsWhenCameraAvailableAfterCameraDisconnected() =
+        testScope.runTest(20.seconds) {
+            val cameraController = createCamera2CameraController()
+            cameraController.updateSurfaceMap(mapOf(streamId1 to fakeSurface))
+            cameraController.start()
+            fakeCamera2DeviceManager.simulateCameraOpen(cameraId)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraUnavailable()
+            fakeCamera2DeviceManager.simulateCameraError(cameraId, CameraError.ERROR_CAMERA_IN_USE)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraAvailable()
+            testScope.advanceUntilIdle()
+            assertEquals(cameraController.controllerState, ControllerState.STARTED)
+            verify(fakeCaptureSessionFactory, times(1)).create(any(), any(), any())
+
+            cameraController.close()
+        }
+
+    @Test
+    fun testControllerDoesNotRestartWhenCameraAvailableAfterGraphConfigError() =
+        testScope.runTest(20.seconds) {
+            val cameraController = createCamera2CameraController()
+            cameraController.updateSurfaceMap(mapOf(streamId1 to fakeSurface))
+            cameraController.start()
+            fakeCamera2DeviceManager.simulateCameraOpen(cameraId)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraUnavailable()
+            fakeCamera2DeviceManager.simulateCameraError(cameraId, CameraError.ERROR_GRAPH_CONFIG)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraAvailable()
+            testScope.advanceUntilIdle()
+            assertEquals(cameraController.controllerState, ControllerState.ERROR)
+
+            cameraController.close()
+        }
+
+    @Test
+    fun testControllerDoesNotRestartWhenCameraPrioritiesChangedAfterCameraError() =
+        testScope.runTest(20.seconds) {
+            val cameraController = createCamera2CameraController()
+            cameraController.updateSurfaceMap(mapOf(streamId1 to fakeSurface))
+            cameraController.start()
+            fakeCamera2DeviceManager.simulateCameraOpen(cameraId)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraUnavailable()
+            fakeCamera2DeviceManager.simulateCameraError(cameraId, CameraError.ERROR_CAMERA_DEVICE)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraPrioritiesChanged()
+            testScope.advanceUntilIdle()
+            assertEquals(cameraController.controllerState, ControllerState.ERROR)
+
+            cameraController.close()
+        }
+
+    @Test
+    fun testControllerRestartsWhenCameraPrioritiesChangedAfterCameraDisconnected() =
+        testScope.runTest(20.seconds) {
+            val cameraController = createCamera2CameraController()
+            cameraController.updateSurfaceMap(mapOf(streamId1 to fakeSurface))
+            cameraController.start()
+            fakeCamera2DeviceManager.simulateCameraOpen(cameraId)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraUnavailable()
+            fakeCamera2DeviceManager.simulateCameraError(cameraId, CameraError.ERROR_CAMERA_IN_USE)
+            testScope.advanceUntilIdle()
+
+            fakeCameraStatusMonitor.simulateCameraPrioritiesChanged()
+            fakeCameraStatusMonitor.simulateCameraAvailable()
+            testScope.advanceUntilIdle()
+            assertEquals(cameraController.controllerState, ControllerState.STARTED)
+            verify(fakeCaptureSessionFactory, times(1)).create(any(), any(), any())
+
+            cameraController.close()
+        }
 }