diff --git a/packages/camera/camera/android/build.gradle b/packages/camera/camera/android/build.gradle
index 0907c1eeecc9..65c6d26edb49 100644
--- a/packages/camera/camera/android/build.gradle
+++ b/packages/camera/camera/android/build.gradle
@@ -49,7 +49,7 @@ android {
dependencies {
compileOnly 'androidx.annotation:annotation:1.1.0'
testImplementation 'junit:junit:4.12'
- testImplementation 'org.mockito:mockito-inline:3.5.13'
+ testImplementation 'org.mockito:mockito-inline:3.11.1'
testImplementation 'androidx.test:core:1.3.0'
testImplementation 'org.robolectric:robolectric:4.3'
}
diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegionUtils.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegionUtils.java
new file mode 100644
index 000000000000..ff8a49f1d148
--- /dev/null
+++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegionUtils.java
@@ -0,0 +1,161 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.camera;
+
+import android.annotation.TargetApi;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.os.Build;
+import android.util.Size;
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import java.util.Arrays;
+
+/**
+ * Utility class offering functions to calculate values regarding the camera boundaries.
+ *
+ *
The functions are used to calculate focus and exposure settings.
+ */
+public final class CameraRegionUtils {
+
+ /**
+ * Obtains the boundaries for the currently active camera, that can be used for calculating
+ * MeteringRectangle instances required for setting focus or exposure settings.
+ *
+ * @param cameraProperties - Collection of the characteristics for the current camera device.
+ * @param requestBuilder - The request builder for the current capture request.
+ * @return The boundaries for the current camera device.
+ */
+ public static Size getCameraBoundaries(
+ @NonNull CameraProperties cameraProperties, @NonNull CaptureRequest.Builder requestBuilder) {
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
+ && supportsDistortionCorrection(cameraProperties)) {
+ // Get the current distortion correction mode.
+ Integer distortionCorrectionMode =
+ requestBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE);
+
+ // Return the correct boundaries depending on the mode.
+ android.graphics.Rect rect;
+ if (distortionCorrectionMode == null
+ || distortionCorrectionMode == CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
+ rect = cameraProperties.getSensorInfoPreCorrectionActiveArraySize();
+ } else {
+ rect = cameraProperties.getSensorInfoActiveArraySize();
+ }
+
+ return SizeFactory.create(rect.width(), rect.height());
+ } else {
+ // No distortion correction support.
+ return cameraProperties.getSensorInfoPixelArraySize();
+ }
+ }
+
+ /**
+ * Converts a point into a {@link MeteringRectangle} with the supplied coordinates as the center
+ * point.
+ *
+ *
Since the Camera API (due to cross-platform constraints) only accepts a point when
+ * configuring a specific focus or exposure area and Android requires a rectangle to configure
+ * these settings there is a need to convert the point into a rectangle. This method will create
+ * the required rectangle with an arbitrarily size that is a 10th of the current viewport and the
+ * coordinates as the center point.
+ *
+ * @param boundaries - The camera boundaries to calculate the metering rectangle for.
+ * @param x x - 1 >= coordinate >= 0.
+ * @param y y - 1 >= coordinate >= 0.
+ * @return The dimensions of the metering rectangle based on the supplied coordinates and
+ * boundaries.
+ */
+ public static MeteringRectangle convertPointToMeteringRectangle(
+ @NonNull Size boundaries, double x, double y) {
+ assert (boundaries.getWidth() > 0 && boundaries.getHeight() > 0);
+ assert (x >= 0 && x <= 1);
+ assert (y >= 0 && y <= 1);
+
+ // Interpolate the target coordinate.
+ int targetX = (int) Math.round(x * ((double) (boundaries.getWidth() - 1)));
+ int targetY = (int) Math.round(y * ((double) (boundaries.getHeight() - 1)));
+ // Determine the dimensions of the metering rectangle (10th of the viewport).
+ int targetWidth = (int) Math.round(((double) boundaries.getWidth()) / 10d);
+ int targetHeight = (int) Math.round(((double) boundaries.getHeight()) / 10d);
+ // Adjust target coordinate to represent top-left corner of metering rectangle.
+ targetX -= targetWidth / 2;
+ targetY -= targetHeight / 2;
+ // Adjust target coordinate as to not fall out of bounds.
+ if (targetX < 0) {
+ targetX = 0;
+ }
+ if (targetY < 0) {
+ targetY = 0;
+ }
+ int maxTargetX = boundaries.getWidth() - 1 - targetWidth;
+ int maxTargetY = boundaries.getHeight() - 1 - targetHeight;
+ if (targetX > maxTargetX) {
+ targetX = maxTargetX;
+ }
+ if (targetY > maxTargetY) {
+ targetY = maxTargetY;
+ }
+
+ // Build the metering rectangle.
+ return MeteringRectangleFactory.create(targetX, targetY, targetWidth, targetHeight, 1);
+ }
+
+ @TargetApi(Build.VERSION_CODES.P)
+ private static boolean supportsDistortionCorrection(CameraProperties cameraProperties) {
+ int[] availableDistortionCorrectionModes =
+ cameraProperties.getDistortionCorrectionAvailableModes();
+ if (availableDistortionCorrectionModes == null) {
+ availableDistortionCorrectionModes = new int[0];
+ }
+ long nonOffModesSupported =
+ Arrays.stream(availableDistortionCorrectionModes)
+ .filter((value) -> value != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF)
+ .count();
+ return nonOffModesSupported > 0;
+ }
+
+ /** Factory class that assists in creating a {@link MeteringRectangle} instance. */
+ static class MeteringRectangleFactory {
+ /**
+ * Creates a new instance of the {@link MeteringRectangle} class.
+ *
+ *
This method is visible for testing purposes only and should never be used outside this *
+ * class.
+ *
+ * @param x coordinate >= 0.
+ * @param y coordinate >= 0.
+ * @param width width >= 0.
+ * @param height height >= 0.
+ * @param meteringWeight weight between {@value MeteringRectangle#METERING_WEIGHT_MIN} and
+ * {@value MeteringRectangle#METERING_WEIGHT_MAX} inclusively
+ * @return new instance of the {@link MeteringRectangle} class.
+ * @throws IllegalArgumentException if any of the parameters were negative.
+ */
+ @VisibleForTesting
+ public static MeteringRectangle create(
+ int x, int y, int width, int height, int meteringWeight) {
+ return new MeteringRectangle(x, y, width, height, meteringWeight);
+ }
+ }
+
+ /** Factory class that assists in creating a {@link Size} instance. */
+ static class SizeFactory {
+ /**
+ * Creates a new instance of the {@link Size} class.
+ *
+ *
This method is visible for testing purposes only and should never be used outside this *
+ * class.
+ *
+ * @param width width >= 0.
+ * @param height height >= 0.
+ * @return new instance of the {@link Size} class.
+ */
+ @VisibleForTesting
+ public static Size create(int width, int height) {
+ return new Size(width, height);
+ }
+ }
+}
diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java
index f729d33c8528..8c2ee6167846 100644
--- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java
+++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java
@@ -6,28 +6,37 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.MeteringRectangle;
-import android.util.Log;
+import android.util.Size;
import androidx.annotation.NonNull;
import io.flutter.plugins.camera.CameraProperties;
+import io.flutter.plugins.camera.CameraRegionUtils;
import io.flutter.plugins.camera.features.CameraFeature;
import io.flutter.plugins.camera.features.Point;
-import io.flutter.plugins.camera.types.CameraRegions;
/** Exposure point controls where in the frame exposure metering will come from. */
public class ExposurePointFeature extends CameraFeature {
- private final CameraRegions cameraRegions;
- private Point currentSetting = new Point(0.0, 0.0);
+ private Size cameraBoundaries;
+ private Point exposurePoint;
+ private MeteringRectangle exposureRectangle;
/**
* Creates a new instance of the {@link ExposurePointFeature}.
*
* @param cameraProperties Collection of the characteristics for the current camera device.
- * @param cameraRegions Utility class to assist in calculating exposure boundaries.
*/
- public ExposurePointFeature(CameraProperties cameraProperties, CameraRegions cameraRegions) {
+ public ExposurePointFeature(CameraProperties cameraProperties) {
super(cameraProperties);
- this.cameraRegions = cameraRegions;
+ }
+
+ /**
+ * Sets the camera boundaries that are required for the exposure point feature to function.
+ *
+ * @param cameraBoundaries - The camera boundaries to set.
+ */
+ public void setCameraBoundaries(@NonNull Size cameraBoundaries) {
+ this.cameraBoundaries = cameraBoundaries;
+ this.buildExposureRectangle();
}
@Override
@@ -37,18 +46,13 @@ public String getDebugName() {
@Override
public Point getValue() {
- return currentSetting;
+ return exposurePoint;
}
@Override
- public void setValue(@NonNull Point value) {
- this.currentSetting = value;
-
- if (value.x == null || value.y == null) {
- cameraRegions.resetAutoExposureMeteringRectangle();
- } else {
- cameraRegions.setAutoExposureMeteringRectangleFromPoint(value.x, value.y);
- }
+ public void setValue(Point value) {
+ this.exposurePoint = (value == null || value.x == null || value.y == null) ? null : value;
+ this.buildExposureRectangle();
}
// Whether or not this camera can set the exposure point.
@@ -63,16 +67,22 @@ public void updateBuilder(CaptureRequest.Builder requestBuilder) {
if (!checkIsSupported()) {
return;
}
-
- MeteringRectangle aeRect = null;
- try {
- aeRect = cameraRegions.getAEMeteringRectangle();
- } catch (Exception e) {
- Log.w("Camera", "Unable to retrieve the Auto Exposure metering rectangle.", e);
- }
-
requestBuilder.set(
CaptureRequest.CONTROL_AE_REGIONS,
- aeRect == null ? null : new MeteringRectangle[] {aeRect});
+ exposureRectangle == null ? null : new MeteringRectangle[] {exposureRectangle});
+ }
+
+ private void buildExposureRectangle() {
+ if (this.cameraBoundaries == null) {
+ throw new AssertionError(
+ "The cameraBoundaries should be set (using `ExposurePointFeature.setCameraBoundaries(Size)`) before updating the exposure point.");
+ }
+ if (this.exposurePoint == null) {
+ this.exposureRectangle = null;
+ } else {
+ this.exposureRectangle =
+ CameraRegionUtils.convertPointToMeteringRectangle(
+ this.cameraBoundaries, this.exposurePoint.x, this.exposurePoint.y);
+ }
}
}
diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/focuspoint/FocusPointFeature.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/focuspoint/FocusPointFeature.java
new file mode 100644
index 000000000000..92fcfa9f1132
--- /dev/null
+++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/focuspoint/FocusPointFeature.java
@@ -0,0 +1,88 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.camera.features.focuspoint;
+
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.util.Size;
+import androidx.annotation.NonNull;
+import io.flutter.plugins.camera.CameraProperties;
+import io.flutter.plugins.camera.CameraRegionUtils;
+import io.flutter.plugins.camera.features.CameraFeature;
+import io.flutter.plugins.camera.features.Point;
+
+/** Focus point controls where in the frame focus will come from. */
+public class FocusPointFeature extends CameraFeature {
+
+ private Size cameraBoundaries;
+ private Point focusPoint;
+ private MeteringRectangle focusRectangle;
+
+ /**
+ * Creates a new instance of the {@link FocusPointFeature}.
+ *
+ * @param cameraProperties Collection of the characteristics for the current camera device.
+ */
+ public FocusPointFeature(CameraProperties cameraProperties) {
+ super(cameraProperties);
+ }
+
+ /**
+ * Sets the camera boundaries that are required for the focus point feature to function.
+ *
+ * @param cameraBoundaries - The camera boundaries to set.
+ */
+ public void setCameraBoundaries(@NonNull Size cameraBoundaries) {
+ this.cameraBoundaries = cameraBoundaries;
+ this.buildFocusRectangle();
+ }
+
+ @Override
+ public String getDebugName() {
+ return "FocusPointFeature";
+ }
+
+ @Override
+ public Point getValue() {
+ return focusPoint;
+ }
+
+ @Override
+ public void setValue(Point value) {
+ this.focusPoint = value == null || value.x == null || value.y == null ? null : value;
+ this.buildFocusRectangle();
+ }
+
+ // Whether or not this camera can set the focus point.
+ @Override
+ public boolean checkIsSupported() {
+ Integer supportedRegions = cameraProperties.getControlMaxRegionsAutoFocus();
+ return supportedRegions != null && supportedRegions > 0;
+ }
+
+ @Override
+ public void updateBuilder(CaptureRequest.Builder requestBuilder) {
+ if (!checkIsSupported()) {
+ return;
+ }
+ requestBuilder.set(
+ CaptureRequest.CONTROL_AF_REGIONS,
+ focusRectangle == null ? null : new MeteringRectangle[] {focusRectangle});
+ }
+
+ private void buildFocusRectangle() {
+ if (this.cameraBoundaries == null) {
+ throw new AssertionError(
+ "The cameraBoundaries should be set (using `FocusPointFeature.setCameraBoundaries(Size)`) before updating the focus point.");
+ }
+ if (this.focusPoint == null) {
+ this.focusRectangle = null;
+ } else {
+ this.focusRectangle =
+ CameraRegionUtils.convertPointToMeteringRectangle(
+ this.cameraBoundaries, this.focusPoint.x, this.focusPoint.y);
+ }
+ }
+}
diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/CameraRegions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/CameraRegions.java
deleted file mode 100644
index b86241e78d29..000000000000
--- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/CameraRegions.java
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package io.flutter.plugins.camera.types;
-
-import android.annotation.TargetApi;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.os.Build;
-import android.util.Size;
-import androidx.annotation.NonNull;
-import io.flutter.plugins.camera.CameraProperties;
-import java.util.Arrays;
-
-/**
- * Utility class that contains information regarding the camera's regions.
- *
- * The regions information is used to calculate focus and exposure settings.
- */
-public final class CameraRegions {
-
- /** Factory class that assists in creating a {@link CameraRegions} instance. */
- public static class Factory {
- /**
- * Creates a new instance of the {@link CameraRegions} class.
- *
- *
The {@link CameraProperties} and {@link CaptureRequest.Builder} classed are used to
- * determine if the device's camera supports distortion correction mode and calculate the
- * correct boundaries based on the outcome.
- *
- * @param cameraProperties Collection of the characteristics for the current camera device.
- * @param requestBuilder CaptureRequest builder containing current target and surface settings.
- * @return new instance of the {@link CameraRegions} class.
- */
- public static CameraRegions create(
- @NonNull CameraProperties cameraProperties,
- @NonNull CaptureRequest.Builder requestBuilder) {
- Size boundaries;
-
- // No distortion correction support
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
- && supportsDistortionCorrection(cameraProperties)) {
- // Get the current distortion correction mode
- Integer distortionCorrectionMode =
- requestBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE);
-
- // Return the correct boundaries depending on the mode
- android.graphics.Rect rect;
- if (distortionCorrectionMode == null
- || distortionCorrectionMode == CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
- rect = cameraProperties.getSensorInfoPreCorrectionActiveArraySize();
- } else {
- rect = cameraProperties.getSensorInfoActiveArraySize();
- }
-
- // Set new region size
- boundaries = rect == null ? null : new Size(rect.width(), rect.height());
- } else {
- boundaries = cameraProperties.getSensorInfoPixelArraySize();
- }
-
- // Create new camera regions using new size
- return new CameraRegions(boundaries);
- }
-
- @TargetApi(Build.VERSION_CODES.P)
- private static boolean supportsDistortionCorrection(CameraProperties cameraProperties) {
- int[] availableDistortionCorrectionModes =
- cameraProperties.getDistortionCorrectionAvailableModes();
- if (availableDistortionCorrectionModes == null) {
- availableDistortionCorrectionModes = new int[0];
- }
- long nonOffModesSupported =
- Arrays.stream(availableDistortionCorrectionModes)
- .filter((value) -> value != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF)
- .count();
- return nonOffModesSupported > 0;
- }
- }
-
- private final Size boundaries;
-
- private MeteringRectangle aeMeteringRectangle;
- private MeteringRectangle afMeteringRectangle;
-
- /**
- * Creates a new instance of the {@link CameraRegions} class.
- *
- * @param boundaries The area of the image sensor.
- */
- CameraRegions(Size boundaries) {
- assert (boundaries == null || boundaries.getWidth() > 0);
- assert (boundaries == null || boundaries.getHeight() > 0);
-
- this.boundaries = boundaries;
- }
-
- /**
- * Gets the {@link MeteringRectangle} on which the auto exposure will be applied.
- *
- * @return The {@link MeteringRectangle} on which the auto exposure will be applied.
- */
- public MeteringRectangle getAEMeteringRectangle() {
- return aeMeteringRectangle;
- }
-
- /**
- * Gets the {@link MeteringRectangle} on which the auto focus will be applied.
- *
- * @return The {@link MeteringRectangle} on which the auto focus will be applied.
- */
- public MeteringRectangle getAFMeteringRectangle() {
- return afMeteringRectangle;
- }
-
- /**
- * Gets the area of the image sensor.
- *
- *
If distortion correction is supported the size corresponds to the active pixels after any
- * geometric distortion correction has been applied. If distortion correction is not supported the
- * dimensions include the full pixel array, possibly including black calibration pixels.
- *
- * @return The area of the image sensor.
- */
- public Size getBoundaries() {
- return this.boundaries;
- }
-
- /** Resets the {@link MeteringRectangle} on which the auto exposure will be applied. */
- public void resetAutoExposureMeteringRectangle() {
- this.aeMeteringRectangle = null;
- }
-
- /**
- * Sets the coordinates which will form the centre of the exposure rectangle.
- *
- * @param x x – coordinate >= 0
- * @param y y – coordinate >= 0
- */
- public void setAutoExposureMeteringRectangleFromPoint(double x, double y) {
- this.aeMeteringRectangle = convertPointToMeteringRectangle(x, y);
- }
-
- /** Resets the {@link MeteringRectangle} on which the auto focus will be applied. */
- public void resetAutoFocusMeteringRectangle() {
- this.afMeteringRectangle = null;
- }
-
- /**
- * Sets the coordinates which will form the centre of the focus rectangle.
- *
- * @param x x – coordinate >= 0
- * @param y y – coordinate >= 0
- */
- public void setAutoFocusMeteringRectangleFromPoint(double x, double y) {
- this.afMeteringRectangle = convertPointToMeteringRectangle(x, y);
- }
-
- /**
- * Converts a point into a {@link MeteringRectangle} with the supplied coordinates as the centre
- * point.
- *
- *
Since the Camera API (due to cross-platform constraints) only accepts a point when
- * configuring a specific focus or exposure area and Android requires a rectangle to configure
- * these settings there is a need to convert the point into a rectangle. This method will create
- * the required rectangle with an arbitrarily size that is a 10th of the current viewport and the
- * coordinates as the centre point.
- *
- * @param x x - coordinate >= 0
- * @param y y - coordinate >= 0
- * @return The dimensions of the metering rectangle based on the supplied coordinates.
- */
- MeteringRectangle convertPointToMeteringRectangle(double x, double y) {
- assert (x >= 0 && x <= 1);
- assert (y >= 0 && y <= 1);
-
- // Interpolate the target coordinate
- int targetX = (int) Math.round(x * ((double) (boundaries.getWidth() - 1)));
- int targetY = (int) Math.round(y * ((double) (boundaries.getHeight() - 1)));
- // Since the Camera API only allows Determine the dimensions of the metering rectangle (10th of
- // the viewport)
- int targetWidth = (int) Math.round(((double) boundaries.getWidth()) / 10d);
- int targetHeight = (int) Math.round(((double) boundaries.getHeight()) / 10d);
- // Adjust target coordinate to represent top-left corner of metering rectangle
- targetX -= targetWidth / 2;
- targetY -= targetHeight / 2;
- // Adjust target coordinate as to not fall out of bounds
- if (targetX < 0) targetX = 0;
- if (targetY < 0) targetY = 0;
- int maxTargetX = boundaries.getWidth() - 1 - targetWidth;
- int maxTargetY = boundaries.getHeight() - 1 - targetHeight;
- if (targetX > maxTargetX) targetX = maxTargetX;
- if (targetY > maxTargetY) targetY = maxTargetY;
-
- // Build the metering rectangle
- return new MeteringRectangle(targetX, targetY, targetWidth, targetHeight, 1);
- }
-}
diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionUtilsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionUtilsTest.java
new file mode 100644
index 000000000000..2d65c4e0fc05
--- /dev/null
+++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionUtilsTest.java
@@ -0,0 +1,353 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+package io.flutter.plugins.camera;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Rect;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.os.Build;
+import android.util.Size;
+import io.flutter.plugins.camera.utils.TestUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+public class CameraRegionUtilsTest {
+
+ Size mockCameraBoundaries;
+
+ @Before
+ public void setUp() {
+ this.mockCameraBoundaries = mock(Size.class);
+ when(this.mockCameraBoundaries.getWidth()).thenReturn(100);
+ when(this.mockCameraBoundaries.getHeight()).thenReturn(100);
+ }
+
+ @Test
+ public void
+ getCameraBoundaries_should_return_sensor_info_pixel_array_size_when_running_pre_android_p() {
+ updateSdkVersion(Build.VERSION_CODES.O_MR1);
+
+ try {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+ when(mockCameraProperties.getSensorInfoPixelArraySize()).thenReturn(mockCameraBoundaries);
+
+ Size result = CameraRegionUtils.getCameraBoundaries(mockCameraProperties, mockBuilder);
+
+ assertEquals(mockCameraBoundaries, result);
+ verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
+ verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
+ } finally {
+ updateSdkVersion(0);
+ }
+ }
+
+ @Test
+ public void
+ getCameraBoundaries_should_return_sensor_info_pixel_array_size_when_distortion_correction_is_null() {
+ updateSdkVersion(Build.VERSION_CODES.P);
+
+ try {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+
+ when(mockCameraProperties.getDistortionCorrectionAvailableModes()).thenReturn(null);
+ when(mockCameraProperties.getSensorInfoPixelArraySize()).thenReturn(mockCameraBoundaries);
+
+ Size result = CameraRegionUtils.getCameraBoundaries(mockCameraProperties, mockBuilder);
+
+ assertEquals(mockCameraBoundaries, result);
+ verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
+ verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
+ } finally {
+ updateSdkVersion(0);
+ }
+ }
+
+ @Test
+ public void
+ getCameraBoundaries_should_return_sensor_info_pixel_array_size_when_distortion_correction_is_off() {
+ updateSdkVersion(Build.VERSION_CODES.P);
+
+ try {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+
+ when(mockCameraProperties.getDistortionCorrectionAvailableModes())
+ .thenReturn(new int[] {CaptureRequest.DISTORTION_CORRECTION_MODE_OFF});
+ when(mockCameraProperties.getSensorInfoPixelArraySize()).thenReturn(mockCameraBoundaries);
+
+ Size result = CameraRegionUtils.getCameraBoundaries(mockCameraProperties, mockBuilder);
+
+ assertEquals(mockCameraBoundaries, result);
+ verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
+ verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
+ } finally {
+ updateSdkVersion(0);
+ }
+ }
+
+ @Test
+ public void
+ getCameraBoundaries_should_return_info_pre_correction_active_array_size_when_distortion_correction_mode_is_set_to_null() {
+ updateSdkVersion(Build.VERSION_CODES.P);
+
+ try {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+ Rect mockSensorInfoPreCorrectionActiveArraySize = mock(Rect.class);
+ when(mockSensorInfoPreCorrectionActiveArraySize.width()).thenReturn(100);
+ when(mockSensorInfoPreCorrectionActiveArraySize.height()).thenReturn(100);
+
+ when(mockCameraProperties.getDistortionCorrectionAvailableModes())
+ .thenReturn(
+ new int[] {
+ CaptureRequest.DISTORTION_CORRECTION_MODE_OFF,
+ CaptureRequest.DISTORTION_CORRECTION_MODE_FAST
+ });
+ when(mockBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE)).thenReturn(null);
+ when(mockCameraProperties.getSensorInfoPreCorrectionActiveArraySize())
+ .thenReturn(mockSensorInfoPreCorrectionActiveArraySize);
+
+ try (MockedStatic mockedSizeFactory =
+ mockStatic(CameraRegionUtils.SizeFactory.class)) {
+ mockedSizeFactory
+ .when(() -> CameraRegionUtils.SizeFactory.create(anyInt(), anyInt()))
+ .thenAnswer(
+ (Answer)
+ invocation -> {
+ Size mockSize = mock(Size.class);
+ when(mockSize.getWidth()).thenReturn(invocation.getArgument(0));
+ when(mockSize.getHeight()).thenReturn(invocation.getArgument(1));
+ return mockSize;
+ });
+
+ Size result = CameraRegionUtils.getCameraBoundaries(mockCameraProperties, mockBuilder);
+
+ assertEquals(100, result.getWidth());
+ assertEquals(100, result.getHeight());
+ verify(mockCameraProperties, never()).getSensorInfoPixelArraySize();
+ verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
+ }
+ } finally {
+ updateSdkVersion(0);
+ }
+ }
+
+ @Test
+ public void
+ getCameraBoundaries_should_return_info_pre_correction_active_array_size_when_distortion_correction_mode_is_set_to_off() {
+ updateSdkVersion(Build.VERSION_CODES.P);
+
+ try {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+ Rect mockSensorInfoPreCorrectionActiveArraySize = mock(Rect.class);
+ when(mockSensorInfoPreCorrectionActiveArraySize.width()).thenReturn(100);
+ when(mockSensorInfoPreCorrectionActiveArraySize.height()).thenReturn(100);
+
+ when(mockCameraProperties.getDistortionCorrectionAvailableModes())
+ .thenReturn(
+ new int[] {
+ CaptureRequest.DISTORTION_CORRECTION_MODE_OFF,
+ CaptureRequest.DISTORTION_CORRECTION_MODE_FAST
+ });
+
+ when(mockBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE))
+ .thenReturn(CaptureRequest.DISTORTION_CORRECTION_MODE_OFF);
+ when(mockCameraProperties.getSensorInfoPreCorrectionActiveArraySize())
+ .thenReturn(mockSensorInfoPreCorrectionActiveArraySize);
+
+ try (MockedStatic mockedSizeFactory =
+ mockStatic(CameraRegionUtils.SizeFactory.class)) {
+ mockedSizeFactory
+ .when(() -> CameraRegionUtils.SizeFactory.create(anyInt(), anyInt()))
+ .thenAnswer(
+ (Answer)
+ invocation -> {
+ Size mockSize = mock(Size.class);
+ when(mockSize.getWidth()).thenReturn(invocation.getArgument(0));
+ when(mockSize.getHeight()).thenReturn(invocation.getArgument(1));
+ return mockSize;
+ });
+
+ Size result = CameraRegionUtils.getCameraBoundaries(mockCameraProperties, mockBuilder);
+
+ assertEquals(100, result.getWidth());
+ assertEquals(100, result.getHeight());
+ verify(mockCameraProperties, never()).getSensorInfoPixelArraySize();
+ verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
+ }
+ } finally {
+ updateSdkVersion(0);
+ }
+ }
+
+ @Test
+ public void
+ getCameraBoundaries_should_return_sensor_info_active_array_size_when_distortion_correction_mode_is_set() {
+ updateSdkVersion(Build.VERSION_CODES.P);
+
+ try {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+ Rect mockSensorInfoActiveArraySize = mock(Rect.class);
+ when(mockSensorInfoActiveArraySize.width()).thenReturn(100);
+ when(mockSensorInfoActiveArraySize.height()).thenReturn(100);
+
+ when(mockCameraProperties.getDistortionCorrectionAvailableModes())
+ .thenReturn(
+ new int[] {
+ CaptureRequest.DISTORTION_CORRECTION_MODE_OFF,
+ CaptureRequest.DISTORTION_CORRECTION_MODE_FAST
+ });
+
+ when(mockBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE))
+ .thenReturn(CaptureRequest.DISTORTION_CORRECTION_MODE_FAST);
+ when(mockCameraProperties.getSensorInfoActiveArraySize())
+ .thenReturn(mockSensorInfoActiveArraySize);
+
+ try (MockedStatic mockedSizeFactory =
+ mockStatic(CameraRegionUtils.SizeFactory.class)) {
+ mockedSizeFactory
+ .when(() -> CameraRegionUtils.SizeFactory.create(anyInt(), anyInt()))
+ .thenAnswer(
+ (Answer)
+ invocation -> {
+ Size mockSize = mock(Size.class);
+ when(mockSize.getWidth()).thenReturn(invocation.getArgument(0));
+ when(mockSize.getHeight()).thenReturn(invocation.getArgument(1));
+ return mockSize;
+ });
+
+ Size result = CameraRegionUtils.getCameraBoundaries(mockCameraProperties, mockBuilder);
+
+ assertEquals(100, result.getWidth());
+ assertEquals(100, result.getHeight());
+ verify(mockCameraProperties, never()).getSensorInfoPixelArraySize();
+ verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
+ }
+ } finally {
+ updateSdkVersion(0);
+ }
+ }
+
+ @Test(expected = AssertionError.class)
+ public void getMeteringRectangleForPoint_should_throw_for_x_upper_bound() {
+ CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 1.5, 0);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void getMeteringRectangleForPoint_should_throw_for_x_lower_bound() {
+ CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, -0.5, 0);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void getMeteringRectangleForPoint_should_throw_for_y_upper_bound() {
+ CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 0, 1.5);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void getMeteringRectangleForPoint_should_throw_for_y_lower_bound() {
+ CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 0, -0.5);
+ }
+
+ @Test
+ public void getMeteringRectangleForPoint_should_return_valid_MeteringRectangle() {
+ try (MockedStatic mockedMeteringRectangleFactory =
+ mockStatic(CameraRegionUtils.MeteringRectangleFactory.class)) {
+
+ mockedMeteringRectangleFactory
+ .when(
+ () ->
+ CameraRegionUtils.MeteringRectangleFactory.create(
+ anyInt(), anyInt(), anyInt(), anyInt(), anyInt()))
+ .thenAnswer(
+ new Answer() {
+ @Override
+ public MeteringRectangle answer(InvocationOnMock createInvocation)
+ throws Throwable {
+ MeteringRectangle mockMeteringRectangle = mock(MeteringRectangle.class);
+ when(mockMeteringRectangle.getX()).thenReturn(createInvocation.getArgument(0));
+ when(mockMeteringRectangle.getY()).thenReturn(createInvocation.getArgument(1));
+ when(mockMeteringRectangle.getWidth())
+ .thenReturn(createInvocation.getArgument(2));
+ when(mockMeteringRectangle.getHeight())
+ .thenReturn(createInvocation.getArgument(3));
+ when(mockMeteringRectangle.getMeteringWeight())
+ .thenReturn(createInvocation.getArgument(4));
+ when(mockMeteringRectangle.equals(any()))
+ .thenAnswer(
+ new Answer() {
+ @Override
+ public Boolean answer(InvocationOnMock equalsInvocation)
+ throws Throwable {
+ MeteringRectangle otherMockMeteringRectangle =
+ equalsInvocation.getArgument(0);
+ return mockMeteringRectangle.getX()
+ == otherMockMeteringRectangle.getX()
+ && mockMeteringRectangle.getY()
+ == otherMockMeteringRectangle.getY()
+ && mockMeteringRectangle.getWidth()
+ == otherMockMeteringRectangle.getWidth()
+ && mockMeteringRectangle.getHeight()
+ == otherMockMeteringRectangle.getHeight()
+ && mockMeteringRectangle.getMeteringWeight()
+ == otherMockMeteringRectangle.getMeteringWeight();
+ }
+ });
+ return mockMeteringRectangle;
+ }
+ });
+
+ MeteringRectangle r;
+ // Center
+ r = CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 0.5, 0.5);
+ assertTrue(CameraRegionUtils.MeteringRectangleFactory.create(45, 45, 10, 10, 1).equals(r));
+
+ // Top left
+ r = CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 0.0, 0.0);
+ assertTrue(CameraRegionUtils.MeteringRectangleFactory.create(0, 0, 10, 10, 1).equals(r));
+
+ // Bottom right
+ r = CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 1.0, 1.0);
+ assertTrue(CameraRegionUtils.MeteringRectangleFactory.create(89, 89, 10, 10, 1).equals(r));
+
+ // Top left
+ r = CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 0.0, 1.0);
+ assertTrue(CameraRegionUtils.MeteringRectangleFactory.create(0, 89, 10, 10, 1).equals(r));
+
+ // Top right
+ r = CameraRegionUtils.convertPointToMeteringRectangle(this.mockCameraBoundaries, 1.0, 0.0);
+ assertTrue(CameraRegionUtils.MeteringRectangleFactory.create(89, 0, 10, 10, 1).equals(r));
+ }
+ }
+
+ @Test(expected = AssertionError.class)
+ public void getMeteringRectangleForPoint_should_throw_for_0_width_boundary() {
+ new io.flutter.plugins.camera.CameraRegions(new Size(0, 50));
+ }
+
+ @Test(expected = AssertionError.class)
+ public void getMeteringRectangleForPoint_should_throw_for_0_height_boundary() {
+ new io.flutter.plugins.camera.CameraRegions(new Size(100, 0));
+ }
+
+ private static void updateSdkVersion(int version) {
+ TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", version);
+ }
+}
diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java
index 0aedc59ef635..4a515c6fd0ec 100644
--- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java
+++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java
@@ -6,9 +6,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -17,41 +18,48 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.MeteringRectangle;
+import android.util.Size;
import io.flutter.plugins.camera.CameraProperties;
+import io.flutter.plugins.camera.CameraRegionUtils;
import io.flutter.plugins.camera.features.Point;
-import io.flutter.plugins.camera.types.CameraRegions;
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
public class ExposurePointFeatureTest {
+
+ Size mockCameraBoundaries;
+
+ @Before
+ public void setUp() {
+ this.mockCameraBoundaries = mock(Size.class);
+ when(this.mockCameraBoundaries.getWidth()).thenReturn(100);
+ when(this.mockCameraBoundaries.getHeight()).thenReturn(100);
+ }
+
@Test
public void getDebugName_should_return_the_name_of_the_feature() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
+ CameraRegionUtils mockCameraRegions = mock(CameraRegionUtils.class);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
assertEquals("ExposurePointFeature", exposurePointFeature.getDebugName());
}
@Test
- public void getValue_should_return_default_point_if_not_set() {
+ public void getValue_should_return_null_if_not_set() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
- Point expectedPoint = new Point(0.0, 0.0);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
Point actualPoint = exposurePointFeature.getValue();
-
- assertEquals(expectedPoint.x, actualPoint.x);
- assertEquals(expectedPoint.y, actualPoint.y);
+ assertNull(exposurePointFeature.getValue());
}
@Test
public void getValue_should_echo_the_set_value() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
Point expectedPoint = new Point(0.0, 0.0);
exposurePointFeature.setValue(expectedPoint);
@@ -63,45 +71,114 @@ public void getValue_should_echo_the_set_value() {
@Test
public void setValue_should_reset_point_when_x_coord_is_null() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
exposurePointFeature.setValue(new Point(null, 0.0));
- verify(mockCameraRegions, times(1)).resetAutoExposureMeteringRectangle();
+ assertNull(exposurePointFeature.getValue());
}
@Test
public void setValue_should_reset_point_when_y_coord_is_null() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
exposurePointFeature.setValue(new Point(0.0, null));
- verify(mockCameraRegions, times(1)).resetAutoExposureMeteringRectangle();
+ assertNull(exposurePointFeature.getValue());
}
@Test
- public void setValue_should_reset_point_when_valid_coords_are_supplied() {
+ public void setValue_should_set_point_when_valid_coords_are_supplied() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
Point point = new Point(0.0, 0.0);
exposurePointFeature.setValue(point);
- verify(mockCameraRegions, times(1)).setAutoExposureMeteringRectangleFromPoint(point.x, point.y);
+ assertEquals(point, exposurePointFeature.getValue());
+ }
+
+ @Test
+ public void
+ setValue_should_determine_metering_rectangle_when_valid_boundaries_and_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ Size mockedCameraBoundaries = mock(Size.class);
+ exposurePointFeature.setCameraBoundaries(mockedCameraBoundaries);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+
+ exposurePointFeature.setValue(new Point(0.5, 0.5));
+
+ mockedCameraRegionUtils.verify(
+ () -> CameraRegionUtils.convertPointToMeteringRectangle(mockedCameraBoundaries, 0.5, 0.5),
+ times(1));
+ }
+ }
+
+ @Test(expected = AssertionError.class)
+ public void setValue_should_throw_assertion_error_when_no_valid_boundaries_are_set() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+ exposurePointFeature.setValue(new Point(0.5, 0.5));
+ }
+ }
+
+ @Test
+ public void setValue_should_not_determine_metering_rectangle_when_null_coords_are_set() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ Size mockedCameraBoundaries = mock(Size.class);
+ exposurePointFeature.setCameraBoundaries(mockedCameraBoundaries);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+
+ exposurePointFeature.setValue(null);
+ exposurePointFeature.setValue(new Point(null, 0.5));
+ exposurePointFeature.setValue(new Point(0.5, null));
+
+ mockedCameraRegionUtils.verifyNoInteractions();
+ }
+ }
+
+ @Test
+ public void
+ setCameraBoundaries_should_determine_metering_rectangle_when_valid_boundaries_and_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+ exposurePointFeature.setValue(new Point(0.5, 0.5));
+ Size mockedCameraBoundaries = mock(Size.class);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+
+ exposurePointFeature.setCameraBoundaries(mockedCameraBoundaries);
+
+ mockedCameraRegionUtils.verify(
+ () -> CameraRegionUtils.convertPointToMeteringRectangle(mockedCameraBoundaries, 0.5, 0.5),
+ times(1));
+ }
}
@Test
public void checkIsSupported_should_return_false_when_max_regions_is_null() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, null);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(new Size(100, 100));
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(null);
@@ -111,8 +188,8 @@ public void checkIsSupported_should_return_false_when_max_regions_is_null() {
@Test
public void checkIsSupported_should_return_false_when_max_regions_is_zero() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, null);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(new Size(100, 100));
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(0);
@@ -122,8 +199,8 @@ public void checkIsSupported_should_return_false_when_max_regions_is_zero() {
@Test
public void checkIsSupported_should_return_true_when_max_regions_is_bigger_then_zero() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, null);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(new Size(100, 100));
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
@@ -133,64 +210,72 @@ public void checkIsSupported_should_return_true_when_max_regions_is_bigger_then_
@Test
public void updateBuilder_should_return_when_checkIsSupported_is_false() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(0);
- exposurePointFeature.updateBuilder(null);
+ exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
- verify(mockCameraRegions, never()).getAEMeteringRectangle();
+ verify(mockCaptureRequestBuilder, never()).set(any(), any());
}
@Test
- public void updateBuilder_should_set_ae_regions_to_null_when_ae_metering_rectangle_is_null() {
+ public void
+ updateBuilder_should_set_metering_rectangle_when_valid_boundaries_and_coords_are_supplied() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
-
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
- when(mockCameraRegions.getAEMeteringRectangle()).thenReturn(null);
-
- exposurePointFeature.updateBuilder(mockBuilder);
-
- verify(mockBuilder, times(1)).set(CaptureRequest.CONTROL_AE_REGIONS, null);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ Size mockedCameraBoundaries = mock(Size.class);
+ MeteringRectangle mockedMeteringRectangle = mock(MeteringRectangle.class);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+ mockedCameraRegionUtils
+ .when(
+ () ->
+ CameraRegionUtils.convertPointToMeteringRectangle(
+ mockedCameraBoundaries, 0.5, 0.5))
+ .thenReturn(mockedMeteringRectangle);
+ exposurePointFeature.setCameraBoundaries(mockedCameraBoundaries);
+ exposurePointFeature.setValue(new Point(0.5, 0.5));
+
+ exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
+ }
+
+ verify(mockCaptureRequestBuilder, times(1))
+ .set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[] {mockedMeteringRectangle});
}
@Test
- public void updateBuilder_should_set_ae_regions_with_metering_rectangle() {
+ public void
+ updateBuilder_should_not_set_metering_rectangle_when_no_valid_boundaries_are_supplied() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
- MeteringRectangle meteringRectangle = new MeteringRectangle(0, 0, 0, 0, 0);
-
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
- when(mockCameraRegions.getAEMeteringRectangle()).thenReturn(meteringRectangle);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ MeteringRectangle mockedMeteringRectangle = mock(MeteringRectangle.class);
- exposurePointFeature.updateBuilder(mockBuilder);
+ exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
- verify(mockBuilder, times(1))
- .set(eq(CaptureRequest.CONTROL_AE_REGIONS), any(MeteringRectangle[].class));
+ verify(mockCaptureRequestBuilder, times(1)).set(any(), isNull());
}
@Test
- public void updateBuilder_should_silently_fail_when_exception_occurs() {
+ public void updateBuilder_should_not_set_metering_rectangle_when_no_valid_coords_are_supplied() {
CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CameraRegions mockCameraRegions = mock(CameraRegions.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
- ExposurePointFeature exposurePointFeature =
- new ExposurePointFeature(mockCameraProperties, mockCameraRegions);
-
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
- when(mockCameraRegions.getAEMeteringRectangle()).thenThrow(new IllegalArgumentException());
-
- exposurePointFeature.updateBuilder(mockBuilder);
-
- verify(mockBuilder, times(1)).set(CaptureRequest.CONTROL_AE_REGIONS, null);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ ExposurePointFeature exposurePointFeature = new ExposurePointFeature(mockCameraProperties);
+ exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+
+ 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());
}
}
diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/focuspoint/FocusPointFeatureTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/focuspoint/FocusPointFeatureTest.java
new file mode 100644
index 000000000000..d158336ef235
--- /dev/null
+++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/focuspoint/FocusPointFeatureTest.java
@@ -0,0 +1,281 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.camera.features.focuspoint;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+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.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.util.Size;
+import io.flutter.plugins.camera.CameraProperties;
+import io.flutter.plugins.camera.CameraRegionUtils;
+import io.flutter.plugins.camera.features.Point;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+public class FocusPointFeatureTest {
+
+ Size mockCameraBoundaries;
+
+ @Before
+ public void setUp() {
+ this.mockCameraBoundaries = mock(Size.class);
+ when(this.mockCameraBoundaries.getWidth()).thenReturn(100);
+ when(this.mockCameraBoundaries.getHeight()).thenReturn(100);
+ }
+
+ @Test
+ public void getDebugName_should_return_the_name_of_the_feature() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CameraRegionUtils mockCameraRegions = mock(CameraRegionUtils.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+
+ assertEquals("FocusPointFeature", focusPointFeature.getDebugName());
+ }
+
+ @Test
+ public void getValue_should_return_null_if_not_set() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ Point actualPoint = focusPointFeature.getValue();
+ assertNull(focusPointFeature.getValue());
+ }
+
+ @Test
+ public void getValue_should_echo_the_set_value() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+ Point expectedPoint = new Point(0.0, 0.0);
+
+ focusPointFeature.setValue(expectedPoint);
+ Point actualPoint = focusPointFeature.getValue();
+
+ assertEquals(expectedPoint, actualPoint);
+ }
+
+ @Test
+ public void setValue_should_reset_point_when_x_coord_is_null() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+
+ focusPointFeature.setValue(new Point(null, 0.0));
+
+ assertNull(focusPointFeature.getValue());
+ }
+
+ @Test
+ public void setValue_should_reset_point_when_y_coord_is_null() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+
+ focusPointFeature.setValue(new Point(0.0, null));
+
+ assertNull(focusPointFeature.getValue());
+ }
+
+ @Test
+ public void setValue_should_set_point_when_valid_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+ Point point = new Point(0.0, 0.0);
+
+ focusPointFeature.setValue(point);
+
+ assertEquals(point, focusPointFeature.getValue());
+ }
+
+ @Test
+ public void
+ setValue_should_determine_metering_rectangle_when_valid_boundaries_and_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ Size mockedCameraBoundaries = mock(Size.class);
+ focusPointFeature.setCameraBoundaries(mockedCameraBoundaries);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+
+ focusPointFeature.setValue(new Point(0.5, 0.5));
+
+ mockedCameraRegionUtils.verify(
+ () -> CameraRegionUtils.convertPointToMeteringRectangle(mockedCameraBoundaries, 0.5, 0.5),
+ times(1));
+ }
+ }
+
+ @Test(expected = AssertionError.class)
+ public void setValue_should_throw_assertion_error_when_no_valid_boundaries_are_set() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+ focusPointFeature.setValue(new Point(0.5, 0.5));
+ }
+ }
+
+ @Test
+ public void setValue_should_not_determine_metering_rectangle_when_null_coords_are_set() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ Size mockedCameraBoundaries = mock(Size.class);
+ focusPointFeature.setCameraBoundaries(mockedCameraBoundaries);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+
+ focusPointFeature.setValue(null);
+ focusPointFeature.setValue(new Point(null, 0.5));
+ focusPointFeature.setValue(new Point(0.5, null));
+
+ mockedCameraRegionUtils.verifyNoInteractions();
+ }
+ }
+
+ @Test
+ public void
+ setCameraBoundaries_should_determine_metering_rectangle_when_valid_boundaries_and_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+ focusPointFeature.setValue(new Point(0.5, 0.5));
+ Size mockedCameraBoundaries = mock(Size.class);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+
+ focusPointFeature.setCameraBoundaries(mockedCameraBoundaries);
+
+ mockedCameraRegionUtils.verify(
+ () -> CameraRegionUtils.convertPointToMeteringRectangle(mockedCameraBoundaries, 0.5, 0.5),
+ times(1));
+ }
+ }
+
+ @Test
+ public void checkIsSupported_should_return_false_when_max_regions_is_null() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(new Size(100, 100));
+
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(null);
+
+ assertFalse(focusPointFeature.checkIsSupported());
+ }
+
+ @Test
+ public void checkIsSupported_should_return_false_when_max_regions_is_zero() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(new Size(100, 100));
+
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(0);
+
+ assertFalse(focusPointFeature.checkIsSupported());
+ }
+
+ @Test
+ public void checkIsSupported_should_return_true_when_max_regions_is_bigger_then_zero() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(new Size(100, 100));
+
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+
+ assertTrue(focusPointFeature.checkIsSupported());
+ }
+
+ @Test
+ public void updateBuilder_should_return_when_checkIsSupported_is_false() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(0);
+
+ focusPointFeature.updateBuilder(mockCaptureRequestBuilder);
+
+ verify(mockCaptureRequestBuilder, never()).set(any(), any());
+ }
+
+ @Test
+ public void
+ updateBuilder_should_set_metering_rectangle_when_valid_boundaries_and_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ Size mockedCameraBoundaries = mock(Size.class);
+ MeteringRectangle mockedMeteringRectangle = mock(MeteringRectangle.class);
+
+ try (MockedStatic mockedCameraRegionUtils =
+ Mockito.mockStatic(CameraRegionUtils.class)) {
+ mockedCameraRegionUtils
+ .when(
+ () ->
+ CameraRegionUtils.convertPointToMeteringRectangle(
+ mockedCameraBoundaries, 0.5, 0.5))
+ .thenReturn(mockedMeteringRectangle);
+ focusPointFeature.setCameraBoundaries(mockedCameraBoundaries);
+ focusPointFeature.setValue(new Point(0.5, 0.5));
+
+ focusPointFeature.updateBuilder(mockCaptureRequestBuilder);
+ }
+
+ verify(mockCaptureRequestBuilder, times(1))
+ .set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[] {mockedMeteringRectangle});
+ }
+
+ @Test
+ public void
+ updateBuilder_should_not_set_metering_rectangle_when_no_valid_boundaries_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ MeteringRectangle mockedMeteringRectangle = mock(MeteringRectangle.class);
+
+ focusPointFeature.updateBuilder(mockCaptureRequestBuilder);
+
+ verify(mockCaptureRequestBuilder, times(1)).set(any(), isNull());
+ }
+
+ @Test
+ public void updateBuilder_should_not_set_metering_rectangle_when_no_valid_coords_are_supplied() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ when(mockCameraProperties.getControlMaxRegionsAutoFocus()).thenReturn(1);
+ CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
+ FocusPointFeature focusPointFeature = new FocusPointFeature(mockCameraProperties);
+ focusPointFeature.setCameraBoundaries(this.mockCameraBoundaries);
+
+ focusPointFeature.setValue(null);
+ focusPointFeature.updateBuilder(mockCaptureRequestBuilder);
+ focusPointFeature.setValue(new Point(0d, null));
+ focusPointFeature.updateBuilder(mockCaptureRequestBuilder);
+ focusPointFeature.setValue(new Point(null, 0d));
+ focusPointFeature.updateBuilder(mockCaptureRequestBuilder);
+ verify(mockCaptureRequestBuilder, times(3)).set(any(), isNull());
+ }
+}
diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/CameraRegionsFactoryTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/CameraRegionsFactoryTest.java
deleted file mode 100644
index 5fa0c2c4a2a4..000000000000
--- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/CameraRegionsFactoryTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package io.flutter.plugins.camera.types;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.hardware.camera2.CaptureRequest;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.util.Size;
-import io.flutter.plugins.camera.CameraProperties;
-import io.flutter.plugins.camera.utils.TestUtils;
-import org.junit.Before;
-import org.junit.Test;
-
-public class CameraRegionsFactoryTest {
- private Size mockSize;
-
- @Before
- public void before() {
- mockSize = mock(Size.class);
-
- when(mockSize.getHeight()).thenReturn(640);
- when(mockSize.getWidth()).thenReturn(480);
- }
-
- @Test
- public void
- create_should_initialize_with_sensor_info_pixel_array_size_when_running_pre_android_p() {
- updateSdkVersion(VERSION_CODES.O_MR1);
-
- try {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
-
- when(mockCameraProperties.getSensorInfoPixelArraySize()).thenReturn(mockSize);
-
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertEquals(mockSize, cameraRegions.getBoundaries());
- verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
- verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
- } finally {
- updateSdkVersion(0);
- }
- }
-
- @Test
- public void
- create_should_initialize_with_sensor_info_pixel_array_size_when_distortion_correction_is_null() {
- updateSdkVersion(VERSION_CODES.P);
-
- try {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
-
- when(mockCameraProperties.getDistortionCorrectionAvailableModes()).thenReturn(null);
- when(mockCameraProperties.getSensorInfoPixelArraySize()).thenReturn(mockSize);
-
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertEquals(mockSize, cameraRegions.getBoundaries());
- verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
- verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
- } finally {
- updateSdkVersion(0);
- }
- }
-
- @Test
- public void
- create_should_initialize_with_sensor_info_pixel_array_size_when_distortion_correction_is_off() {
- updateSdkVersion(VERSION_CODES.P);
-
- try {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
-
- when(mockCameraProperties.getDistortionCorrectionAvailableModes())
- .thenReturn(new int[] {CaptureRequest.DISTORTION_CORRECTION_MODE_OFF});
- when(mockCameraProperties.getSensorInfoPixelArraySize()).thenReturn(mockSize);
-
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertEquals(mockSize, cameraRegions.getBoundaries());
- verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
- verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
- } finally {
- updateSdkVersion(0);
- }
- }
-
- @Test
- public void
- create_should_initialize_with_sensor_info_pre_correction_active_array_size_when_distortion_correction_mode_is_set_to_null() {
- updateSdkVersion(VERSION_CODES.P);
-
- try {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
-
- when(mockCameraProperties.getDistortionCorrectionAvailableModes())
- .thenReturn(
- new int[] {
- CaptureRequest.DISTORTION_CORRECTION_MODE_OFF,
- CaptureRequest.DISTORTION_CORRECTION_MODE_FAST
- });
-
- when(mockBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE)).thenReturn(null);
- when(mockCameraProperties.getSensorInfoPreCorrectionActiveArraySize()).thenReturn(null);
-
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertNull(cameraRegions.getBoundaries());
- verify(mockCameraProperties, never()).getSensorInfoPixelArraySize();
- verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
- } finally {
- updateSdkVersion(0);
- }
- }
-
- @Test
- public void
- create_should_initialize_with_sensor_info_pre_correction_active_array_size_when_distortion_correction_mode_is_set_off() {
- updateSdkVersion(VERSION_CODES.P);
-
- try {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
-
- when(mockCameraProperties.getDistortionCorrectionAvailableModes())
- .thenReturn(
- new int[] {
- CaptureRequest.DISTORTION_CORRECTION_MODE_OFF,
- CaptureRequest.DISTORTION_CORRECTION_MODE_FAST
- });
-
- when(mockBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE))
- .thenReturn(CaptureRequest.DISTORTION_CORRECTION_MODE_OFF);
- when(mockCameraProperties.getSensorInfoPreCorrectionActiveArraySize()).thenReturn(null);
-
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertNull(cameraRegions.getBoundaries());
- verify(mockCameraProperties, never()).getSensorInfoPixelArraySize();
- verify(mockCameraProperties, never()).getSensorInfoActiveArraySize();
- } finally {
- updateSdkVersion(0);
- }
- }
-
- @Test
- public void
- ctor_should_initialize_with_sensor_info_active_array_size_when_distortion_correction_mode_is_set() {
- updateSdkVersion(VERSION_CODES.P);
-
- try {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
-
- when(mockCameraProperties.getDistortionCorrectionAvailableModes())
- .thenReturn(
- new int[] {
- CaptureRequest.DISTORTION_CORRECTION_MODE_OFF,
- CaptureRequest.DISTORTION_CORRECTION_MODE_FAST
- });
-
- when(mockBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE))
- .thenReturn(CaptureRequest.DISTORTION_CORRECTION_MODE_FAST);
- when(mockCameraProperties.getSensorInfoActiveArraySize()).thenReturn(null);
-
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertNull(cameraRegions.getBoundaries());
- verify(mockCameraProperties, never()).getSensorInfoPixelArraySize();
- verify(mockCameraProperties, never()).getSensorInfoPreCorrectionActiveArraySize();
- } finally {
- updateSdkVersion(0);
- }
- }
-
- @Test
- public void getBoundaries_should_return_null_if_not_set() {
- CameraProperties mockCameraProperties = mock(CameraProperties.class);
- CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
- CameraRegions cameraRegions = CameraRegions.Factory.create(mockCameraProperties, mockBuilder);
-
- assertNull(cameraRegions.getBoundaries());
- }
-
- private static void updateSdkVersion(int version) {
- TestUtils.setFinalStatic(VERSION.class, "SDK_INT", version);
- }
-}
diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/CameraRegionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/CameraRegionsTest.java
deleted file mode 100644
index b760e1e9ca29..000000000000
--- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/CameraRegionsTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package io.flutter.plugins.camera.types;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.hardware.camera2.params.MeteringRectangle;
-import android.util.Size;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public class CameraRegionsTest {
- io.flutter.plugins.camera.types.CameraRegions cameraRegions;
-
- @Before
- public void setUp() {
- this.cameraRegions = new io.flutter.plugins.camera.types.CameraRegions(new Size(100, 100));
- }
-
- @Test(expected = AssertionError.class)
- public void getMeteringRectangleForPoint_should_throw_for_x_upper_bound() {
- cameraRegions.convertPointToMeteringRectangle(1.5, 0);
- }
-
- @Test(expected = AssertionError.class)
- public void getMeteringRectangleForPoint_should_throw_for_x_lower_bound() {
- cameraRegions.convertPointToMeteringRectangle(-0.5, 0);
- }
-
- @Test(expected = AssertionError.class)
- public void getMeteringRectangleForPoint_should_throw_for_y_upper_bound() {
- cameraRegions.convertPointToMeteringRectangle(0, 1.5);
- }
-
- @Test(expected = AssertionError.class)
- public void getMeteringRectangleForPoint_should_throw_for_y_lower_bound() {
- cameraRegions.convertPointToMeteringRectangle(0, -0.5);
- }
-
- @Test
- public void getMeteringRectangleForPoint_should_return_valid_MeteringRectangle() {
- MeteringRectangle r;
- // Center
- r = cameraRegions.convertPointToMeteringRectangle(0.5, 0.5);
- assertEquals(new MeteringRectangle(45, 45, 10, 10, 1), r);
-
- // Top left
- r = cameraRegions.convertPointToMeteringRectangle(0.0, 0.0);
- assertEquals(new MeteringRectangle(0, 0, 10, 10, 1), r);
-
- // Bottom right
- r = cameraRegions.convertPointToMeteringRectangle(1.0, 1.0);
- assertEquals(new MeteringRectangle(89, 89, 10, 10, 1), r);
-
- // Top left
- r = cameraRegions.convertPointToMeteringRectangle(0.0, 1.0);
- assertEquals(new MeteringRectangle(0, 89, 10, 10, 1), r);
-
- // Top right
- r = cameraRegions.convertPointToMeteringRectangle(1.0, 0.0);
- assertEquals(new MeteringRectangle(89, 0, 10, 10, 1), r);
- }
-
- @Test(expected = AssertionError.class)
- public void constructor_should_throw_for_0_width_boundary() {
- new io.flutter.plugins.camera.CameraRegions(new Size(0, 50));
- }
-
- @Test(expected = AssertionError.class)
- public void constructor_should_throw_for_0_height_boundary() {
- new io.flutter.plugins.camera.CameraRegions(new Size(100, 0));
- }
-
- @Test
- public void setAutoExposureMeteringRectangleFromPoint_should_set_aeMeteringRectangle_for_point() {
- cameraRegions.setAutoExposureMeteringRectangleFromPoint(0, 0);
- assertEquals(new MeteringRectangle(0, 0, 10, 10, 1), cameraRegions.getAEMeteringRectangle());
- }
-
- @Test
- public void resetAutoExposureMeteringRectangle_should_reset_aeMeteringRectangle() {
- io.flutter.plugins.camera.types.CameraRegions cr =
- new io.flutter.plugins.camera.types.CameraRegions(new Size(100, 50));
- cr.setAutoExposureMeteringRectangleFromPoint(0, 0);
- assertNotNull(cr.getAEMeteringRectangle());
- cr.resetAutoExposureMeteringRectangle();
- assertNull(cr.getAEMeteringRectangle());
- }
-
- @Test
- public void setAutoFocusMeteringRectangleFromPoint_should_set_afMeteringRectangle_for_point() {
- io.flutter.plugins.camera.types.CameraRegions cr =
- new io.flutter.plugins.camera.types.CameraRegions(new Size(100, 50));
- cr.setAutoFocusMeteringRectangleFromPoint(0, 0);
- assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), cr.getAFMeteringRectangle());
- }
-
- @Test
- public void resetAutoFocusMeteringRectangle_should_reset_afMeteringRectangle() {
- io.flutter.plugins.camera.types.CameraRegions cr =
- new io.flutter.plugins.camera.types.CameraRegions(new Size(100, 50));
- cr.setAutoFocusMeteringRectangleFromPoint(0, 0);
- assertNotNull(cr.getAFMeteringRectangle());
- cr.resetAutoFocusMeteringRectangle();
- assertNull(cr.getAFMeteringRectangle());
- }
-}