Skip to content

Commit 867f2a4

Browse files
authored
[camera_android] Provides a default exposure point if null. (flutter#3851)
Recently we had problems in our apps (they use the camera a lot), due to the error of [CONTROL_AE_REGIONS] being set to a null value. It should now return the default exposure point value. Thanks https://github.com/AnggaSP Fix attempt for flutter#105200
1 parent dab5a77 commit 867f2a4

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

packages/camera/camera_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.10.8+5
2+
3+
* Provides a default exposure point if null.
4+
15
## 0.10.8+4
26

37
* Adjusts SDK checks for better testability.

packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeature.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.util.Size;
1111
import androidx.annotation.NonNull;
1212
import androidx.annotation.Nullable;
13+
import androidx.annotation.VisibleForTesting;
1314
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
1415
import io.flutter.plugins.camera.CameraProperties;
1516
import io.flutter.plugins.camera.CameraRegionUtils;
@@ -24,6 +25,8 @@ public class ExposurePointFeature extends CameraFeature<Point> {
2425
@Nullable private Point exposurePoint;
2526
private MeteringRectangle exposureRectangle;
2627
@NonNull private final SensorOrientationFeature sensorOrientationFeature;
28+
private boolean defaultRegionsHasBeenSet = false;
29+
@VisibleForTesting @Nullable public MeteringRectangle[] defaultRegions;
2730

2831
/**
2932
* Creates a new instance of the {@link ExposurePointFeature}.
@@ -78,9 +81,18 @@ public void updateBuilder(@NonNull CaptureRequest.Builder requestBuilder) {
7881
if (!checkIsSupported()) {
7982
return;
8083
}
81-
requestBuilder.set(
82-
CaptureRequest.CONTROL_AE_REGIONS,
83-
exposureRectangle == null ? null : new MeteringRectangle[] {exposureRectangle});
84+
85+
if (!defaultRegionsHasBeenSet) {
86+
defaultRegions = requestBuilder.get(CaptureRequest.CONTROL_AE_REGIONS);
87+
defaultRegionsHasBeenSet = true;
88+
}
89+
90+
if (exposureRectangle != null) {
91+
requestBuilder.set(
92+
CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[] {exposureRectangle});
93+
} else {
94+
requestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, defaultRegions);
95+
}
8496
}
8597

8698
private void buildExposureRectangle() {

packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/exposurepoint/ExposurePointFeatureTest.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import static org.junit.Assert.assertNull;
1010
import static org.junit.Assert.assertTrue;
1111
import static org.mockito.ArgumentMatchers.any;
12-
import static org.mockito.ArgumentMatchers.isNull;
12+
import static org.mockito.ArgumentMatchers.eq;
1313
import static org.mockito.Mockito.mock;
1414
import static org.mockito.Mockito.never;
1515
import static org.mockito.Mockito.times;
@@ -281,7 +281,7 @@ public void updateBuilder_shouldSetMeteringRectangleWhenValidBoundariesAndCoords
281281
}
282282

283283
@Test
284-
public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidBoundariesAreSupplied() {
284+
public void updateBuilder_shoulSetDefaultMeteringRectangleWhenNoValidBoundariesAreSupplied() {
285285
CameraProperties mockCameraProperties = mock(CameraProperties.class);
286286
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
287287
CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
@@ -290,24 +290,52 @@ public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidBoundariesAreS
290290

291291
exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
292292

293-
verify(mockCaptureRequestBuilder, times(1)).set(any(), isNull());
293+
verify(mockCaptureRequestBuilder, times(1)).set(any(), any());
294294
}
295295

296296
@Test
297-
public void updateBuilder_shouldNotSetMeteringRectangleWhenNoValidCoordsAreSupplied() {
297+
public void updateBuilder_shouldSetDefaultMeteringRectangleWhenNoValidCoordsAreSupplied() {
298298
CameraProperties mockCameraProperties = mock(CameraProperties.class);
299299
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
300300
CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
301301
ExposurePointFeature exposurePointFeature =
302302
new ExposurePointFeature(mockCameraProperties, mockSensorOrientationFeature);
303303
exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
304304

305+
MeteringRectangle[] defaultRegions =
306+
new MeteringRectangle[] {new MeteringRectangle(0, 0, 100, 100, 0)};
307+
when(mockCaptureRequestBuilder.get(CaptureRequest.CONTROL_AE_REGIONS))
308+
.thenReturn(defaultRegions);
309+
305310
exposurePointFeature.setValue(null);
306311
exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
307312
exposurePointFeature.setValue(new Point(0d, null));
308313
exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
309314
exposurePointFeature.setValue(new Point(null, 0d));
310315
exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
311-
verify(mockCaptureRequestBuilder, times(3)).set(any(), isNull());
316+
317+
verify(mockCaptureRequestBuilder, times(3)).set(any(), eq(defaultRegions));
318+
}
319+
320+
@Test
321+
public void updateBuilder_shouldSetNonNullMeteringRectangleWhenNullValueIsSupplied() {
322+
CameraProperties mockCameraProperties = mock(CameraProperties.class);
323+
when(mockCameraProperties.getControlMaxRegionsAutoExposure()).thenReturn(1);
324+
CaptureRequest.Builder mockCaptureRequestBuilder = mock(CaptureRequest.Builder.class);
325+
ExposurePointFeature exposurePointFeature =
326+
new ExposurePointFeature(mockCameraProperties, mockSensorOrientationFeature);
327+
328+
MeteringRectangle[] defaultRegions =
329+
new MeteringRectangle[] {new MeteringRectangle(0, 0, 100, 100, 0)};
330+
when(mockCaptureRequestBuilder.get(CaptureRequest.CONTROL_AE_REGIONS))
331+
.thenReturn(defaultRegions);
332+
333+
exposurePointFeature.setCameraBoundaries(this.mockCameraBoundaries);
334+
335+
exposurePointFeature.setValue(null);
336+
337+
exposurePointFeature.updateBuilder(mockCaptureRequestBuilder);
338+
339+
verify(mockCaptureRequestBuilder, times(1)).set(any(), eq(exposurePointFeature.defaultRegions));
312340
}
313341
}

packages/camera/camera_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Android implementation of the camera plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
55

6-
version: 0.10.8+4
6+
version: 0.10.8+5
77

88
environment:
99
sdk: ">=2.18.0 <4.0.0"

0 commit comments

Comments
 (0)