diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 557e16ea59e4..46cfad017a1a 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.12.1 + +* Adds `setJpegImageQuality` for controlling JPEG compression quality. + ## 0.12.0+1 * Makes `Optional.of` constructor `const`. diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index b5d9dff6e913..1b82bcd3ed4e 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -31,3 +31,8 @@ dev_dependencies: flutter: uses-material-design: true +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins +dependency_overrides: + camera_android_camerax: {path: ../../../../packages/camera/camera_android_camerax} + camera_avfoundation: {path: ../../../../packages/camera/camera_avfoundation} diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index d941c2e85f66..1683ac8c2f0c 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -994,6 +994,24 @@ class CameraController extends ValueNotifier { } } + /// Sets the JPEG compression quality for still image capture. + /// + /// The [quality] must be between 1 (lowest) and 100 (highest). + Future setJpegImageQuality(int quality) async { + if (quality < 1 || quality > 100) { + throw ArgumentError.value( + quality, + 'quality', + 'Must be between 1 and 100.', + ); + } + try { + await CameraPlatform.instance.setJpegImageQuality(_cameraId, quality); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + /// Check whether the camera platform supports image streaming. bool supportsImageStreaming() => CameraPlatform.instance.supportsImageStreaming(); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2d5967181c32..0425307fef98 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.12.0+1 +version: 0.12.1 environment: sdk: ^3.9.0 @@ -21,9 +21,9 @@ flutter: default_package: camera_web dependencies: - camera_android_camerax: ^0.7.0 - camera_avfoundation: ^0.10.0 - camera_platform_interface: ^2.12.0 + camera_android_camerax: ^0.7.1 + camera_avfoundation: ^0.10.1 + camera_platform_interface: ^2.13.0 camera_web: ^0.3.3 flutter: sdk: flutter @@ -38,3 +38,8 @@ dev_dependencies: topics: - camera +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins +dependency_overrides: + camera_android_camerax: {path: ../../../packages/camera/camera_android_camerax} + camera_avfoundation: {path: ../../../packages/camera/camera_avfoundation} diff --git a/packages/camera/camera/test/camera_preview_test.dart b/packages/camera/camera/test/camera_preview_test.dart index 912a583e9255..cfd3af86bc6a 100644 --- a/packages/camera/camera/test/camera_preview_test.dart +++ b/packages/camera/camera/test/camera_preview_test.dart @@ -149,6 +149,9 @@ class FakeController extends ValueNotifier Future> getSupportedVideoStabilizationModes() async => []; + @override + Future setJpegImageQuality(int quality) async {} + @override bool supportsImageStreaming() => true; } diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 913d3391cd9e..fe95180cccd0 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -885,6 +885,83 @@ void main() { }, ); + test('setJpegImageQuality() calls CameraPlatform', () async { + final cameraController = CameraController( + const CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90, + ), + ResolutionPreset.max, + ); + await cameraController.initialize(); + + await cameraController.setJpegImageQuality(50); + + verify( + CameraPlatform.instance.setJpegImageQuality(cameraController.cameraId, 50), + ).called(1); + }); + + test( + 'setJpegImageQuality() throws CameraException on PlatformException', + () async { + final cameraController = CameraController( + const CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90, + ), + ResolutionPreset.max, + ); + await cameraController.initialize(); + + when( + CameraPlatform.instance.setJpegImageQuality( + cameraController.cameraId, + 50, + ), + ).thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + ), + ); + + expect( + cameraController.setJpegImageQuality(50), + throwsA( + isA().having( + (CameraException error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ), + ), + ); + }, + ); + + test('setJpegImageQuality() throws ArgumentError for invalid values', () async { + final cameraController = CameraController( + const CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90, + ), + ResolutionPreset.max, + ); + await cameraController.initialize(); + + expect( + () => cameraController.setJpegImageQuality(0), + throwsA(isA()), + ); + expect( + () => cameraController.setJpegImageQuality(101), + throwsA(isA()), + ); + }); + test('setExposureMode() calls $CameraPlatform', () async { final cameraController = CameraController( const CameraDescription( @@ -4152,6 +4229,12 @@ class MockCameraPlatform extends Mock ) async => super.noSuchMethod( Invocation.method(#setVideoStabilizationMode, [cameraId, mode]), ); + + @override + Future setJpegImageQuality(int? cameraId, int? quality) async => + super.noSuchMethod( + Invocation.method(#setJpegImageQuality, [cameraId, quality]), + ); } class MockCameraDescription extends CameraDescription { diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md index 0bf9721e6ab9..6276e41013da 100644 --- a/packages/camera/camera_android/CHANGELOG.md +++ b/packages/camera/camera_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.11 + +* Adds `setJpegImageQuality` for controlling JPEG compression quality. + ## 0.10.10+16 * Updates build files from Groovy to Kotlin. diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java index 818151d754fe..5f59bc425495 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -53,6 +53,7 @@ import io.flutter.plugins.camera.features.flash.FlashMode; import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; +import io.flutter.plugins.camera.features.jpegquality.JpegQualityFeature; import io.flutter.plugins.camera.features.resolution.ResolutionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionPreset; import io.flutter.plugins.camera.features.sensororientation.DeviceOrientationManager; @@ -1416,6 +1417,20 @@ public void setDescriptionWhileRecording(CameraProperties properties) { } } + /** + * Sets the JPEG compression quality for still image capture. + * + * @param quality JPEG quality value between 1 and 100. + */ + public void setJpegImageQuality(@NonNull Long quality) { + JpegQualityFeature jpegQualityFeature = cameraFeatures.getJpegQuality(); + if (jpegQualityFeature == null) { + jpegQualityFeature = cameraFeatureFactory.createJpegQualityFeature(cameraProperties); + cameraFeatures.setJpegQuality(jpegQualityFeature); + } + jpegQualityFeature.setValue(quality.intValue()); + } + public void dispose() { Log.i(TAG, "dispose"); diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java index b3b04d5309e5..28a8d9a17a27 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraApiImpl.java @@ -343,6 +343,11 @@ public void setDescriptionWhileRecording(@NonNull String cameraName) { } } + @Override + public void setJpegImageQuality(@NonNull Long quality) { + camera.setJpegImageQuality(quality); + } + @Override public void dispose() { if (camera != null) { diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java index e61e0c48c199..0670586bd782 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Messages.java @@ -1079,6 +1079,9 @@ void create( */ void setDescriptionWhileRecording(@NonNull String description); + /** Sets the JPEG compression quality for still image capture. */ + void setJpegImageQuality(@NonNull Long quality); + /** The codec used by CameraApi. */ static @NonNull MessageCodec getCodec() { return PigeonCodec.INSTANCE; @@ -1809,6 +1812,31 @@ public void error(Throwable error) { channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.camera_android.CameraApi.setJpegImageQuality" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + Long qualityArg = (Long) args.get(0); + try { + api.setJpegImageQuality(qualityArg); + wrapped.add(0, null); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } } } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactory.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactory.java index 4027e665e71a..7f5ad2e6b9dd 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactory.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactory.java @@ -15,6 +15,7 @@ import io.flutter.plugins.camera.features.flash.FlashFeature; import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; +import io.flutter.plugins.camera.features.jpegquality.JpegQualityFeature; import io.flutter.plugins.camera.features.noisereduction.NoiseReductionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionPreset; @@ -157,4 +158,14 @@ ExposurePointFeature createExposurePointFeature( */ @NonNull NoiseReductionFeature createNoiseReductionFeature(@NonNull CameraProperties cameraProperties); + + /** + * Creates a new instance of the JPEG quality feature. + * + * @param cameraProperties instance of the CameraProperties class containing information about the + * cameras features. + * @return newly created instance of the JpegQualityFeature class. + */ + @NonNull + JpegQualityFeature createJpegQualityFeature(@NonNull CameraProperties cameraProperties); } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactoryImpl.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactoryImpl.java index c333d8f485ad..91ff9d991a48 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactoryImpl.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatureFactoryImpl.java @@ -15,6 +15,7 @@ import io.flutter.plugins.camera.features.flash.FlashFeature; import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; +import io.flutter.plugins.camera.features.jpegquality.JpegQualityFeature; import io.flutter.plugins.camera.features.noisereduction.NoiseReductionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionPreset; @@ -105,4 +106,10 @@ public NoiseReductionFeature createNoiseReductionFeature( @NonNull CameraProperties cameraProperties) { return new NoiseReductionFeature(cameraProperties); } + + @NonNull + @Override + public JpegQualityFeature createJpegQualityFeature(@NonNull CameraProperties cameraProperties) { + return new JpegQualityFeature(cameraProperties); + } } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatures.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatures.java index c700e3b2c184..69068cec7050 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatures.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/CameraFeatures.java @@ -6,6 +6,7 @@ import android.app.Activity; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import io.flutter.plugins.camera.CameraProperties; import io.flutter.plugins.camera.DartMessenger; import io.flutter.plugins.camera.features.autofocus.AutoFocusFeature; @@ -15,6 +16,7 @@ import io.flutter.plugins.camera.features.flash.FlashFeature; import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; +import io.flutter.plugins.camera.features.jpegquality.JpegQualityFeature; import io.flutter.plugins.camera.features.noisereduction.NoiseReductionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionPreset; @@ -41,6 +43,7 @@ public class CameraFeatures { private static final String REGION_BOUNDARIES = "REGION_BOUNDARIES"; private static final String RESOLUTION = "RESOLUTION"; private static final String SENSOR_ORIENTATION = "SENSOR_ORIENTATION"; + private static final String JPEG_QUALITY = "JPEG_QUALITY"; private static final String ZOOM_LEVEL = "ZOOM_LEVEL"; @NonNull @@ -297,4 +300,23 @@ public ZoomLevelFeature getZoomLevel() { public void setZoomLevel(@NonNull ZoomLevelFeature zoomLevel) { this.featureMap.put(ZOOM_LEVEL, zoomLevel); } + + /** + * Gets the JPEG quality feature if it has been set. + * + * @return the JPEG quality feature, or null if not set. + */ + @Nullable + public JpegQualityFeature getJpegQuality() { + return (JpegQualityFeature) featureMap.get(JPEG_QUALITY); + } + + /** + * Sets the instance of the JPEG quality feature. + * + * @param jpegQuality the {@link JpegQualityFeature} instance to set. + */ + public void setJpegQuality(@NonNull JpegQualityFeature jpegQuality) { + this.featureMap.put(JPEG_QUALITY, jpegQuality); + } } diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/jpegquality/JpegQualityFeature.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/jpegquality/JpegQualityFeature.java new file mode 100644 index 000000000000..5b07b82fccda --- /dev/null +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/jpegquality/JpegQualityFeature.java @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors +// 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.jpegquality; + +import android.annotation.SuppressLint; +import android.hardware.camera2.CaptureRequest; +import androidx.annotation.NonNull; +import io.flutter.plugins.camera.CameraProperties; +import io.flutter.plugins.camera.features.CameraFeature; + +/** Controls the JPEG compression quality on the {@link android.hardware.camera2} API. */ +public class JpegQualityFeature extends CameraFeature { + private int currentSetting = 100; + + /** + * Creates a new instance of the {@link JpegQualityFeature}. + * + * @param cameraProperties Collection of characteristics for the current camera device. + */ + public JpegQualityFeature(@NonNull CameraProperties cameraProperties) { + super(cameraProperties); + } + + @NonNull + @Override + public String getDebugName() { + return "JpegQualityFeature"; + } + + @SuppressLint("KotlinPropertyAccess") + @NonNull + @Override + public Integer getValue() { + return currentSetting; + } + + @Override + public void setValue(@NonNull Integer value) { + this.currentSetting = value; + } + + @Override + public boolean checkIsSupported() { + return true; + } + + @Override + public void updateBuilder(@NonNull CaptureRequest.Builder requestBuilder) { + requestBuilder.set(CaptureRequest.JPEG_QUALITY, (byte) currentSetting); + } +} diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java index 85e317cd0c0b..108225e06055 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java @@ -45,6 +45,7 @@ import io.flutter.plugins.camera.features.flash.FlashMode; import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; +import io.flutter.plugins.camera.features.jpegquality.JpegQualityFeature; import io.flutter.plugins.camera.features.noisereduction.NoiseReductionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionPreset; @@ -1468,5 +1469,10 @@ public NoiseReductionFeature createNoiseReductionFeature( @NonNull CameraProperties cameraProperties) { return mockNoiseReductionFeature; } + + @Override + public JpegQualityFeature createJpegQualityFeature(@NonNull CameraProperties cameraProperties) { + return mock(JpegQualityFeature.class); + } } } diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest_getRecordingProfileTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest_getRecordingProfileTest.java index 4094be54f4d4..c6998199ae61 100644 --- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest_getRecordingProfileTest.java +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest_getRecordingProfileTest.java @@ -26,6 +26,7 @@ import io.flutter.plugins.camera.features.flash.FlashFeature; import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; +import io.flutter.plugins.camera.features.jpegquality.JpegQualityFeature; import io.flutter.plugins.camera.features.noisereduction.NoiseReductionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionFeature; import io.flutter.plugins.camera.features.resolution.ResolutionPreset; @@ -200,5 +201,10 @@ public NoiseReductionFeature createNoiseReductionFeature( @NonNull CameraProperties cameraProperties) { return mockNoiseReductionFeature; } + + @Override + public JpegQualityFeature createJpegQualityFeature(@NonNull CameraProperties cameraProperties) { + return mock(JpegQualityFeature.class); + } } } diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/jpegquality/JpegQualityFeatureTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/jpegquality/JpegQualityFeatureTest.java new file mode 100644 index 000000000000..6c873e7ca589 --- /dev/null +++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/features/jpegquality/JpegQualityFeatureTest.java @@ -0,0 +1,73 @@ +// Copyright 2013 The Flutter Authors +// 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.jpegquality; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.hardware.camera2.CaptureRequest; +import io.flutter.plugins.camera.CameraProperties; +import org.junit.Test; + +public class JpegQualityFeatureTest { + @Test + public void getDebugName_shouldReturnTheNameOfTheFeature() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + JpegQualityFeature jpegQualityFeature = new JpegQualityFeature(mockCameraProperties); + + assertEquals("JpegQualityFeature", jpegQualityFeature.getDebugName()); + } + + @Test + public void getValue_shouldReturn100IfNotSet() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + JpegQualityFeature jpegQualityFeature = new JpegQualityFeature(mockCameraProperties); + + assertEquals(Integer.valueOf(100), jpegQualityFeature.getValue()); + } + + @Test + public void getValue_shouldEchoTheSetValue() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + JpegQualityFeature jpegQualityFeature = new JpegQualityFeature(mockCameraProperties); + + jpegQualityFeature.setValue(50); + assertEquals(Integer.valueOf(50), jpegQualityFeature.getValue()); + } + + @Test + public void checkIsSupported_shouldReturnTrue() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + JpegQualityFeature jpegQualityFeature = new JpegQualityFeature(mockCameraProperties); + + assertTrue(jpegQualityFeature.checkIsSupported()); + } + + @Test + public void updateBuilder_shouldSetJpegQualityOnBuilder() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class); + JpegQualityFeature jpegQualityFeature = new JpegQualityFeature(mockCameraProperties); + + jpegQualityFeature.setValue(75); + jpegQualityFeature.updateBuilder(mockBuilder); + + verify(mockBuilder, times(1)).set(CaptureRequest.JPEG_QUALITY, (byte) 75); + } + + @Test + public void updateBuilder_shouldSetDefaultQualityWhenNotExplicitlySet() { + CameraProperties mockCameraProperties = mock(CameraProperties.class); + CaptureRequest.Builder mockBuilder = mock(CaptureRequest.Builder.class); + JpegQualityFeature jpegQualityFeature = new JpegQualityFeature(mockCameraProperties); + + jpegQualityFeature.updateBuilder(mockBuilder); + + verify(mockBuilder, times(1)).set(CaptureRequest.JPEG_QUALITY, (byte) 100); + } +} diff --git a/packages/camera/camera_android/example/pubspec.yaml b/packages/camera/camera_android/example/pubspec.yaml index f4d614defd67..505e8dcdd0ca 100644 --- a/packages/camera/camera_android/example/pubspec.yaml +++ b/packages/camera/camera_android/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - camera_platform_interface: ^2.6.0 + camera_platform_interface: ^2.13.0 flutter: sdk: flutter path_provider: ^2.0.0 diff --git a/packages/camera/camera_android/lib/src/android_camera.dart b/packages/camera/camera_android/lib/src/android_camera.dart index 9f7d580f2364..e79d4ef1f55b 100644 --- a/packages/camera/camera_android/lib/src/android_camera.dart +++ b/packages/camera/camera_android/lib/src/android_camera.dart @@ -380,6 +380,10 @@ class AndroidCamera extends CameraPlatform { await _hostApi.setDescriptionWhileRecording(description.name); } + @override + Future setJpegImageQuality(int cameraId, int quality) => + _hostApi.setJpegImageQuality(quality); + @override Widget buildPreview(int cameraId) { return Texture(textureId: cameraId); diff --git a/packages/camera/camera_android/lib/src/messages.g.dart b/packages/camera/camera_android/lib/src/messages.g.dart index e4c047452511..c264a4715ddf 100644 --- a/packages/camera/camera_android/lib/src/messages.g.dart +++ b/packages/camera/camera_android/lib/src/messages.g.dart @@ -1,9 +1,9 @@ // Copyright 2013 The Flutter Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.0), do not edit directly. +// Autogenerated from Pigeon (v26.1.8), do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -18,11 +18,7 @@ PlatformException _createConnectionError(String channelName) { ); } -List wrapResponse({ - Object? result, - PlatformException? error, - bool empty = false, -}) { +List wrapResponse({Object? result, PlatformException? error, bool empty = false}) { if (empty) { return []; } @@ -31,27 +27,27 @@ List wrapResponse({ } return [error.code, error.message, error.details]; } - bool _deepEquals(Object? a, Object? b) { if (a is List && b is List) { return a.length == b.length && - a.indexed.every( - ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), - ); + a.indexed + .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); } if (a is Map && b is Map) { - return a.length == b.length && - a.entries.every( - (MapEntry entry) => - (b as Map).containsKey(entry.key) && - _deepEquals(entry.value, b[entry.key]), - ); + return a.length == b.length && a.entries.every((MapEntry entry) => + (b as Map).containsKey(entry.key) && + _deepEquals(entry.value, b[entry.key])); } return a == b; } + /// Pigeon equivalent of [CameraLensDirection]. -enum PlatformCameraLensDirection { front, back, external } +enum PlatformCameraLensDirection { + front, + back, + external, +} /// Pigeon equivalent of [DeviceOrientation]. enum PlatformDeviceOrientation { @@ -62,13 +58,26 @@ enum PlatformDeviceOrientation { } /// Pigeon equivalent of [ExposureMode]. -enum PlatformExposureMode { auto, locked } +enum PlatformExposureMode { + auto, + locked, +} /// Pigeon equivalent of [FocusMode]. -enum PlatformFocusMode { auto, locked } +enum PlatformFocusMode { + auto, + locked, +} /// Pigeon equivalent of [ResolutionPreset]. -enum PlatformResolutionPreset { low, medium, high, veryHigh, ultraHigh, max } +enum PlatformResolutionPreset { + low, + medium, + high, + veryHigh, + ultraHigh, + max, +} /// Pigeon equivalent of [ImageFormatGroup]. enum PlatformImageFormatGroup { @@ -79,7 +88,12 @@ enum PlatformImageFormatGroup { } /// Pigeon equivalent of [FlashMode]. -enum PlatformFlashMode { off, auto, always, torch } +enum PlatformFlashMode { + off, + auto, + always, + torch, +} /// Pigeon equivalent of [CameraDescription]. class PlatformCameraDescription { @@ -96,12 +110,15 @@ class PlatformCameraDescription { int sensorOrientation; List _toList() { - return [name, lensDirection, sensorOrientation]; + return [ + name, + lensDirection, + sensorOrientation, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformCameraDescription decode(Object result) { result as List; @@ -115,8 +132,7 @@ class PlatformCameraDescription { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes bool operator ==(Object other) { - if (other is! PlatformCameraDescription || - other.runtimeType != runtimeType) { + if (other is! PlatformCameraDescription || other.runtimeType != runtimeType) { return false; } if (identical(this, other)) { @@ -127,7 +143,8 @@ class PlatformCameraDescription { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } /// Data needed for [CameraInitializedEvent]. @@ -161,8 +178,7 @@ class PlatformCameraState { } Object encode() { - return _toList(); - } + return _toList(); } static PlatformCameraState decode(Object result) { result as List; @@ -189,24 +205,30 @@ class PlatformCameraState { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } /// Pigeon equivalent of [Size]. class PlatformSize { - PlatformSize({required this.width, required this.height}); + PlatformSize({ + required this.width, + required this.height, + }); double width; double height; List _toList() { - return [width, height]; + return [ + width, + height, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformSize decode(Object result) { result as List; @@ -230,28 +252,37 @@ class PlatformSize { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } /// Pigeon equivalent of [Point]. class PlatformPoint { - PlatformPoint({required this.x, required this.y}); + PlatformPoint({ + required this.x, + required this.y, + }); double x; double y; List _toList() { - return [x, y]; + return [ + x, + y, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformPoint decode(Object result) { result as List; - return PlatformPoint(x: result[0]! as double, y: result[1]! as double); + return PlatformPoint( + x: result[0]! as double, + y: result[1]! as double, + ); } @override @@ -268,7 +299,8 @@ class PlatformPoint { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } /// Pigeon equivalent of [MediaSettings]. @@ -302,8 +334,7 @@ class PlatformMediaSettings { } Object encode() { - return _toList(); - } + return _toList(); } static PlatformMediaSettings decode(Object result) { result as List; @@ -330,9 +361,11 @@ class PlatformMediaSettings { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } + class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -340,40 +373,40 @@ class _PigeonCodec extends StandardMessageCodec { if (value is int) { buffer.putUint8(4); buffer.putInt64(value); - } else if (value is PlatformCameraLensDirection) { + } else if (value is PlatformCameraLensDirection) { buffer.putUint8(129); writeValue(buffer, value.index); - } else if (value is PlatformDeviceOrientation) { + } else if (value is PlatformDeviceOrientation) { buffer.putUint8(130); writeValue(buffer, value.index); - } else if (value is PlatformExposureMode) { + } else if (value is PlatformExposureMode) { buffer.putUint8(131); writeValue(buffer, value.index); - } else if (value is PlatformFocusMode) { + } else if (value is PlatformFocusMode) { buffer.putUint8(132); writeValue(buffer, value.index); - } else if (value is PlatformResolutionPreset) { + } else if (value is PlatformResolutionPreset) { buffer.putUint8(133); writeValue(buffer, value.index); - } else if (value is PlatformImageFormatGroup) { + } else if (value is PlatformImageFormatGroup) { buffer.putUint8(134); writeValue(buffer, value.index); - } else if (value is PlatformFlashMode) { + } else if (value is PlatformFlashMode) { buffer.putUint8(135); writeValue(buffer, value.index); - } else if (value is PlatformCameraDescription) { + } else if (value is PlatformCameraDescription) { buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is PlatformCameraState) { + } else if (value is PlatformCameraState) { buffer.putUint8(137); writeValue(buffer, value.encode()); - } else if (value is PlatformSize) { + } else if (value is PlatformSize) { buffer.putUint8(138); writeValue(buffer, value.encode()); - } else if (value is PlatformPoint) { + } else if (value is PlatformPoint) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is PlatformMediaSettings) { + } else if (value is PlatformMediaSettings) { buffer.putUint8(140); writeValue(buffer, value.encode()); } else { @@ -384,36 +417,36 @@ class _PigeonCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 129: - final int? value = readValue(buffer) as int?; + case 129: + final value = readValue(buffer) as int?; return value == null ? null : PlatformCameraLensDirection.values[value]; - case 130: - final int? value = readValue(buffer) as int?; + case 130: + final value = readValue(buffer) as int?; return value == null ? null : PlatformDeviceOrientation.values[value]; - case 131: - final int? value = readValue(buffer) as int?; + case 131: + final value = readValue(buffer) as int?; return value == null ? null : PlatformExposureMode.values[value]; - case 132: - final int? value = readValue(buffer) as int?; + case 132: + final value = readValue(buffer) as int?; return value == null ? null : PlatformFocusMode.values[value]; - case 133: - final int? value = readValue(buffer) as int?; + case 133: + final value = readValue(buffer) as int?; return value == null ? null : PlatformResolutionPreset.values[value]; - case 134: - final int? value = readValue(buffer) as int?; + case 134: + final value = readValue(buffer) as int?; return value == null ? null : PlatformImageFormatGroup.values[value]; - case 135: - final int? value = readValue(buffer) as int?; + case 135: + final value = readValue(buffer) as int?; return value == null ? null : PlatformFlashMode.values[value]; - case 136: + case 136: return PlatformCameraDescription.decode(readValue(buffer)!); - case 137: + case 137: return PlatformCameraState.decode(readValue(buffer)!); - case 138: + case 138: return PlatformSize.decode(readValue(buffer)!); - case 139: + case 139: return PlatformPoint.decode(readValue(buffer)!); - case 140: + case 140: return PlatformMediaSettings.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -426,13 +459,9 @@ class CameraApi { /// Constructor for [CameraApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - CameraApi({ - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; + CameraApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -441,17 +470,14 @@ class CameraApi { /// Returns the list of available cameras. Future> getAvailableCameras() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -466,29 +492,20 @@ class CameraApi { message: 'Host platform returned null value for non-null return value.', ); } else { - return (pigeonVar_replyList[0] as List?)! - .cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } /// Creates a new camera with the given name and settings and returns its ID. - Future create( - String cameraName, - PlatformMediaSettings mediaSettings, - ) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.create$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [cameraName, mediaSettings], + Future create(String cameraName, PlatformMediaSettings mediaSettings) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.create$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([cameraName, mediaSettings]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -509,19 +526,14 @@ class CameraApi { /// Initializes the camera with the given ID for the given image format. Future initialize(PlatformImageFormatGroup imageFormat) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.initialize$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [imageFormat], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.initialize$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([imageFormat]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -537,17 +549,14 @@ class CameraApi { /// Disposes of the camera with the given ID. Future dispose() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.dispose$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.dispose$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -562,22 +571,15 @@ class CameraApi { } /// Locks the camera with the given ID to the given orientation. - Future lockCaptureOrientation( - PlatformDeviceOrientation orientation, - ) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.lockCaptureOrientation$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [orientation], + Future lockCaptureOrientation(PlatformDeviceOrientation orientation) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.lockCaptureOrientation$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([orientation]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -593,17 +595,14 @@ class CameraApi { /// Unlocks the orientation for the camera with the given ID. Future unlockCaptureOrientation() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.unlockCaptureOrientation$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.unlockCaptureOrientation$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -620,17 +619,14 @@ class CameraApi { /// Takes a picture on the camera with the given ID and returns a path to the /// resulting file. Future takePicture() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -651,19 +647,14 @@ class CameraApi { /// Starts recording a video on the camera with the given ID. Future startVideoRecording(bool enableStream) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [enableStream], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([enableStream]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -680,17 +671,14 @@ class CameraApi { /// Ends video recording on the camera with the given ID and returns the path /// to the resulting file. Future stopVideoRecording() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -711,17 +699,14 @@ class CameraApi { /// Pauses video recording on the camera with the given ID. Future pauseVideoRecording() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.pauseVideoRecording$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.pauseVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -737,17 +722,14 @@ class CameraApi { /// Resumes previously paused video recording on the camera with the given ID. Future resumeVideoRecording() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.resumeVideoRecording$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.resumeVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -763,17 +745,14 @@ class CameraApi { /// Begins streaming frames from the camera. Future startImageStream() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.startImageStream$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.startImageStream$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -789,17 +768,14 @@ class CameraApi { /// Stops streaming frames from the camera. Future stopImageStream() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.stopImageStream$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.stopImageStream$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -815,19 +791,14 @@ class CameraApi { /// Sets the flash mode of the camera with the given ID. Future setFlashMode(PlatformFlashMode flashMode) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setFlashMode$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [flashMode], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setFlashMode$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([flashMode]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -843,19 +814,14 @@ class CameraApi { /// Sets the exposure mode of the camera with the given ID. Future setExposureMode(PlatformExposureMode exposureMode) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setExposureMode$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [exposureMode], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setExposureMode$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([exposureMode]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -873,19 +839,14 @@ class CameraApi { /// /// A null value resets to the default exposure point. Future setExposurePoint(PlatformPoint? point) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setExposurePoint$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [point], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setExposurePoint$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([point]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -901,17 +862,14 @@ class CameraApi { /// Returns the minimum exposure offset of the camera with the given ID. Future getMinExposureOffset() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.getMinExposureOffset$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.getMinExposureOffset$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -932,17 +890,14 @@ class CameraApi { /// Returns the maximum exposure offset of the camera with the given ID. Future getMaxExposureOffset() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.getMaxExposureOffset$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.getMaxExposureOffset$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -963,17 +918,14 @@ class CameraApi { /// Returns the exposure step size of the camera with the given ID. Future getExposureOffsetStepSize() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.getExposureOffsetStepSize$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.getExposureOffsetStepSize$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -995,19 +947,14 @@ class CameraApi { /// Sets the exposure offset of the camera with the given ID and returns the /// actual exposure offset. Future setExposureOffset(double offset) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setExposureOffset$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [offset], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setExposureOffset$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([offset]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1028,19 +975,14 @@ class CameraApi { /// Sets the focus mode of the camera with the given ID. Future setFocusMode(PlatformFocusMode focusMode) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setFocusMode$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [focusMode], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setFocusMode$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([focusMode]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1058,19 +1000,14 @@ class CameraApi { /// /// A null value resets to the default focus point. Future setFocusPoint(PlatformPoint? point) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setFocusPoint$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [point], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setFocusPoint$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([point]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1086,17 +1023,14 @@ class CameraApi { /// Returns the maximum zoom level of the camera with the given ID. Future getMaxZoomLevel() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.getMaxZoomLevel$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.getMaxZoomLevel$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1117,17 +1051,14 @@ class CameraApi { /// Returns the minimum zoom level of the camera with the given ID. Future getMinZoomLevel() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.getMinZoomLevel$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.getMinZoomLevel$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1148,19 +1079,14 @@ class CameraApi { /// Sets the zoom level of the camera with the given ID. Future setZoomLevel(double zoom) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setZoomLevel$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [zoom], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setZoomLevel$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([zoom]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1176,17 +1102,14 @@ class CameraApi { /// Pauses streaming of preview frames. Future pausePreview() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1202,17 +1125,14 @@ class CameraApi { /// Resumes previously paused streaming of preview frames. Future resumePreview() async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1230,19 +1150,37 @@ class CameraApi { /// /// This should be called only while video recording is active. Future setDescriptionWhileRecording(String description) async { - final String pigeonVar_channelName = - 'dev.flutter.pigeon.camera_android.CameraApi.setDescriptionWhileRecording$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [description], + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setDescriptionWhileRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([description]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the JPEG compression quality for still image capture. + Future setJpegImageQuality(int quality) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_android.CameraApi.setJpegImageQuality$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final Future pigeonVar_sendFuture = pigeonVar_channel.send([quality]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1264,45 +1202,29 @@ abstract class CameraGlobalEventApi { /// Called when the device's physical orientation changes. void deviceOrientationChanged(PlatformDeviceOrientation orientation); - static void setUp( - CameraGlobalEventApi? api, { - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) { - messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; + static void setUp(CameraGlobalEventApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) { + messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel - pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + final pigeonVar_channel = BasicMessageChannel( + 'dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { pigeonVar_channel.setMessageHandler((Object? message) async { - assert( - message != null, - 'Argument for dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged was null.', - ); + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged was null.'); final List args = (message as List?)!; - final PlatformDeviceOrientation? arg_orientation = - (args[0] as PlatformDeviceOrientation?); - assert( - arg_orientation != null, - 'Argument for dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged was null, expected non-null PlatformDeviceOrientation.', - ); + final PlatformDeviceOrientation? arg_orientation = (args[0] as PlatformDeviceOrientation?); + assert(arg_orientation != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraGlobalEventApi.deviceOrientationChanged was null, expected non-null PlatformDeviceOrientation.'); try { api.deviceOrientationChanged(arg_orientation!); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } @@ -1323,90 +1245,62 @@ abstract class CameraEventApi { /// Called when the camera closes. void closed(); - static void setUp( - CameraEventApi? api, { - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) { - messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; + static void setUp(CameraEventApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) { + messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel - pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_android.CameraEventApi.initialized$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + final pigeonVar_channel = BasicMessageChannel( + 'dev.flutter.pigeon.camera_android.CameraEventApi.initialized$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { pigeonVar_channel.setMessageHandler((Object? message) async { - assert( - message != null, - 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.initialized was null.', - ); + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.initialized was null.'); final List args = (message as List?)!; - final PlatformCameraState? arg_initialState = - (args[0] as PlatformCameraState?); - assert( - arg_initialState != null, - 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.initialized was null, expected non-null PlatformCameraState.', - ); + final PlatformCameraState? arg_initialState = (args[0] as PlatformCameraState?); + assert(arg_initialState != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.initialized was null, expected non-null PlatformCameraState.'); try { api.initialized(arg_initialState!); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } } { - final BasicMessageChannel - pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_android.CameraEventApi.error$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + final pigeonVar_channel = BasicMessageChannel( + 'dev.flutter.pigeon.camera_android.CameraEventApi.error$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { pigeonVar_channel.setMessageHandler((Object? message) async { - assert( - message != null, - 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.error was null.', - ); + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.error was null.'); final List args = (message as List?)!; final String? arg_message = (args[0] as String?); - assert( - arg_message != null, - 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.error was null, expected non-null String.', - ); + assert(arg_message != null, + 'Argument for dev.flutter.pigeon.camera_android.CameraEventApi.error was null, expected non-null String.'); try { api.error(arg_message!); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } } { - final BasicMessageChannel - pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_android.CameraEventApi.closed$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + final pigeonVar_channel = BasicMessageChannel( + 'dev.flutter.pigeon.camera_android.CameraEventApi.closed$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { @@ -1416,10 +1310,8 @@ abstract class CameraEventApi { return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } diff --git a/packages/camera/camera_android/pigeons/messages.dart b/packages/camera/camera_android/pigeons/messages.dart index 4489fe3f6fb8..a8f1bd582270 100644 --- a/packages/camera/camera_android/pigeons/messages.dart +++ b/packages/camera/camera_android/pigeons/messages.dart @@ -207,6 +207,9 @@ abstract class CameraApi { /// /// This should be called only while video recording is active. void setDescriptionWhileRecording(String description); + + /// Sets the JPEG compression quality for still image capture. + void setJpegImageQuality(int quality); } /// Handles calls from native side to Dart that are not camera-specific. diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml index 34ffc900e502..d532e9fd41b2 100644 --- a/packages/camera/camera_android/pubspec.yaml +++ b/packages/camera/camera_android/pubspec.yaml @@ -3,7 +3,7 @@ description: Android implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.10.10+16 +version: 0.10.11 environment: sdk: ^3.9.0 @@ -19,7 +19,7 @@ flutter: dartPluginClass: AndroidCamera dependencies: - camera_platform_interface: ^2.9.0 + camera_platform_interface: ^2.13.0 flutter: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.2 diff --git a/packages/camera/camera_android/test/android_camera_test.dart b/packages/camera/camera_android/test/android_camera_test.dart index 8321001ed954..de6c4eee7057 100644 --- a/packages/camera/camera_android/test/android_camera_test.dart +++ b/packages/camera/camera_android/test/android_camera_test.dart @@ -873,5 +873,14 @@ void main() { verify(mockCameraApi.startImageStream()).called(1); verify(mockCameraApi.stopImageStream()).called(1); }); + + test('Should set the image quality', () async { + // Arrange + // Act + await camera.setJpegImageQuality(cameraId, 50); + + // Assert + verify(mockCameraApi.setJpegImageQuality(50)).called(1); + }); }); } diff --git a/packages/camera/camera_android/test/android_camera_test.mocks.dart b/packages/camera/camera_android/test/android_camera_test.mocks.dart index 53cd6e9489a1..e03db33b106d 100644 --- a/packages/camera/camera_android/test/android_camera_test.mocks.dart +++ b/packages/camera/camera_android/test/android_camera_test.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.4.4 from annotations +// Mocks generated by Mockito 5.4.6 from annotations // in camera_android/test/android_camera_test.dart. // Do not manually edit this file. @@ -17,10 +17,12 @@ import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable // ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +// ignore_for_file: invalid_use_of_internal_member /// A class which mocks [CameraApi]. /// @@ -316,4 +318,13 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + + @override + _i4.Future setJpegImageQuality(int? quality) => + (super.noSuchMethod( + Invocation.method(#setJpegImageQuality, [quality]), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); } diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index c6a099c854d7..a1013c3f9cd5 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.2 + +* Adds `setJpegImageQuality` for controlling JPEG compression quality. + ## 0.7.1+2 * Fixes dartdoc comments that accidentally used HTML. diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXLibrary.g.kt b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXLibrary.g.kt index 2bdf4371dfed..7813f22eab7f 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXLibrary.g.kt +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXLibrary.g.kt @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.7), do not edit directly. +// Autogenerated from Pigeon (v26.1.8), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") @@ -4247,7 +4247,8 @@ abstract class PigeonApiImageCapture( abstract fun pigeon_defaultConstructor( resolutionSelector: androidx.camera.core.resolutionselector.ResolutionSelector?, targetRotation: Long?, - flashMode: CameraXFlashMode? + flashMode: CameraXFlashMode?, + jpegQuality: Long? ): androidx.camera.core.ImageCapture abstract fun resolutionSelector( @@ -4288,11 +4289,12 @@ abstract class PigeonApiImageCapture( args[1] as androidx.camera.core.resolutionselector.ResolutionSelector? val targetRotationArg = args[2] as Long? val flashModeArg = args[3] as CameraXFlashMode? + val jpegQualityArg = args[4] as Long? val wrapped: List = try { api.pigeonRegistrar.instanceManager.addDartCreatedInstance( api.pigeon_defaultConstructor( - resolutionSelectorArg, targetRotationArg, flashModeArg), + resolutionSelectorArg, targetRotationArg, flashModeArg, jpegQualityArg), pigeon_identifierArg) listOf(null) } catch (exception: Throwable) { diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureProxyApi.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureProxyApi.java index 78ba586b2314..eeb4731b227e 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureProxyApi.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureProxyApi.java @@ -40,7 +40,8 @@ public ProxyApiRegistrar getPigeonRegistrar() { public ImageCapture pigeon_defaultConstructor( @Nullable ResolutionSelector resolutionSelector, @Nullable Long targetRotation, - @Nullable CameraXFlashMode flashMode) { + @Nullable CameraXFlashMode flashMode, + @Nullable Long jpegQuality) { final ImageCapture.Builder builder = new ImageCapture.Builder(); if (targetRotation != null) { builder.setTargetRotation(targetRotation.intValue()); @@ -62,6 +63,9 @@ public ImageCapture pigeon_defaultConstructor( if (resolutionSelector != null) { builder.setResolutionSelector(resolutionSelector); } + if (jpegQuality != null) { + builder.setJpegQuality(jpegQuality.intValue()); + } return builder.build(); } diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java index 5c84dff947df..13f4397fbe29 100644 --- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java @@ -39,13 +39,30 @@ public void pigeon_defaultConstructor_createsImageCaptureWithCorrectConfiguratio final long targetResolution = Surface.ROTATION_0; final ImageCapture imageCapture = api.pigeon_defaultConstructor( - mockResolutionSelector, targetResolution, CameraXFlashMode.OFF); + mockResolutionSelector, targetResolution, CameraXFlashMode.OFF, null); assertEquals(imageCapture.getResolutionSelector(), mockResolutionSelector); assertEquals(imageCapture.getTargetRotation(), Surface.ROTATION_0); assertEquals(imageCapture.getFlashMode(), ImageCapture.FLASH_MODE_OFF); } + @Test + public void pigeon_defaultConstructor_setsJpegQualityWhenProvided() { + final PigeonApiImageCapture api = new TestProxyApiRegistrar().getPigeonApiImageCapture(); + + final ResolutionSelector mockResolutionSelector = new ResolutionSelector.Builder().build(); + final long targetRotation = Surface.ROTATION_0; + final long jpegQuality = 75; + final ImageCapture imageCapture = + api.pigeon_defaultConstructor( + mockResolutionSelector, targetRotation, CameraXFlashMode.OFF, jpegQuality); + + assertEquals(imageCapture.getResolutionSelector(), mockResolutionSelector); + assertEquals(imageCapture.getTargetRotation(), Surface.ROTATION_0); + assertEquals(imageCapture.getFlashMode(), ImageCapture.FLASH_MODE_OFF); + assertEquals(imageCapture.getJpegQuality(), 75); + } + @Test public void resolutionSelector_returnsExpectedResolutionSelector() { final PigeonApiImageCapture api = new TestProxyApiRegistrar().getPigeonApiImageCapture(); diff --git a/packages/camera/camera_android_camerax/example/pubspec.yaml b/packages/camera/camera_android_camerax/example/pubspec.yaml index 81a4e079b2ae..8fc5e2380436 100644 --- a/packages/camera/camera_android_camerax/example/pubspec.yaml +++ b/packages/camera/camera_android_camerax/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - camera_platform_interface: ^2.6.0 + camera_platform_interface: ^2.13.0 flutter: sdk: flutter video_player: ^2.7.0 @@ -28,4 +28,3 @@ dev_dependencies: flutter: uses-material-design: true - diff --git a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart index e52e4bd09cf1..bffcee28b3ec 100644 --- a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart +++ b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart @@ -205,6 +205,13 @@ class AndroidCameraCameraX extends CameraPlatform { @visibleForTesting bool captureOrientationLocked = false; + /// The target rotation set by [lockCaptureOrientation], if any. + /// + /// Used to preserve the locked rotation when recreating use cases (e.g., + /// in [setJpegImageQuality]). + @visibleForTesting + int? lockedCaptureOrientation; + /// Whether or not the default rotation for [UseCase]s needs to be set /// manually because the capture orientation was previously locked. /// @@ -588,6 +595,7 @@ class AndroidCameraCameraX extends CameraPlatform { final int targetLockedRotation = _getRotationConstantFromDeviceOrientation( orientation, ); + lockedCaptureOrientation = targetLockedRotation; // Update UseCases to use target device orientation. await imageCapture!.setTargetRotation(targetLockedRotation); @@ -600,6 +608,7 @@ class AndroidCameraCameraX extends CameraPlatform { Future unlockCaptureOrientation(int cameraId) async { // Flag that default rotation should be set for UseCases as needed. captureOrientationLocked = false; + lockedCaptureOrientation = null; } /// Sets the exposure point for automatically determining the exposure values for @@ -1126,6 +1135,31 @@ class AndroidCameraCameraX extends CameraPlatform { } } + /// Sets the JPEG compression quality for still image capture. + /// + /// CameraX only supports setting JPEG quality via `ImageCapture.Builder` + /// at construction time, so this recreates the `ImageCapture` use case + /// with the requested quality. The next call to [takePicture] will bind + /// the new instance automatically. + @override + Future setJpegImageQuality(int cameraId, int quality) async { + // Unbind the current ImageCapture if it exists and is bound. + if (imageCapture != null) { + await _unbindUseCaseFromLifecycle(imageCapture!); + } + + // Recreate ImageCapture with the requested JPEG quality. + // Preserve locked orientation if set, otherwise use default display rotation. + final int targetRotation = + lockedCaptureOrientation ?? + await deviceOrientationManager.getDefaultDisplayRotation(); + imageCapture = ImageCapture( + resolutionSelector: _presetResolutionSelector, + targetRotation: targetRotation, + jpegQuality: quality, + ); + } + /// Prepare the capture session for video recording. /// /// This optimization is not used on Android, so this implementation is a diff --git a/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart b/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart index 7b642695e0b0..40960369e615 100644 --- a/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart +++ b/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.7), do not edit directly. +// Autogenerated from Pigeon (v26.1.8), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -123,6 +123,7 @@ class PigeonOverrides { ResolutionSelector? resolutionSelector, int? targetRotation, CameraXFlashMode? flashMode, + int? jpegQuality, })? imageCapture_new; @@ -5118,12 +5119,14 @@ class ImageCapture extends UseCase { ResolutionSelector? resolutionSelector, int? targetRotation, CameraXFlashMode? flashMode, + int? jpegQuality, }) { if (PigeonOverrides.imageCapture_new != null) { return PigeonOverrides.imageCapture_new!( resolutionSelector: resolutionSelector, targetRotation: targetRotation, flashMode: flashMode, + jpegQuality: jpegQuality, ); } return ImageCapture.pigeon_new( @@ -5132,6 +5135,7 @@ class ImageCapture extends UseCase { resolutionSelector: resolutionSelector, targetRotation: targetRotation, flashMode: flashMode, + jpegQuality: jpegQuality, ); } @@ -5142,6 +5146,7 @@ class ImageCapture extends UseCase { this.resolutionSelector, int? targetRotation, CameraXFlashMode? flashMode, + int? jpegQuality, }) : super.pigeon_detached() { final int pigeonVar_instanceIdentifier = pigeon_instanceManager .addDartCreatedInstance(this); @@ -5155,14 +5160,14 @@ class ImageCapture extends UseCase { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [ - pigeonVar_instanceIdentifier, - resolutionSelector, - targetRotation, - flashMode, - ], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel + .send([ + pigeonVar_instanceIdentifier, + resolutionSelector, + targetRotation, + flashMode, + jpegQuality, + ]); () async { final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { diff --git a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart index 611157f65248..479dc0a6829d 100644 --- a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart +++ b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart @@ -598,7 +598,11 @@ enum CameraXFlashMode { ), ) abstract class ImageCapture extends UseCase { - ImageCapture(int? targetRotation, CameraXFlashMode? flashMode); + ImageCapture( + int? targetRotation, + CameraXFlashMode? flashMode, + int? jpegQuality, + ); late final ResolutionSelector? resolutionSelector; diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index 2dda62c4a153..45dd2812c1ca 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.7.1+2 +version: 0.7.2 environment: sdk: ^3.9.0 @@ -19,7 +19,7 @@ flutter: dependencies: async: ^2.5.0 - camera_platform_interface: ^2.12.0 + camera_platform_interface: ^2.13.0 flutter: sdk: flutter meta: ^1.7.0 diff --git a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart index 71ed3d58ccde..5f68b48b3802 100644 --- a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart +++ b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart @@ -197,6 +197,7 @@ void main() { int? targetRotation, CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, + int? jpegQuality, }) { final mockImageCapture = MockImageCapture(); when( @@ -630,6 +631,7 @@ void main() { int? targetRotation, CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, + int? jpegQuality, }) { return mockImageCapture; }; @@ -1281,6 +1283,7 @@ void main() { int? targetRotation, CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, + int? jpegQuality, }) { return mockImageCapture; }; @@ -1771,6 +1774,7 @@ void main() { int? targetRotation, CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, + int? jpegQuality, }) { return mockImageCapture; }; @@ -2195,6 +2199,7 @@ void main() { int? targetRotation, CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, + int? jpegQuality, }) => mockImageCapture; PigeonOverrides.recorder_new = ({ @@ -3364,6 +3369,7 @@ void main() { CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, int? targetRotation, + int? jpegQuality, }) { return mockImageCapture; }; @@ -3627,6 +3633,7 @@ void main() { CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, int? targetRotation, + int? jpegQuality, }) { return mockImageCapture; }; @@ -3905,6 +3912,108 @@ void main() { }, ); + test( + 'setJpegImageQuality unbinds and recreates ImageCapture with requested quality', + () async { + final camera = AndroidCameraCameraX(); + final mockProcessCameraProvider = MockProcessCameraProvider(); + final mockDeviceOrientationManager = MockDeviceOrientationManager(); + final mockImageCapture = MockImageCapture(); + final mockNewImageCapture = MockImageCapture(); + const int defaultTargetRotation = Surface.rotation90; + const jpegQuality = 73; + const cameraId = 9; + int? actualTargetRotation; + int? actualJpegQuality; + + camera.processCameraProvider = mockProcessCameraProvider; + camera.imageCapture = mockImageCapture; + + PigeonOverrides.deviceOrientationManager_new = + ({ + required void Function(DeviceOrientationManager, String) + onDeviceOrientationChanged, + }) { + when( + mockDeviceOrientationManager.getDefaultDisplayRotation(), + ).thenAnswer((_) async => defaultTargetRotation); + return mockDeviceOrientationManager; + }; + PigeonOverrides.imageCapture_new = + ({ + int? targetRotation, + CameraXFlashMode? flashMode, + ResolutionSelector? resolutionSelector, + int? jpegQuality, + }) { + actualTargetRotation = targetRotation; + actualJpegQuality = jpegQuality; + return mockNewImageCapture; + }; + + when( + mockProcessCameraProvider.isBound(mockImageCapture), + ).thenAnswer((_) async => true); + + await camera.setJpegImageQuality(cameraId, jpegQuality); + + verify( + mockProcessCameraProvider.unbind([mockImageCapture]), + ).called(1); + verify( + mockDeviceOrientationManager.getDefaultDisplayRotation(), + ).called(1); + expect(actualTargetRotation, defaultTargetRotation); + expect(actualJpegQuality, jpegQuality); + expect(camera.imageCapture, same(mockNewImageCapture)); + }, + ); + + test( + 'setJpegImageQuality preserves locked target rotation when recreating ImageCapture', + () async { + final camera = AndroidCameraCameraX(); + final mockDeviceOrientationManager = MockDeviceOrientationManager(); + final mockNewImageCapture = MockImageCapture(); + const int lockedTargetRotation = Surface.rotation270; + const jpegQuality = 64; + const cameraId = 11; + int? actualTargetRotation; + int? actualJpegQuality; + + camera.lockedCaptureOrientation = lockedTargetRotation; + + PigeonOverrides.deviceOrientationManager_new = + ({ + required void Function(DeviceOrientationManager, String) + onDeviceOrientationChanged, + }) { + when( + mockDeviceOrientationManager.getDefaultDisplayRotation(), + ).thenAnswer((_) async => Surface.rotation0); + return mockDeviceOrientationManager; + }; + PigeonOverrides.imageCapture_new = + ({ + int? targetRotation, + CameraXFlashMode? flashMode, + ResolutionSelector? resolutionSelector, + int? jpegQuality, + }) { + actualTargetRotation = targetRotation; + actualJpegQuality = jpegQuality; + return mockNewImageCapture; + }; + + await camera.setJpegImageQuality(cameraId, jpegQuality); + + verifyNever(mockDeviceOrientationManager.getDefaultDisplayRotation()); + expect(actualTargetRotation, lockedTargetRotation); + expect(actualJpegQuality, jpegQuality); + expect(camera.imageCapture, same(mockNewImageCapture)); + }, + ); + test( 'takePicture turns non-torch flash mode off when torch mode enabled', () async { diff --git a/packages/camera/camera_android_camerax/test/preview_rotation_test.dart b/packages/camera/camera_android_camerax/test/preview_rotation_test.dart index cfc6b2db103b..9d7b2531ba09 100644 --- a/packages/camera/camera_android_camerax/test/preview_rotation_test.dart +++ b/packages/camera/camera_android_camerax/test/preview_rotation_test.dart @@ -123,6 +123,7 @@ void main() { int? targetRotation, CameraXFlashMode? flashMode, ResolutionSelector? resolutionSelector, + int? jpegQuality, }) => MockImageCapture(); PigeonOverrides.recorder_new = ({ diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index ca97b101df8b..fe3789d174a1 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.2 + +* Adds `setJpegImageQuality` for controlling JPEG compression quality. + ## 0.10.1 * Fixes fatal crash on iPhone 17 when using `ResolutionPreset.max`. diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift index 34a306b511d7..f01da07aa12f 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift @@ -251,6 +251,28 @@ final class CameraPluginDelegatingMethodTests: XCTestCase { XCTAssertTrue(setImageFileFormatCalled) } + func testSetImageQuality_callsCameraSetImageQuality() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + let targetQuality: Int64 = 50 + + var setJpegImageQualityCalled = false + mockCamera.setJpegImageQualityStub = { quality in + XCTAssertEqual(quality, targetQuality) + setJpegImageQualityCalled = true + } + + cameraPlugin.setJpegImageQuality(quality: targetQuality) { result in + let _ = self.assertSuccess(result) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setJpegImageQualityCalled) + } + func testStartImageStream_callsCameraStartImageStream() { let (cameraPlugin, mockCamera) = createCameraPlugin() let expectation = expectation(description: "Call completed") diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift index ec6e6fd88f9c..569f55630155 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift @@ -27,6 +27,7 @@ final class MockCamera: NSObject, Camera { var lockCaptureOrientationStub: ((PlatformDeviceOrientation) -> Void)? var unlockCaptureOrientationStub: (() -> Void)? var setImageFileFormatStub: ((PlatformImageFileFormat) -> Void)? + var setJpegImageQualityStub: ((Int64) -> Void)? var setExposureModeStub: ((PlatformExposureMode) -> Void)? var setExposureOffsetStub: ((Double) -> Void)? var setExposurePointStub: ((PlatformPoint?, @escaping (Result) -> Void) -> Void)? @@ -144,6 +145,10 @@ final class MockCamera: NSObject, Camera { setImageFileFormatStub?(fileFormat) } + func setJpegImageQuality(_ quality: Int64) { + setJpegImageQualityStub?(quality) + } + func setExposureMode(_ mode: PlatformExposureMode) { setExposureModeStub?(mode) } diff --git a/packages/camera/camera_avfoundation/example/pubspec.yaml b/packages/camera/camera_avfoundation/example/pubspec.yaml index 4b9a5b5a5e53..d9cce5808257 100644 --- a/packages/camera/camera_avfoundation/example/pubspec.yaml +++ b/packages/camera/camera_avfoundation/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - camera_platform_interface: ^2.10.0 + camera_platform_interface: ^2.13.0 flutter: sdk: flutter path_provider: ^2.0.0 diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift index 117fd909d32e..02e9503f6adc 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift @@ -62,6 +62,7 @@ protocol Camera: FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate, func unlockCaptureOrientation() func setImageFileFormat(_ fileFormat: PlatformImageFileFormat) + func setJpegImageQuality(_ quality: Int64) func setExposureMode(_ mode: PlatformExposureMode) func setExposureOffset(_ offset: Double) diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift index 43ef5f48916c..136c05f18d58 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift @@ -555,4 +555,13 @@ extension CameraPlugin: CameraApi { completion(.success(())) } } + + func setJpegImageQuality( + quality: Int64, completion: @escaping (Result) -> Void + ) { + captureSessionQueue.async { [weak self] in + self?.camera?.setJpegImageQuality(quality) + completion(.success(())) + } + } } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 16d1637d23fa..d702248a6d7b 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -121,6 +121,7 @@ final class DefaultCamera: NSObject, Camera { private var maxStreamingPendingFramesCount = 4 private var fileFormat = PlatformImageFileFormat.jpeg + private var imageQuality: Int64 = 100 private var lockedCaptureOrientation = UIDeviceOrientation.unknown private var exposureMode = PlatformExposureMode.auto private var focusMode = PlatformFocusMode.auto @@ -719,6 +720,17 @@ final class DefaultCamera: NSObject, Camera { fileExtension = "heif" } else { fileExtension = "jpg" + if imageQuality < 100 { + settings = AVCapturePhotoSettings(format: [ + AVVideoCodecKey: AVVideoCodecType.jpeg, + AVVideoCompressionPropertiesKey: [ + AVVideoQualityKey: CGFloat(imageQuality) / 100.0 + ], + ]) + if mediaSettings.resolutionPreset == .max { + settings.isHighResolutionPhotoEnabled = true + } + } } if flashMode != .torch { @@ -842,6 +854,10 @@ final class DefaultCamera: NSObject, Camera { self.fileFormat = fileFormat } + func setJpegImageQuality(_ quality: Int64) { + self.imageQuality = quality + } + func setExposureMode(_ mode: PlatformExposureMode) { exposureMode = mode applyExposureMode() diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Messages.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Messages.swift index 47e6abbbe750..f89e1b2fec9c 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Messages.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Messages.swift @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.5), do not edit directly. +// Autogenerated from Pigeon (v26.1.8), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -59,9 +59,7 @@ private func wrapError(_ error: Any) -> [Any?] { } private func createConnectionError(withChannelName channelName: String) -> PigeonError { - return PigeonError( - code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", - details: "") + return PigeonError(code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", details: "") } private func isNullish(_ value: Any?) -> Bool { @@ -116,12 +114,12 @@ func deepEqualsMessages(_ lhs: Any?, _ rhs: Any?) -> Bool { func deepHashMessages(value: Any?, hasher: inout Hasher) { if let valueList = value as? [AnyHashable] { - for item in valueList { deepHashMessages(value: item, hasher: &hasher) } - return + for item in valueList { deepHashMessages(value: item, hasher: &hasher) } + return } if let valueDict = value as? [AnyHashable: AnyHashable] { - for key in valueDict.keys { + for key in valueDict.keys { hasher.combine(key) deepHashMessages(value: valueDict[key]!, hasher: &hasher) } @@ -135,6 +133,8 @@ func deepHashMessages(value: Any?, hasher: inout Hasher) { return hasher.combine(String(describing: value)) } + + enum PlatformCameraLensDirection: Int { /// Front facing camera (a user looking at the screen is seen by the camera). case front = 0 @@ -215,6 +215,7 @@ struct PlatformCameraDescription: Hashable { /// The type of the camera lens. var lensType: PlatformCameraLensType + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformCameraDescription? { let name = pigeonVar_list[0] as! String @@ -235,8 +236,7 @@ struct PlatformCameraDescription: Hashable { ] } static func == (lhs: PlatformCameraDescription, rhs: PlatformCameraDescription) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -255,6 +255,7 @@ struct PlatformCameraState: Hashable { /// Whether setting focus points is supported. var focusPointSupported: Bool + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformCameraState? { let previewSize = pigeonVar_list[0] as! PlatformSize @@ -281,8 +282,7 @@ struct PlatformCameraState: Hashable { ] } static func == (lhs: PlatformCameraState, rhs: PlatformCameraState) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -299,6 +299,7 @@ struct PlatformCameraImageData: Hashable { var sensorExposureTimeNanoseconds: Int64 var sensorSensitivity: Double + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformCameraImageData? { let formatCode = pigeonVar_list[0] as! Int64 @@ -331,8 +332,7 @@ struct PlatformCameraImageData: Hashable { ] } static func == (lhs: PlatformCameraImageData, rhs: PlatformCameraImageData) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -345,6 +345,7 @@ struct PlatformCameraImagePlane: Hashable { var width: Int64 var height: Int64 + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformCameraImagePlane? { let bytes = pigeonVar_list[0] as! FlutterStandardTypedData @@ -368,8 +369,7 @@ struct PlatformCameraImagePlane: Hashable { ] } static func == (lhs: PlatformCameraImagePlane, rhs: PlatformCameraImagePlane) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -383,6 +383,7 @@ struct PlatformMediaSettings: Hashable { var audioBitrate: Int64? = nil var enableAudio: Bool + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformMediaSettings? { let resolutionPreset = pigeonVar_list[0] as! PlatformResolutionPreset @@ -409,8 +410,7 @@ struct PlatformMediaSettings: Hashable { ] } static func == (lhs: PlatformMediaSettings, rhs: PlatformMediaSettings) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -421,6 +421,7 @@ struct PlatformPoint: Hashable { var x: Double var y: Double + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformPoint? { let x = pigeonVar_list[0] as! Double @@ -438,8 +439,7 @@ struct PlatformPoint: Hashable { ] } static func == (lhs: PlatformPoint, rhs: PlatformPoint) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -450,6 +450,7 @@ struct PlatformSize: Hashable { var width: Double var height: Double + // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> PlatformSize? { let width = pigeonVar_list[0] as! Double @@ -467,8 +468,7 @@ struct PlatformSize: Hashable { ] } static func == (lhs: PlatformSize, rhs: PlatformSize) -> Bool { - return deepEqualsMessages(lhs.toList(), rhs.toList()) - } + return deepEqualsMessages(lhs.toList(), rhs.toList()) } func hash(into hasher: inout Hasher) { deepHashMessages(value: toList(), hasher: &hasher) } @@ -630,22 +630,17 @@ class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter()) } -var messagesPigeonMethodCodec = FlutterStandardMethodCodec( - readerWriter: MessagesPigeonCodecReaderWriter()) +var messagesPigeonMethodCodec = FlutterStandardMethodCodec(readerWriter: MessagesPigeonCodecReaderWriter()); + /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol CameraApi { /// Returns the list of available cameras. - func getAvailableCameras( - completion: @escaping (Result<[PlatformCameraDescription], Error>) -> Void) + func getAvailableCameras(completion: @escaping (Result<[PlatformCameraDescription], Error>) -> Void) /// Create a new camera with the given settings, and returns its ID. - func create( - cameraName: String, settings: PlatformMediaSettings, - completion: @escaping (Result) -> Void) + func create(cameraName: String, settings: PlatformMediaSettings, completion: @escaping (Result) -> Void) /// Initializes the camera with the given ID. - func initialize( - cameraId: Int64, imageFormat: PlatformImageFormatGroup, - completion: @escaping (Result) -> Void) + func initialize(cameraId: Int64, imageFormat: PlatformImageFormatGroup, completion: @escaping (Result) -> Void) /// Begins streaming frames from the camera. func startImageStream(completion: @escaping (Result) -> Void) /// Stops streaming frames from the camera. @@ -659,8 +654,7 @@ protocol CameraApi { /// and any associated resources can be cleaned up. func dispose(cameraId: Int64, completion: @escaping (Result) -> Void) /// Locks the camera capture to the current device orientation. - func lockCaptureOrientation( - orientation: PlatformDeviceOrientation, completion: @escaping (Result) -> Void) + func lockCaptureOrientation(orientation: PlatformDeviceOrientation, completion: @escaping (Result) -> Void) /// Unlocks camera capture orientation, allowing it to automatically adapt to /// device orientation. func unlockCaptureOrientation(completion: @escaping (Result) -> Void) @@ -681,8 +675,7 @@ protocol CameraApi { /// Switches the camera to the given flash mode. func setFlashMode(mode: PlatformFlashMode, completion: @escaping (Result) -> Void) /// Switches the camera to the given exposure mode. - func setExposureMode( - mode: PlatformExposureMode, completion: @escaping (Result) -> Void) + func setExposureMode(mode: PlatformExposureMode, completion: @escaping (Result) -> Void) /// Anchors auto-exposure to the given point in (0,1) coordinate space. /// /// A null value resets to the default exposure point. @@ -706,11 +699,9 @@ protocol CameraApi { /// Sets the zoom factor. func setZoomLevel(zoom: Double, completion: @escaping (Result) -> Void) /// Sets the video stabilization mode. - func setVideoStabilizationMode( - mode: PlatformVideoStabilizationMode, completion: @escaping (Result) -> Void) + func setVideoStabilizationMode(mode: PlatformVideoStabilizationMode, completion: @escaping (Result) -> Void) /// Gets if the given video stabilization mode is supported. - func isVideoStabilizationModeSupported( - mode: PlatformVideoStabilizationMode, completion: @escaping (Result) -> Void) + func isVideoStabilizationModeSupported(mode: PlatformVideoStabilizationMode, completion: @escaping (Result) -> Void) /// Pauses streaming of preview frames. func pausePreview(completion: @escaping (Result) -> Void) /// Resumes a previously paused preview stream. @@ -718,25 +709,21 @@ protocol CameraApi { /// Changes the camera used while recording video. /// /// This should only be called while video recording is active. - func updateDescriptionWhileRecording( - cameraName: String, completion: @escaping (Result) -> Void) + func updateDescriptionWhileRecording(cameraName: String, completion: @escaping (Result) -> Void) /// Sets the file format used for taking pictures. - func setImageFileFormat( - format: PlatformImageFileFormat, completion: @escaping (Result) -> Void) + func setImageFileFormat(format: PlatformImageFileFormat, completion: @escaping (Result) -> Void) + /// Sets the JPEG compression quality for still image capture. + func setJpegImageQuality(quality: Int64, completion: @escaping (Result) -> Void) } /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. class CameraApiSetup { static var codec: FlutterStandardMessageCodec { MessagesPigeonCodec.shared } /// Sets up an instance of `CameraApi` to handle messages through the `binaryMessenger`. - static func setUp( - binaryMessenger: FlutterBinaryMessenger, api: CameraApi?, messageChannelSuffix: String = "" - ) { + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: CameraApi?, messageChannelSuffix: String = "") { let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" /// Returns the list of available cameras. - let getAvailableCamerasChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let getAvailableCamerasChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getAvailableCamerasChannel.setMessageHandler { _, reply in api.getAvailableCameras { result in @@ -752,9 +739,7 @@ class CameraApiSetup { getAvailableCamerasChannel.setMessageHandler(nil) } /// Create a new camera with the given settings, and returns its ID. - let createChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.create\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let createChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.create\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { createChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -773,9 +758,7 @@ class CameraApiSetup { createChannel.setMessageHandler(nil) } /// Initializes the camera with the given ID. - let initializeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let initializeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { initializeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -794,9 +777,7 @@ class CameraApiSetup { initializeChannel.setMessageHandler(nil) } /// Begins streaming frames from the camera. - let startImageStreamChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.startImageStream\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let startImageStreamChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.startImageStream\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { startImageStreamChannel.setMessageHandler { _, reply in api.startImageStream { result in @@ -812,9 +793,7 @@ class CameraApiSetup { startImageStreamChannel.setMessageHandler(nil) } /// Stops streaming frames from the camera. - let stopImageStreamChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let stopImageStreamChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { stopImageStreamChannel.setMessageHandler { _, reply in api.stopImageStream { result in @@ -833,10 +812,7 @@ class CameraApiSetup { /// frame sent. /// /// This is used to throttle sending frames across the channel. - let receivedImageStreamDataChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.receivedImageStreamData\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let receivedImageStreamDataChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.receivedImageStreamData\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { receivedImageStreamDataChannel.setMessageHandler { _, reply in api.receivedImageStreamData { result in @@ -853,9 +829,7 @@ class CameraApiSetup { } /// Indicates that the given camera is no longer being used on the Dart side, /// and any associated resources can be cleaned up. - let disposeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let disposeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { disposeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -873,10 +847,7 @@ class CameraApiSetup { disposeChannel.setMessageHandler(nil) } /// Locks the camera capture to the current device orientation. - let lockCaptureOrientationChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.lockCaptureOrientation\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let lockCaptureOrientationChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.lockCaptureOrientation\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { lockCaptureOrientationChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -895,10 +866,7 @@ class CameraApiSetup { } /// Unlocks camera capture orientation, allowing it to automatically adapt to /// device orientation. - let unlockCaptureOrientationChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.unlockCaptureOrientation\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let unlockCaptureOrientationChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.unlockCaptureOrientation\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { unlockCaptureOrientationChannel.setMessageHandler { _, reply in api.unlockCaptureOrientation { result in @@ -915,9 +883,7 @@ class CameraApiSetup { } /// Takes a picture with the current settings, and returns the path to the /// resulting file. - let takePictureChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let takePictureChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { takePictureChannel.setMessageHandler { _, reply in api.takePicture { result in @@ -933,10 +899,7 @@ class CameraApiSetup { takePictureChannel.setMessageHandler(nil) } /// Does any preprocessing necessary before beginning to record video. - let prepareForVideoRecordingChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.prepareForVideoRecording\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let prepareForVideoRecordingChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.prepareForVideoRecording\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { prepareForVideoRecordingChannel.setMessageHandler { _, reply in api.prepareForVideoRecording { result in @@ -953,9 +916,7 @@ class CameraApiSetup { } /// Begins recording video, optionally enabling streaming to Dart at the same /// time. - let startVideoRecordingChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.startVideoRecording\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let startVideoRecordingChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.startVideoRecording\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { startVideoRecordingChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -973,9 +934,7 @@ class CameraApiSetup { startVideoRecordingChannel.setMessageHandler(nil) } /// Stops recording video, and results the path to the resulting file. - let stopVideoRecordingChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.stopVideoRecording\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let stopVideoRecordingChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.stopVideoRecording\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { stopVideoRecordingChannel.setMessageHandler { _, reply in api.stopVideoRecording { result in @@ -991,9 +950,7 @@ class CameraApiSetup { stopVideoRecordingChannel.setMessageHandler(nil) } /// Pauses video recording. - let pauseVideoRecordingChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.pauseVideoRecording\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let pauseVideoRecordingChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.pauseVideoRecording\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { pauseVideoRecordingChannel.setMessageHandler { _, reply in api.pauseVideoRecording { result in @@ -1009,9 +966,7 @@ class CameraApiSetup { pauseVideoRecordingChannel.setMessageHandler(nil) } /// Resumes a previously paused video recording. - let resumeVideoRecordingChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.resumeVideoRecording\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let resumeVideoRecordingChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.resumeVideoRecording\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { resumeVideoRecordingChannel.setMessageHandler { _, reply in api.resumeVideoRecording { result in @@ -1027,9 +982,7 @@ class CameraApiSetup { resumeVideoRecordingChannel.setMessageHandler(nil) } /// Switches the camera to the given flash mode. - let setFlashModeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setFlashModeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setFlashModeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1047,9 +1000,7 @@ class CameraApiSetup { setFlashModeChannel.setMessageHandler(nil) } /// Switches the camera to the given exposure mode. - let setExposureModeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setExposureModeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setExposureModeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1069,9 +1020,7 @@ class CameraApiSetup { /// Anchors auto-exposure to the given point in (0,1) coordinate space. /// /// A null value resets to the default exposure point. - let setExposurePointChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposurePoint\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setExposurePointChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposurePoint\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setExposurePointChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1089,9 +1038,7 @@ class CameraApiSetup { setExposurePointChannel.setMessageHandler(nil) } /// Returns the minimum exposure offset supported by the camera. - let getMinExposureOffsetChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinExposureOffset\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let getMinExposureOffsetChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinExposureOffset\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getMinExposureOffsetChannel.setMessageHandler { _, reply in api.getMinExposureOffset { result in @@ -1107,9 +1054,7 @@ class CameraApiSetup { getMinExposureOffsetChannel.setMessageHandler(nil) } /// Returns the maximum exposure offset supported by the camera. - let getMaxExposureOffsetChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxExposureOffset\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let getMaxExposureOffsetChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxExposureOffset\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getMaxExposureOffsetChannel.setMessageHandler { _, reply in api.getMaxExposureOffset { result in @@ -1125,9 +1070,7 @@ class CameraApiSetup { getMaxExposureOffsetChannel.setMessageHandler(nil) } /// Sets the exposure offset manually to the given value. - let setExposureOffsetChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureOffset\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setExposureOffsetChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureOffset\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setExposureOffsetChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1145,9 +1088,7 @@ class CameraApiSetup { setExposureOffsetChannel.setMessageHandler(nil) } /// Switches the camera to the given focus mode. - let setFocusModeChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setFocusModeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setFocusModeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1167,9 +1108,7 @@ class CameraApiSetup { /// Anchors auto-focus to the given point in (0,1) coordinate space. /// /// A null value resets to the default focus point. - let setFocusPointChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setFocusPointChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setFocusPointChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1187,9 +1126,7 @@ class CameraApiSetup { setFocusPointChannel.setMessageHandler(nil) } /// Returns the minimum zoom level supported by the camera. - let getMinZoomLevelChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let getMinZoomLevelChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getMinZoomLevelChannel.setMessageHandler { _, reply in api.getMinZoomLevel { result in @@ -1205,9 +1142,7 @@ class CameraApiSetup { getMinZoomLevelChannel.setMessageHandler(nil) } /// Returns the maximum zoom level supported by the camera. - let getMaxZoomLevelChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let getMaxZoomLevelChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getMaxZoomLevelChannel.setMessageHandler { _, reply in api.getMaxZoomLevel { result in @@ -1223,9 +1158,7 @@ class CameraApiSetup { getMaxZoomLevelChannel.setMessageHandler(nil) } /// Sets the zoom factor. - let setZoomLevelChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setZoomLevelChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setZoomLevelChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1243,10 +1176,7 @@ class CameraApiSetup { setZoomLevelChannel.setMessageHandler(nil) } /// Sets the video stabilization mode. - let setVideoStabilizationModeChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.setVideoStabilizationMode\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setVideoStabilizationModeChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setVideoStabilizationMode\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setVideoStabilizationModeChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1264,10 +1194,7 @@ class CameraApiSetup { setVideoStabilizationModeChannel.setMessageHandler(nil) } /// Gets if the given video stabilization mode is supported. - let isVideoStabilizationModeSupportedChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.isVideoStabilizationModeSupported\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let isVideoStabilizationModeSupportedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.isVideoStabilizationModeSupported\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { isVideoStabilizationModeSupportedChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1285,9 +1212,7 @@ class CameraApiSetup { isVideoStabilizationModeSupportedChannel.setMessageHandler(nil) } /// Pauses streaming of preview frames. - let pausePreviewChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let pausePreviewChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { pausePreviewChannel.setMessageHandler { _, reply in api.pausePreview { result in @@ -1303,9 +1228,7 @@ class CameraApiSetup { pausePreviewChannel.setMessageHandler(nil) } /// Resumes a previously paused preview stream. - let resumePreviewChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let resumePreviewChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { resumePreviewChannel.setMessageHandler { _, reply in api.resumePreview { result in @@ -1323,10 +1246,7 @@ class CameraApiSetup { /// Changes the camera used while recording video. /// /// This should only be called while video recording is active. - let updateDescriptionWhileRecordingChannel = FlutterBasicMessageChannel( - name: - "dev.flutter.pigeon.camera_avfoundation.CameraApi.updateDescriptionWhileRecording\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let updateDescriptionWhileRecordingChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.updateDescriptionWhileRecording\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { updateDescriptionWhileRecordingChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1344,9 +1264,7 @@ class CameraApiSetup { updateDescriptionWhileRecordingChannel.setMessageHandler(nil) } /// Sets the file format used for taking pictures. - let setImageFileFormatChannel = FlutterBasicMessageChannel( - name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setImageFileFormat\(channelSuffix)", - binaryMessenger: binaryMessenger, codec: codec) + let setImageFileFormatChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setImageFileFormat\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setImageFileFormatChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -1363,6 +1281,24 @@ class CameraApiSetup { } else { setImageFileFormatChannel.setMessageHandler(nil) } + /// Sets the JPEG compression quality for still image capture. + let setJpegImageQualityChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.camera_avfoundation.CameraApi.setJpegImageQuality\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setJpegImageQualityChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let qualityArg = args[0] as! Int64 + api.setJpegImageQuality(quality: qualityArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + setJpegImageQualityChannel.setMessageHandler(nil) + } } } @@ -1416,31 +1352,25 @@ class PigeonEventSink { } class ImageDataStreamStreamHandler: PigeonEventChannelWrapper { - static func register( - with messenger: FlutterBinaryMessenger, - instanceName: String = "", - streamHandler: ImageDataStreamStreamHandler - ) { - var channelName = - "dev.flutter.pigeon.camera_avfoundation.CameraImageStreamEventApi.imageDataStream" + static func register(with messenger: FlutterBinaryMessenger, + instanceName: String = "", + streamHandler: ImageDataStreamStreamHandler) { + var channelName = "dev.flutter.pigeon.camera_avfoundation.CameraImageStreamEventApi.imageDataStream" if !instanceName.isEmpty { channelName += ".\(instanceName)" } let internalStreamHandler = PigeonStreamHandler(wrapper: streamHandler) - let channel = FlutterEventChannel( - name: channelName, binaryMessenger: messenger, codec: messagesPigeonMethodCodec) + let channel = FlutterEventChannel(name: channelName, binaryMessenger: messenger, codec: messagesPigeonMethodCodec) channel.setStreamHandler(internalStreamHandler) } } - + /// Handler for native callbacks that are not tied to a specific camera ID. /// /// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. protocol CameraGlobalEventApiProtocol { /// Called when the device's physical orientation changes. - func deviceOrientationChanged( - orientation orientationArg: PlatformDeviceOrientation, - completion: @escaping (Result) -> Void) + func deviceOrientationChanged(orientation orientationArg: PlatformDeviceOrientation, completion: @escaping (Result) -> Void) } class CameraGlobalEventApi: CameraGlobalEventApiProtocol { private let binaryMessenger: FlutterBinaryMessenger @@ -1453,14 +1383,9 @@ class CameraGlobalEventApi: CameraGlobalEventApiProtocol { return MessagesPigeonCodec.shared } /// Called when the device's physical orientation changes. - func deviceOrientationChanged( - orientation orientationArg: PlatformDeviceOrientation, - completion: @escaping (Result) -> Void - ) { - let channelName: String = - "dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged\(messageChannelSuffix)" - let channel = FlutterBasicMessageChannel( - name: channelName, binaryMessenger: binaryMessenger, codec: codec) + func deviceOrientationChanged(orientation orientationArg: PlatformDeviceOrientation, completion: @escaping (Result) -> Void) { + let channelName: String = "dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([orientationArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) @@ -1484,9 +1409,7 @@ class CameraGlobalEventApi: CameraGlobalEventApiProtocol { /// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. protocol CameraEventApiProtocol { /// Called when the camera is inialitized for use. - func initialized( - initialState initialStateArg: PlatformCameraState, - completion: @escaping (Result) -> Void) + func initialized(initialState initialStateArg: PlatformCameraState, completion: @escaping (Result) -> Void) /// Called when an error occurs in the camera. /// /// This should be used for errors that occur outside of the context of @@ -1504,14 +1427,9 @@ class CameraEventApi: CameraEventApiProtocol { return MessagesPigeonCodec.shared } /// Called when the camera is inialitized for use. - func initialized( - initialState initialStateArg: PlatformCameraState, - completion: @escaping (Result) -> Void - ) { - let channelName: String = - "dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized\(messageChannelSuffix)" - let channel = FlutterBasicMessageChannel( - name: channelName, binaryMessenger: binaryMessenger, codec: codec) + func initialized(initialState initialStateArg: PlatformCameraState, completion: @escaping (Result) -> Void) { + let channelName: String = "dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([initialStateArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) @@ -1531,12 +1449,9 @@ class CameraEventApi: CameraEventApiProtocol { /// /// This should be used for errors that occur outside of the context of /// handling a specific HostApi call, such as during streaming. - func error(message messageArg: String, completion: @escaping (Result) -> Void) - { - let channelName: String = - "dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error\(messageChannelSuffix)" - let channel = FlutterBasicMessageChannel( - name: channelName, binaryMessenger: binaryMessenger, codec: codec) + func error(message messageArg: String, completion: @escaping (Result) -> Void) { + let channelName: String = "dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error\(messageChannelSuffix)" + let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([messageArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { completion(.failure(createConnectionError(withChannelName: channelName))) diff --git a/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart b/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart index 3907ed89219b..2327e66314c5 100644 --- a/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart +++ b/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart @@ -442,6 +442,11 @@ class AVFoundationCamera extends CameraPlatform { await _hostApi.setImageFileFormat(_pigeonImageFileFormat(format)); } + @override + Future setJpegImageQuality(int cameraId, int quality) async { + await _hostApi.setJpegImageQuality(quality); + } + @override Widget buildPreview(int cameraId) { return Texture(textureId: cameraId); diff --git a/packages/camera/camera_avfoundation/lib/src/messages.g.dart b/packages/camera/camera_avfoundation/lib/src/messages.g.dart index 46c94d58f8a1..0e2f4742098d 100644 --- a/packages/camera/camera_avfoundation/lib/src/messages.g.dart +++ b/packages/camera/camera_avfoundation/lib/src/messages.g.dart @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.5), do not edit directly. +// Autogenerated from Pigeon (v26.1.8), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -18,11 +18,7 @@ PlatformException _createConnectionError(String channelName) { ); } -List wrapResponse({ - Object? result, - PlatformException? error, - bool empty = false, -}) { +List wrapResponse({Object? result, PlatformException? error, bool empty = false}) { if (empty) { return []; } @@ -31,32 +27,26 @@ List wrapResponse({ } return [error.code, error.message, error.details]; } - bool _deepEquals(Object? a, Object? b) { if (a is List && b is List) { return a.length == b.length && - a.indexed.every( - ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), - ); + a.indexed + .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); } if (a is Map && b is Map) { - return a.length == b.length && - a.entries.every( - (MapEntry entry) => - (b as Map).containsKey(entry.key) && - _deepEquals(entry.value, b[entry.key]), - ); + return a.length == b.length && a.entries.every((MapEntry entry) => + (b as Map).containsKey(entry.key) && + _deepEquals(entry.value, b[entry.key])); } return a == b; } + enum PlatformCameraLensDirection { /// Front facing camera (a user looking at the screen is seen by the camera). front, - /// Back facing camera (a user looking at the screen is not seen by the camera). back, - /// External camera which may not be mounted to the device. external, } @@ -64,13 +54,10 @@ enum PlatformCameraLensDirection { enum PlatformCameraLensType { /// A built-in wide-angle camera device type. wide, - /// A built-in camera device type with a longer focal length than a wide-angle camera. telephoto, - /// A built-in camera device type with a shorter focal length than a wide-angle camera. ultraWide, - /// Unknown camera device type. unknown, } @@ -82,18 +69,42 @@ enum PlatformDeviceOrientation { landscapeRight, } -enum PlatformExposureMode { auto, locked } +enum PlatformExposureMode { + auto, + locked, +} -enum PlatformFlashMode { off, auto, always, torch } +enum PlatformFlashMode { + off, + auto, + always, + torch, +} -enum PlatformFocusMode { auto, locked } +enum PlatformFocusMode { + auto, + locked, +} /// Pigeon version of ImageFileFormat. -enum PlatformImageFileFormat { jpeg, heif } +enum PlatformImageFileFormat { + jpeg, + heif, +} -enum PlatformImageFormatGroup { bgra8888, yuv420 } +enum PlatformImageFormatGroup { + bgra8888, + yuv420, +} -enum PlatformResolutionPreset { low, medium, high, veryHigh, ultraHigh, max } +enum PlatformResolutionPreset { + low, + medium, + high, + veryHigh, + ultraHigh, + max, +} enum PlatformVideoStabilizationMode { off, @@ -119,12 +130,15 @@ class PlatformCameraDescription { PlatformCameraLensType lensType; List _toList() { - return [name, lensDirection, lensType]; + return [ + name, + lensDirection, + lensType, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformCameraDescription decode(Object result) { result as List; @@ -138,8 +152,7 @@ class PlatformCameraDescription { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes bool operator ==(Object other) { - if (other is! PlatformCameraDescription || - other.runtimeType != runtimeType) { + if (other is! PlatformCameraDescription || other.runtimeType != runtimeType) { return false; } if (identical(this, other)) { @@ -150,7 +163,8 @@ class PlatformCameraDescription { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } class PlatformCameraState { @@ -188,8 +202,7 @@ class PlatformCameraState { } Object encode() { - return _toList(); - } + return _toList(); } static PlatformCameraState decode(Object result) { result as List; @@ -216,7 +229,8 @@ class PlatformCameraState { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } class PlatformCameraImageData { @@ -258,8 +272,7 @@ class PlatformCameraImageData { } Object encode() { - return _toList(); - } + return _toList(); } static PlatformCameraImageData decode(Object result) { result as List; @@ -288,7 +301,8 @@ class PlatformCameraImageData { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } class PlatformCameraImagePlane { @@ -308,12 +322,16 @@ class PlatformCameraImagePlane { int height; List _toList() { - return [bytes, bytesPerRow, width, height]; + return [ + bytes, + bytesPerRow, + width, + height, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformCameraImagePlane decode(Object result) { result as List; @@ -328,8 +346,7 @@ class PlatformCameraImagePlane { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes bool operator ==(Object other) { - if (other is! PlatformCameraImagePlane || - other.runtimeType != runtimeType) { + if (other is! PlatformCameraImagePlane || other.runtimeType != runtimeType) { return false; } if (identical(this, other)) { @@ -340,7 +357,8 @@ class PlatformCameraImagePlane { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } class PlatformMediaSettings { @@ -373,8 +391,7 @@ class PlatformMediaSettings { } Object encode() { - return _toList(); - } + return _toList(); } static PlatformMediaSettings decode(Object result) { result as List; @@ -401,27 +418,36 @@ class PlatformMediaSettings { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } class PlatformPoint { - PlatformPoint({required this.x, required this.y}); + PlatformPoint({ + required this.x, + required this.y, + }); double x; double y; List _toList() { - return [x, y]; + return [ + x, + y, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformPoint decode(Object result) { result as List; - return PlatformPoint(x: result[0]! as double, y: result[1]! as double); + return PlatformPoint( + x: result[0]! as double, + y: result[1]! as double, + ); } @override @@ -438,23 +464,29 @@ class PlatformPoint { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } class PlatformSize { - PlatformSize({required this.width, required this.height}); + PlatformSize({ + required this.width, + required this.height, + }); double width; double height; List _toList() { - return [width, height]; + return [ + width, + height, + ]; } Object encode() { - return _toList(); - } + return _toList(); } static PlatformSize decode(Object result) { result as List; @@ -478,9 +510,11 @@ class PlatformSize { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); + int get hashCode => Object.hashAll(_toList()) +; } + class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -488,55 +522,55 @@ class _PigeonCodec extends StandardMessageCodec { if (value is int) { buffer.putUint8(4); buffer.putInt64(value); - } else if (value is PlatformCameraLensDirection) { + } else if (value is PlatformCameraLensDirection) { buffer.putUint8(129); writeValue(buffer, value.index); - } else if (value is PlatformCameraLensType) { + } else if (value is PlatformCameraLensType) { buffer.putUint8(130); writeValue(buffer, value.index); - } else if (value is PlatformDeviceOrientation) { + } else if (value is PlatformDeviceOrientation) { buffer.putUint8(131); writeValue(buffer, value.index); - } else if (value is PlatformExposureMode) { + } else if (value is PlatformExposureMode) { buffer.putUint8(132); writeValue(buffer, value.index); - } else if (value is PlatformFlashMode) { + } else if (value is PlatformFlashMode) { buffer.putUint8(133); writeValue(buffer, value.index); - } else if (value is PlatformFocusMode) { + } else if (value is PlatformFocusMode) { buffer.putUint8(134); writeValue(buffer, value.index); - } else if (value is PlatformImageFileFormat) { + } else if (value is PlatformImageFileFormat) { buffer.putUint8(135); writeValue(buffer, value.index); - } else if (value is PlatformImageFormatGroup) { + } else if (value is PlatformImageFormatGroup) { buffer.putUint8(136); writeValue(buffer, value.index); - } else if (value is PlatformResolutionPreset) { + } else if (value is PlatformResolutionPreset) { buffer.putUint8(137); writeValue(buffer, value.index); - } else if (value is PlatformVideoStabilizationMode) { + } else if (value is PlatformVideoStabilizationMode) { buffer.putUint8(138); writeValue(buffer, value.index); - } else if (value is PlatformCameraDescription) { + } else if (value is PlatformCameraDescription) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is PlatformCameraState) { + } else if (value is PlatformCameraState) { buffer.putUint8(140); writeValue(buffer, value.encode()); - } else if (value is PlatformCameraImageData) { + } else if (value is PlatformCameraImageData) { buffer.putUint8(141); writeValue(buffer, value.encode()); - } else if (value is PlatformCameraImagePlane) { + } else if (value is PlatformCameraImagePlane) { buffer.putUint8(142); writeValue(buffer, value.encode()); - } else if (value is PlatformMediaSettings) { + } else if (value is PlatformMediaSettings) { buffer.putUint8(143); writeValue(buffer, value.encode()); - } else if (value is PlatformPoint) { + } else if (value is PlatformPoint) { buffer.putUint8(144); writeValue(buffer, value.encode()); - } else if (value is PlatformSize) { + } else if (value is PlatformSize) { buffer.putUint8(145); writeValue(buffer, value.encode()); } else { @@ -547,51 +581,49 @@ class _PigeonCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 129: + case 129: final value = readValue(buffer) as int?; return value == null ? null : PlatformCameraLensDirection.values[value]; - case 130: + case 130: final value = readValue(buffer) as int?; return value == null ? null : PlatformCameraLensType.values[value]; - case 131: + case 131: final value = readValue(buffer) as int?; return value == null ? null : PlatformDeviceOrientation.values[value]; - case 132: + case 132: final value = readValue(buffer) as int?; return value == null ? null : PlatformExposureMode.values[value]; - case 133: + case 133: final value = readValue(buffer) as int?; return value == null ? null : PlatformFlashMode.values[value]; - case 134: + case 134: final value = readValue(buffer) as int?; return value == null ? null : PlatformFocusMode.values[value]; - case 135: + case 135: final value = readValue(buffer) as int?; return value == null ? null : PlatformImageFileFormat.values[value]; - case 136: + case 136: final value = readValue(buffer) as int?; return value == null ? null : PlatformImageFormatGroup.values[value]; - case 137: + case 137: final value = readValue(buffer) as int?; return value == null ? null : PlatformResolutionPreset.values[value]; - case 138: + case 138: final value = readValue(buffer) as int?; - return value == null - ? null - : PlatformVideoStabilizationMode.values[value]; - case 139: + return value == null ? null : PlatformVideoStabilizationMode.values[value]; + case 139: return PlatformCameraDescription.decode(readValue(buffer)!); - case 140: + case 140: return PlatformCameraState.decode(readValue(buffer)!); - case 141: + case 141: return PlatformCameraImageData.decode(readValue(buffer)!); - case 142: + case 142: return PlatformCameraImagePlane.decode(readValue(buffer)!); - case 143: + case 143: return PlatformMediaSettings.decode(readValue(buffer)!); - case 144: + case 144: return PlatformPoint.decode(readValue(buffer)!); - case 145: + case 145: return PlatformSize.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -599,21 +631,15 @@ class _PigeonCodec extends StandardMessageCodec { } } -const StandardMethodCodec pigeonMethodCodec = StandardMethodCodec( - _PigeonCodec(), -); +const StandardMethodCodec pigeonMethodCodec = StandardMethodCodec(_PigeonCodec()); class CameraApi { /// Constructor for [CameraApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - CameraApi({ - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; + CameraApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -622,8 +648,7 @@ class CameraApi { /// Returns the list of available cameras. Future> getAvailableCameras() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -645,23 +670,19 @@ class CameraApi { message: 'Host platform returned null value for non-null return value.', ); } else { - return (pigeonVar_replyList[0] as List?)! - .cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } /// Create a new camera with the given settings, and returns its ID. Future create(String cameraName, PlatformMediaSettings settings) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.create$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.create$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [cameraName, settings], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([cameraName, settings]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -682,20 +703,14 @@ class CameraApi { } /// Initializes the camera with the given ID. - Future initialize( - int cameraId, - PlatformImageFormatGroup imageFormat, - ) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize$pigeonVar_messageChannelSuffix'; + Future initialize(int cameraId, PlatformImageFormatGroup imageFormat) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.initialize$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [cameraId, imageFormat], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([cameraId, imageFormat]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -712,8 +727,7 @@ class CameraApi { /// Begins streaming frames from the camera. Future startImageStream() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startImageStream$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startImageStream$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -736,8 +750,7 @@ class CameraApi { /// Stops streaming frames from the camera. Future stopImageStream() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopImageStream$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -763,8 +776,7 @@ class CameraApi { /// /// This is used to throttle sending frames across the channel. Future receivedImageStreamData() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.receivedImageStreamData$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.receivedImageStreamData$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -788,16 +800,13 @@ class CameraApi { /// Indicates that the given camera is no longer being used on the Dart side, /// and any associated resources can be cleaned up. Future dispose(int cameraId) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.dispose$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [cameraId], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([cameraId]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -813,19 +822,14 @@ class CameraApi { } /// Locks the camera capture to the current device orientation. - Future lockCaptureOrientation( - PlatformDeviceOrientation orientation, - ) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.lockCaptureOrientation$pigeonVar_messageChannelSuffix'; + Future lockCaptureOrientation(PlatformDeviceOrientation orientation) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.lockCaptureOrientation$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [orientation], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([orientation]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -843,8 +847,7 @@ class CameraApi { /// Unlocks camera capture orientation, allowing it to automatically adapt to /// device orientation. Future unlockCaptureOrientation() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.unlockCaptureOrientation$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.unlockCaptureOrientation$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -868,8 +871,7 @@ class CameraApi { /// Takes a picture with the current settings, and returns the path to the /// resulting file. Future takePicture() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.takePicture$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -897,8 +899,7 @@ class CameraApi { /// Does any preprocessing necessary before beginning to record video. Future prepareForVideoRecording() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.prepareForVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.prepareForVideoRecording$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -922,16 +923,13 @@ class CameraApi { /// Begins recording video, optionally enabling streaming to Dart at the same /// time. Future startVideoRecording(bool enableStream) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.startVideoRecording$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [enableStream], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([enableStream]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -948,8 +946,7 @@ class CameraApi { /// Stops recording video, and results the path to the resulting file. Future stopVideoRecording() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.stopVideoRecording$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -977,8 +974,7 @@ class CameraApi { /// Pauses video recording. Future pauseVideoRecording() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pauseVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pauseVideoRecording$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1001,8 +997,7 @@ class CameraApi { /// Resumes a previously paused video recording. Future resumeVideoRecording() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumeVideoRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumeVideoRecording$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1025,16 +1020,13 @@ class CameraApi { /// Switches the camera to the given flash mode. Future setFlashMode(PlatformFlashMode mode) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFlashMode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [mode], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([mode]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1051,16 +1043,13 @@ class CameraApi { /// Switches the camera to the given exposure mode. Future setExposureMode(PlatformExposureMode mode) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureMode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [mode], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([mode]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1079,16 +1068,13 @@ class CameraApi { /// /// A null value resets to the default exposure point. Future setExposurePoint(PlatformPoint? point) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposurePoint$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposurePoint$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [point], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([point]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1105,8 +1091,7 @@ class CameraApi { /// Returns the minimum exposure offset supported by the camera. Future getMinExposureOffset() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinExposureOffset$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinExposureOffset$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1134,8 +1119,7 @@ class CameraApi { /// Returns the maximum exposure offset supported by the camera. Future getMaxExposureOffset() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxExposureOffset$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxExposureOffset$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1163,16 +1147,13 @@ class CameraApi { /// Sets the exposure offset manually to the given value. Future setExposureOffset(double offset) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureOffset$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setExposureOffset$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [offset], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([offset]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1189,16 +1170,13 @@ class CameraApi { /// Switches the camera to the given focus mode. Future setFocusMode(PlatformFocusMode mode) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusMode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [mode], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([mode]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1217,16 +1195,13 @@ class CameraApi { /// /// A null value resets to the default focus point. Future setFocusPoint(PlatformPoint? point) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setFocusPoint$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [point], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([point]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1243,8 +1218,7 @@ class CameraApi { /// Returns the minimum zoom level supported by the camera. Future getMinZoomLevel() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMinZoomLevel$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1272,8 +1246,7 @@ class CameraApi { /// Returns the maximum zoom level supported by the camera. Future getMaxZoomLevel() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.getMaxZoomLevel$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1301,16 +1274,13 @@ class CameraApi { /// Sets the zoom factor. Future setZoomLevel(double zoom) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setZoomLevel$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [zoom], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([zoom]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1326,19 +1296,14 @@ class CameraApi { } /// Sets the video stabilization mode. - Future setVideoStabilizationMode( - PlatformVideoStabilizationMode mode, - ) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setVideoStabilizationMode$pigeonVar_messageChannelSuffix'; + Future setVideoStabilizationMode(PlatformVideoStabilizationMode mode) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setVideoStabilizationMode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [mode], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([mode]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1354,19 +1319,14 @@ class CameraApi { } /// Gets if the given video stabilization mode is supported. - Future isVideoStabilizationModeSupported( - PlatformVideoStabilizationMode mode, - ) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.isVideoStabilizationModeSupported$pigeonVar_messageChannelSuffix'; + Future isVideoStabilizationModeSupported(PlatformVideoStabilizationMode mode) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.isVideoStabilizationModeSupported$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [mode], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([mode]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1388,8 +1348,7 @@ class CameraApi { /// Pauses streaming of preview frames. Future pausePreview() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.pausePreview$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1412,8 +1371,7 @@ class CameraApi { /// Resumes a previously paused preview stream. Future resumePreview() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.resumePreview$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, @@ -1438,16 +1396,13 @@ class CameraApi { /// /// This should only be called while video recording is active. Future updateDescriptionWhileRecording(String cameraName) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.updateDescriptionWhileRecording$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.updateDescriptionWhileRecording$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [cameraName], - ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([cameraName]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1464,16 +1419,36 @@ class CameraApi { /// Sets the file format used for taking pictures. Future setImageFileFormat(PlatformImageFileFormat format) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setImageFileFormat$pigeonVar_messageChannelSuffix'; + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setImageFileFormat$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [format], + final Future pigeonVar_sendFuture = pigeonVar_channel.send([format]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets the JPEG compression quality for still image capture. + Future setJpegImageQuality(int quality) async { + final pigeonVar_channelName = 'dev.flutter.pigeon.camera_avfoundation.CameraApi.setJpegImageQuality$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([quality]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); @@ -1489,18 +1464,17 @@ class CameraApi { } } -Stream imageDataStream({String instanceName = ''}) { +Stream imageDataStream( {String instanceName = ''}) { if (instanceName.isNotEmpty) { instanceName = '.$instanceName'; } - final EventChannel imageDataStreamChannel = EventChannel( - 'dev.flutter.pigeon.camera_avfoundation.CameraImageStreamEventApi.imageDataStream$instanceName', - pigeonMethodCodec, - ); + final EventChannel imageDataStreamChannel = + EventChannel('dev.flutter.pigeon.camera_avfoundation.CameraImageStreamEventApi.imageDataStream$instanceName', pigeonMethodCodec); return imageDataStreamChannel.receiveBroadcastStream().map((dynamic event) { return event as PlatformCameraImageData; }); } + /// Handler for native callbacks that are not tied to a specific camera ID. abstract class CameraGlobalEventApi { @@ -1509,44 +1483,29 @@ abstract class CameraGlobalEventApi { /// Called when the device's physical orientation changes. void deviceOrientationChanged(PlatformDeviceOrientation orientation); - static void setUp( - CameraGlobalEventApi? api, { - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) { - messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; + static void setUp(CameraGlobalEventApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) { + messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + 'dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { pigeonVar_channel.setMessageHandler((Object? message) async { - assert( - message != null, - 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged was null.', - ); + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged was null.'); final List args = (message as List?)!; - final PlatformDeviceOrientation? arg_orientation = - (args[0] as PlatformDeviceOrientation?); - assert( - arg_orientation != null, - 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged was null, expected non-null PlatformDeviceOrientation.', - ); + final PlatformDeviceOrientation? arg_orientation = (args[0] as PlatformDeviceOrientation?); + assert(arg_orientation != null, + 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraGlobalEventApi.deviceOrientationChanged was null, expected non-null PlatformDeviceOrientation.'); try { api.deviceOrientationChanged(arg_orientation!); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } @@ -1569,77 +1528,54 @@ abstract class CameraEventApi { /// handling a specific HostApi call, such as during streaming. void error(String message); - static void setUp( - CameraEventApi? api, { - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) { - messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; + static void setUp(CameraEventApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) { + messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + 'dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { pigeonVar_channel.setMessageHandler((Object? message) async { - assert( - message != null, - 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized was null.', - ); + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized was null.'); final List args = (message as List?)!; - final PlatformCameraState? arg_initialState = - (args[0] as PlatformCameraState?); - assert( - arg_initialState != null, - 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized was null, expected non-null PlatformCameraState.', - ); + final PlatformCameraState? arg_initialState = (args[0] as PlatformCameraState?); + assert(arg_initialState != null, + 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.initialized was null, expected non-null PlatformCameraState.'); try { api.initialized(arg_initialState!); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger, - ); + 'dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error$messageChannelSuffix', pigeonChannelCodec, + binaryMessenger: binaryMessenger); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { pigeonVar_channel.setMessageHandler((Object? message) async { - assert( - message != null, - 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error was null.', - ); + assert(message != null, + 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error was null.'); final List args = (message as List?)!; final String? arg_message = (args[0] as String?); - assert( - arg_message != null, - 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error was null, expected non-null String.', - ); + assert(arg_message != null, + 'Argument for dev.flutter.pigeon.camera_avfoundation.CameraEventApi.error was null, expected non-null String.'); try { api.error(arg_message!); return wrapResponse(empty: true); } on PlatformException catch (e) { return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); } }); } diff --git a/packages/camera/camera_avfoundation/pigeons/messages.dart b/packages/camera/camera_avfoundation/pigeons/messages.dart index b4976758cf47..2d0e3ceec187 100644 --- a/packages/camera/camera_avfoundation/pigeons/messages.dart +++ b/packages/camera/camera_avfoundation/pigeons/messages.dart @@ -349,6 +349,11 @@ abstract class CameraApi { @async @ObjCSelector('setImageFileFormat:') void setImageFileFormat(PlatformImageFileFormat format); + + /// Sets the JPEG compression quality for still image capture. + @async + @ObjCSelector('setJpegImageQuality:') + void setJpegImageQuality(int quality); } @EventChannelApi() diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index 8a10d0d21f72..7ff9cd278609 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.10.1 +version: 0.10.2 environment: sdk: ^3.9.0 @@ -17,7 +17,7 @@ flutter: dartPluginClass: AVFoundationCamera dependencies: - camera_platform_interface: ^2.12.0 + camera_platform_interface: ^2.13.0 flutter: sdk: flutter stream_transform: ^2.0.0 diff --git a/packages/camera/camera_avfoundation/test/avfoundation_camera_test.dart b/packages/camera/camera_avfoundation/test/avfoundation_camera_test.dart index 53d7965c6bac..733d5e0d8e05 100644 --- a/packages/camera/camera_avfoundation/test/avfoundation_camera_test.dart +++ b/packages/camera/camera_avfoundation/test/avfoundation_camera_test.dart @@ -992,5 +992,11 @@ void main() { verify(mockApi.setImageFileFormat(PlatformImageFileFormat.jpeg)); }); + + test('Should set the image quality', () async { + await camera.setJpegImageQuality(cameraId, 50); + + verify(mockApi.setJpegImageQuality(50)); + }); }); } diff --git a/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart b/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart index 225eac9931c6..7e946cdf89f5 100644 --- a/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart +++ b/packages/camera/camera_avfoundation/test/avfoundation_camera_test.mocks.dart @@ -22,6 +22,7 @@ import 'package:mockito/src/dummies.dart' as _i3; // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +// ignore_for_file: invalid_use_of_internal_member /// A class which mocks [CameraApi]. /// @@ -360,4 +361,13 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + + @override + _i4.Future setJpegImageQuality(int? quality) => + (super.noSuchMethod( + Invocation.method(#setJpegImageQuality, [quality]), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); }