diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/flash/FlashMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/flash/FlashMode.java index d4a5ee0ab12f..788c768e0b3c 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/flash/FlashMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/flash/FlashMode.java @@ -17,6 +17,15 @@ public enum FlashMode { this.strValue = strValue; } + /** + * Tries to convert the supplied string into a {@see FlashMode} enum value. + * + *
When the supplied string doesn't match a valid {@see FlashMode} enum value, null is
+ * returned.
+ *
+ * @param modeStr String value to convert into an {@see FlashMode} enum value.
+ * @return Matching {@see FlashMode} enum value, or null if no match is found.
+ */
public static FlashMode getValueForString(String modeStr) {
for (FlashMode value : values()) {
if (value.strValue.equals(modeStr)) return value;
diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionFeature.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionFeature.java
new file mode 100644
index 000000000000..847a817641ab
--- /dev/null
+++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionFeature.java
@@ -0,0 +1,94 @@
+// 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.noisereduction;
+
+import android.hardware.camera2.CaptureRequest;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.util.Log;
+import io.flutter.plugins.camera.CameraProperties;
+import io.flutter.plugins.camera.features.CameraFeature;
+import java.util.HashMap;
+
+/**
+ * This can either be enabled or disabled. Only full capability devices can set this to off. Legacy
+ * and full support the fast mode.
+ * https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
+ */
+public class NoiseReductionFeature extends CameraFeature Full-capability camera devices will always support OFF and FAST. Camera devices that
+ * support YUV_REPROCESSING or PRIVATE_REPROCESSING will support ZERO_SHUTTER_LAG.
+ * Legacy-capability camera devices will only support FAST mode.
+ */
+
+ // Can be null on some devices.
+ int[] modes = cameraProperties.getAvailableNoiseReductionModes();
+
+ /// If there's at least one mode available then we are supported.
+ return modes != null && modes.length > 0;
+ }
+
+ @Override
+ public void updateBuilder(CaptureRequest.Builder requestBuilder) {
+ if (!checkIsSupported()) {
+ return;
+ }
+
+ Log.i("Camera", "updateNoiseReduction | currentSetting: " + currentSetting);
+
+ // Always use fast mode.
+ requestBuilder.set(
+ CaptureRequest.NOISE_REDUCTION_MODE, NOISE_REDUCTION_MODES.get(currentSetting));
+ }
+}
diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionMode.java
new file mode 100644
index 000000000000..425a458e2a2b
--- /dev/null
+++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionMode.java
@@ -0,0 +1,41 @@
+// 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.noisereduction;
+
+/** Only supports fast mode for now. */
+public enum NoiseReductionMode {
+ off("off"),
+ fast("fast"),
+ highQuality("highQuality"),
+ minimal("minimal"),
+ zeroShutterLag("zeroShutterLag");
+
+ private final String strValue;
+
+ NoiseReductionMode(String strValue) {
+ this.strValue = strValue;
+ }
+
+ /**
+ * Tries to convert the supplied string into a {@see NoiseReductionMode} enum value.
+ *
+ * When the supplied string doesn't match a valid {@see NoiseReductionMode} enum value, null is
+ * returned.
+ *
+ * @param modeStr String value to convert into an {@see NoiseReductionMode} enum value.
+ * @return Matching {@see NoiseReductionMode} enum value, or null if no match is found.
+ */
+ public static NoiseReductionMode getValueForString(String modeStr) {
+ for (NoiseReductionMode value : values()) {
+ if (value.strValue.equals(modeStr)) return value;
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return strValue;
+ }
+}
diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionFeatureTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionFeatureTest.java
new file mode 100644
index 000000000000..eb1a639a2ac3
--- /dev/null
+++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/features/noisereduction/NoiseReductionFeatureTest.java
@@ -0,0 +1,151 @@
+// 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.noisereduction;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+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.os.Build.VERSION;
+import io.flutter.plugins.camera.CameraProperties;
+import io.flutter.plugins.camera.utils.TestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NoiseReductionFeatureTest {
+ @Before
+ public void before() {
+ // Make sure the VERSION.SDK_INT field returns 23, to allow using all available
+ // noise reduction modes in tests.
+ TestUtils.setFinalStatic(VERSION.class, "SDK_INT", 23);
+ }
+
+ @After
+ public void after() {
+ // Make sure we reset the VERSION.SDK_INT field to it's original value.
+ TestUtils.setFinalStatic(VERSION.class, "SDK_INT", 0);
+ }
+
+ @Test
+ public void getDebugName_should_return_the_name_of_the_feature() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ assertEquals("NoiseReductionFeature", noiseReductionFeature.getDebugName());
+ }
+
+ @Test
+ public void getValue_should_return_fast_if_not_set() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ assertEquals(NoiseReductionMode.fast, noiseReductionFeature.getValue());
+ }
+
+ @Test
+ public void getValue_should_echo_the_set_value() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+ NoiseReductionMode expectedValue = NoiseReductionMode.fast;
+
+ noiseReductionFeature.setValue(expectedValue);
+ NoiseReductionMode actualValue = noiseReductionFeature.getValue();
+
+ assertEquals(expectedValue, actualValue);
+ }
+
+ @Test
+ public void checkIsSupported_should_return_false_when_available_noise_reduction_modes_is_null() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ when(mockCameraProperties.getAvailableNoiseReductionModes()).thenReturn(null);
+
+ assertFalse(noiseReductionFeature.checkIsSupported());
+ }
+
+ @Test
+ public void
+ checkIsSupported_should_return_false_when_available_noise_reduction_modes_returns_an_empty_array() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ when(mockCameraProperties.getAvailableNoiseReductionModes()).thenReturn(new int[] {});
+
+ assertFalse(noiseReductionFeature.checkIsSupported());
+ }
+
+ @Test
+ public void
+ checkIsSupported_should_return_true_when_available_noise_reduction_modes_returns_at_least_one_item() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ when(mockCameraProperties.getAvailableNoiseReductionModes()).thenReturn(new int[] {1});
+
+ assertTrue(noiseReductionFeature.checkIsSupported());
+ }
+
+ @Test
+ public void updateBuilder_should_return_when_checkIsSupported_is_false() {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ when(mockCameraProperties.getAvailableNoiseReductionModes()).thenReturn(new int[] {});
+
+ noiseReductionFeature.updateBuilder(mockBuilder);
+
+ verify(mockBuilder, never()).set(any(), any());
+ }
+
+ @Test
+ public void updateBuilder_should_set_noise_reduction_mode_off_when_off() {
+ testUpdateBuilderWith(NoiseReductionMode.off, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
+ }
+
+ @Test
+ public void updateBuilder_should_set_noise_reduction_mode_fast_when_fast() {
+ testUpdateBuilderWith(NoiseReductionMode.fast, CaptureRequest.NOISE_REDUCTION_MODE_FAST);
+ }
+
+ @Test
+ public void updateBuilder_should_set_noise_reduction_mode_high_quality_when_high_quality() {
+ testUpdateBuilderWith(
+ NoiseReductionMode.highQuality, CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
+ }
+
+ @Test
+ public void updateBuilder_should_set_noise_reduction_mode_minimal_when_minimal() {
+ testUpdateBuilderWith(NoiseReductionMode.minimal, CaptureRequest.NOISE_REDUCTION_MODE_MINIMAL);
+ }
+
+ @Test
+ public void
+ updateBuilder_should_set_noise_reduction_mode_zero_shutter_lag_when_zero_shutter_lag() {
+ testUpdateBuilderWith(
+ NoiseReductionMode.zeroShutterLag, CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
+ }
+
+ private static void testUpdateBuilderWith(NoiseReductionMode mode, int expectedResult) {
+ CameraProperties mockCameraProperties = mock(CameraProperties.class);
+ CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class);
+ NoiseReductionFeature noiseReductionFeature = new NoiseReductionFeature(mockCameraProperties);
+
+ when(mockCameraProperties.getAvailableNoiseReductionModes()).thenReturn(new int[] {1});
+
+ noiseReductionFeature.setValue(mode);
+ noiseReductionFeature.updateBuilder(mockBuilder);
+ verify(mockBuilder, times(1)).set(CaptureRequest.NOISE_REDUCTION_MODE, expectedResult);
+ }
+}