diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md index a0a0fd8ae6b..426731aa7ff 100644 --- a/packages/camera/camera_android/CHANGELOG.md +++ b/packages/camera/camera_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.8+5 + +* Provides a default exposure point if null. + ## 0.10.8+4 * Adjusts SDK checks for better testability. diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java index 40f28eadc04..afeed9899f3 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java @@ -10,6 +10,7 @@ import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugins.camera.CameraProperties; import io.flutter.plugins.camera.CameraRegionUtils; @@ -24,6 +25,8 @@ public class ExposurePointFeature extends CameraFeature { @Nullable private Point exposurePoint; private MeteringRectangle exposureRectangle; @NonNull private final SensorOrientationFeature sensorOrientationFeature; + private boolean defaultRegionsHasBeenSet = false; + @VisibleForTesting @Nullable public MeteringRectangle[] defaultRegions; /** * Creates a new instance of the {@link ExposurePointFeature}. @@ -78,9 +81,18 @@ public void updateBuilder(@NonNull CaptureRequest.Builder requestBuilder) { if (!checkIsSupported()) { return; } - requestBuilder.set( - CaptureRequest.CONTROL_AE_REGIONS, - exposureRectangle == null ? null : new MeteringRectangle[] {exposureRectangle}); + + if (!defaultRegionsHasBeenSet) { + defaultRegions = requestBuilder.get(CaptureRequest.CONTROL_AE_REGIONS); + defaultRegionsHasBeenSet = true; + } + + if (exposureRectangle != null) { + requestBuilder.set( + CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[] {exposureRectangle}); + } else { + requestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, defaultRegions); + } } private void buildExposureRectangle() { diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java index 800c3f74d1d..1eaa537c91b 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java @@ -9,7 +9,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -281,7 +281,7 @@ public void updateBuilder_shouldSetMeteringRectangleWhenValidBoundariesAndCoords } @Test - public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidBoundariesAreSupplied() { + public void updateBuilder_shoulSetDefaultMeteringRectangleWhenNoValidBoundariesAreSupplied() { CameraProperties mockCameraProperties = mock(CameraProperties.class); when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1); CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class); @@ -290,11 +290,11 @@ public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidBoundariesAreS exposurePointFeature.updateBuilder(mockCaptureRequestBuilder); - verify(mockCaptureRequestBuilder, times(1)).set(any(), isNull()); + verify(mockCaptureRequestBuilder, times(1)).set(any(), any()); } @Test - public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidCoordsAreSupplied() { + public void updateBuilder_shouldSetDefaultMeteringRectangleWhenNoValidCoordsAreSupplied() { CameraProperties mockCameraProperties = mock(CameraProperties.class); when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1); CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class); @@ -302,12 +302,40 @@ public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidCoordsAreSuppl new ExposurePointFeature(mockCameraProperties, mockSensorOrientationFeature); exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries); + MeteringRectangle[] defaultRegions = + new MeteringRectangle[] {new MeteringRectangle(0, 0, 100, 100, 0)}; + when(mockCaptureRequestBuilder.get(CaptureRequest.CONTROL_AE_REGIONS)) + .thenReturn(defaultRegions); + exposurePointFeature.setValue(null); exposurePointFeature.updateBuilder(mockCaptureRequestBuilder); exposurePointFeature.setValue(new Point(0d, null)); exposurePointFeature.updateBuilder(mockCaptureRequestBuilder); exposurePointFeature.setValue(new Point(null, 0d)); exposurePointFeature.updateBuilder(mockCaptureRequestBuilder); - verify(mockCaptureRequestBuilder, times(3)).set(any(), isNull()); + + verify(mockCaptureRequestBuilder, times(3)).set(any(), eq(defaultRegions)); + } + + @Test + public void updateBuilder_shouldSetNonNullMeteringRectangleWhenNullValueIsSupplied() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1); + CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class); + ExposurePointFeature exposurePointFeature = + new ExposurePointFeature(mockCameraProperties, mockSensorOrientationFeature); + + MeteringRectangle[] defaultRegions = + new MeteringRectangle[] {new MeteringRectangle(0, 0, 100, 100, 0)}; + when(mockCaptureRequestBuilder.get(CaptureRequest.CONTROL_AE_REGIONS)) + .thenReturn(defaultRegions); + + exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries); + + exposurePointFeature.setValue(null); + + exposurePointFeature.updateBuilder(mockCaptureRequestBuilder); + + verify(mockCaptureRequestBuilder, times(1)).set(any(), eq(exposurePointFeature.defaultRegions)); } } diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml index 307506a42f9..68e539e3919 100644 --- a/packages/camera/camera_android/pubspec.yaml +++ b/packages/camera/camera_android/pubspec.yaml @@ -3,7 +3,7 @@ description: Android implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.10.8+4 +version: 0.10.8+5 environment: sdk: ">=2.18.0 <4.0.0"