Merge "Update hasCameraTransform bit" into androidx-main
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
index 45d12bd..ad3c388 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
@@ -300,6 +300,7 @@
             // Attach new UseCases.
             for (UseCase useCase : cameraUseCasesToAttach) {
                 ConfigPair configPair = requireNonNull(configs.get(useCase));
+                useCase.setHasCameraTransform(true);
                 useCase.bindToCamera(mCameraInternal, configPair.mExtendedConfig,
                         configPair.mCameraConfig);
                 useCase.updateSuggestedStreamSpec(
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java
index 1a5ec39..fa70b29 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCamera.java
@@ -96,6 +96,7 @@
 
     void bindChildren() {
         for (UseCase useCase : mChildren) {
+            useCase.setHasCameraTransform(false);
             useCase.bindToCamera(this, null,
                     useCase.getDefaultConfig(true, mUseCaseConfigFactory));
         }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
index d1dae4c..122860b 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
@@ -645,7 +645,7 @@
         previewToDetach = Preview.Builder()
             .setTargetRotation(Surface.ROTATION_0)
             .build()
-        previewToDetach.setHasCameraTransform(hasCameraTransform)
+        previewToDetach.hasCameraTransform = hasCameraTransform
         previewToDetach.processor = surfaceProcessor
         previewToDetach.setSurfaceProvider(CameraXExecutors.directExecutor()) {}
         val previewConfig = PreviewConfig(
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt
index 6680e50..2f6869c3 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/internal/CameraUseCaseAdapterTest.kt
@@ -141,6 +141,11 @@
         // Assert: StreamSharing children are bound
         assertThat(preview.camera).isNotNull()
         assertThat(video.camera).isNotNull()
+        // Assert: has camera transform bit.
+        assertThat(preview.hasCameraTransform).isFalse()
+        assertThat(video.hasCameraTransform).isFalse()
+        assertThat(image.hasCameraTransform).isTrue()
+        assertThat(adapter.getStreamSharing().hasCameraTransform).isTrue()
     }
 
     @Test
@@ -154,6 +159,8 @@
             Preview::class.java,
             FakeUseCase::class.java
         )
+        assertThat(preview.hasCameraTransform).isTrue()
+        assertThat(video.hasCameraTransform).isTrue()
     }
 
     @Test(expected = CameraException::class)
@@ -176,6 +183,8 @@
             FakeUseCase::class.java,
             ImageCapture::class.java
         )
+        assertThat(image.hasCameraTransform).isTrue()
+        assertThat(video.hasCameraTransform).isTrue()
         // Act: add a new UseCase that needs StreamSharing
         adapter.addUseCases(setOf(preview))
         // Assert: StreamSharing is created.
@@ -187,6 +196,11 @@
         assertThat(preview.camera).isNotNull()
         assertThat(video.camera).isNotNull()
         assertThat(image.camera).isNotNull()
+        // Assert: hasCameraTransform bit
+        assertThat(preview.hasCameraTransform).isFalse()
+        assertThat(video.hasCameraTransform).isFalse()
+        assertThat(image.hasCameraTransform).isTrue()
+        assertThat(adapter.getStreamSharing().hasCameraTransform).isTrue()
     }
 
     @Test
@@ -203,6 +217,11 @@
         val streamSharing =
             adapter.cameraUseCases.filterIsInstance(StreamSharing::class.java).single()
         assertThat(streamSharing.camera).isNotNull()
+        // Assert: hasCameraTransform bit
+        assertThat(preview.hasCameraTransform).isFalse()
+        assertThat(video.hasCameraTransform).isFalse()
+        assertThat(image.hasCameraTransform).isTrue()
+        assertThat(adapter.getStreamSharing().hasCameraTransform).isTrue()
         // Act: remove UseCase so that StreamSharing is no longer needed
         adapter.removeUseCases(setOf(video))
         // Assert: StreamSharing removed and unbound.
@@ -211,6 +230,9 @@
             ImageCapture::class.java
         )
         assertThat(streamSharing.camera).isNull()
+        // Assert: hasCameraTransform bit
+        assertThat(image.hasCameraTransform).isTrue()
+        assertThat(preview.hasCameraTransform).isTrue()
     }
 
     @Test(expected = CameraException::class)
@@ -229,7 +251,7 @@
         // Act: add UseCases that require StreamSharing
         adapter.addUseCases(setOf(preview, video, image))
         // Assert: StreamSharing is used.
-        val streamSharing = adapter.cameraUseCases.filterIsInstance<StreamSharing>().single()
+        val streamSharing = adapter.getStreamSharing()
         adapter.cameraUseCases.hasExactTypes(
             StreamSharing::class.java,
             ImageCapture::class.java
@@ -237,9 +259,7 @@
         // Act: add another UseCase
         adapter.addUseCases(setOf(analysis))
         // Assert: the same StreamSharing instance is kept.
-        assertThat(
-            adapter.cameraUseCases.filterIsInstance<StreamSharing>().single()
-        ).isSameInstanceAs(streamSharing)
+        assertThat(adapter.getStreamSharing()).isSameInstanceAs(streamSharing)
         adapter.cameraUseCases.hasExactTypes(
             StreamSharing::class.java,
             ImageCapture::class.java,
@@ -247,6 +267,10 @@
         )
     }
 
+    private fun CameraUseCaseAdapter.getStreamSharing(): StreamSharing {
+        return this.cameraUseCases.filterIsInstance(StreamSharing::class.java).single()
+    }
+
     private fun createFakeVideoCapture(): FakeUseCase {
         val fakeUseCaseConfig = FakeUseCaseConfig.Builder()
             .setBufferFormat(ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE)
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
index 945dd35..dd46cef 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
@@ -145,14 +145,17 @@
     fun setNoCameraTransform_propagatesToCameraEdge() {
         // Arrange.
         setupCamera()
-        createCameraUseCaseAdapter()
         val processor = createFakeSurfaceProcessor()
         val videoCapture = createVideoCapture(createVideoOutput(), processor = processor)
-        // Act.
-        videoCapture.setHasCameraTransform(false)
-        addAndAttachUseCases(videoCapture)
-        // Assert.
+        // Act: set no transform and create pipeline.
+        videoCapture.hasCameraTransform = false
+        videoCapture.bindToCamera(camera, null, null)
+        videoCapture.updateSuggestedStreamSpec(StreamSpec.builder(Size(640, 480)).build())
+        videoCapture.onStateAttached()
+        // Assert: camera edge does not have transform.
         assertThat(videoCapture.cameraEdge!!.hasCameraTransform()).isFalse()
+        videoCapture.onStateDetached()
+        videoCapture.unbindFromCamera(camera)
     }
 
     @Test