From e78dd63d218b1f615b1e3db18eaa755c51b4e5c8 Mon Sep 17 00:00:00 2001 From: Camille Simon <43054281+camsim99@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:06:06 -0400 Subject: [PATCH] [camerax] Use `AspectRatioStrategy` to help automatic selection of expected resolution (#6357) Defines `AspectRatioStategy`s that will help CameraX select the resolution we expect. Fixes https://github.com/flutter/flutter/issues/144363. --- .../camera_android_camerax/CHANGELOG.md | 6 + .../camerax/CameraAndroidCameraxPlugin.java | 2 + .../camerax/GeneratedCameraXLibrary.java | 80 ++- .../camerax/ResolutionFilterHostApiImpl.java | 94 +++ .../ResolutionSelectorHostApiImpl.java | 17 +- .../plugins/camerax/ResolutionFilterTest.java | 76 +++ .../camerax/ResolutionSelectorTest.java | 13 +- .../lib/src/android_camera_camerax.dart | 22 +- .../lib/src/camerax_library.g.dart | 65 +- .../lib/src/camerax_proxy.dart | 45 +- .../lib/src/resolution_filter.dart | 107 +++ .../lib/src/resolution_selector.dart | 16 +- .../lib/src/zoom_state.dart | 2 +- .../pigeons/camerax_library.dart | 7 + .../camera_android_camerax/pubspec.yaml | 2 +- .../test/android_camera_camerax_test.dart | 386 +++++++---- .../android_camera_camerax_test.mocks.dart | 613 ++++++++++-------- .../test/resolution_filter_test.dart | 90 +++ .../test/resolution_filter_test.mocks.dart | 67 ++ .../test/resolution_selector_test.dart | 26 +- .../test/resolution_selector_test.mocks.dart | 48 +- .../test/test_camerax_library.g.dart | 75 ++- 22 files changed, 1431 insertions(+), 428 deletions(-) create mode 100644 packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionFilterHostApiImpl.java create mode 100644 packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionFilterTest.java create mode 100644 packages/camera/camera_android_camerax/lib/src/resolution_filter.dart create mode 100644 packages/camera/camera_android_camerax/test/resolution_filter_test.dart create mode 100644 packages/camera/camera_android_camerax/test/resolution_filter_test.mocks.dart diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 2226ba4352c7..68fdea1e7554 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.1 + +* Modifies resolution selection logic to use an `AspectRatioStrategy` for all aspect ratios supported by CameraX. +* Adds `ResolutionFilter` to resolution selection logic to prioritize resolutions that match + the defined `ResolutionPreset`s. + ## 0.6.0+1 * Updates `README.md` to encourage developers to opt into this implementation of the camera plugin. diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java index 6a30074a2f87..d281bbe65a8c 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java @@ -134,6 +134,8 @@ public void setUp( binaryMessenger, new FocusMeteringResultHostApiImpl(instanceManager)); meteringPointHostApiImpl = new MeteringPointHostApiImpl(instanceManager); GeneratedCameraXLibrary.MeteringPointHostApi.setup(binaryMessenger, meteringPointHostApiImpl); + GeneratedCameraXLibrary.ResolutionFilterHostApi.setup( + binaryMessenger, new ResolutionFilterHostApiImpl(instanceManager)); } @Override diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java index 75b4a8c276bc..fa6be7920961 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java @@ -2507,6 +2507,7 @@ public interface ResolutionSelectorHostApi { void create( @NonNull Long identifier, @Nullable Long resolutionStrategyIdentifier, + @Nullable Long resolutionSelectorIdentifier, @Nullable Long aspectRatioStrategyIdentifier); /** The codec used by ResolutionSelectorHostApi. */ @@ -2530,13 +2531,17 @@ static void setup( ArrayList args = (ArrayList) message; Number identifierArg = (Number) args.get(0); Number resolutionStrategyIdentifierArg = (Number) args.get(1); - Number aspectRatioStrategyIdentifierArg = (Number) args.get(2); + Number resolutionSelectorIdentifierArg = (Number) args.get(2); + Number aspectRatioStrategyIdentifierArg = (Number) args.get(3); try { api.create( (identifierArg == null) ? null : identifierArg.longValue(), (resolutionStrategyIdentifierArg == null) ? null : resolutionStrategyIdentifierArg.longValue(), + (resolutionSelectorIdentifierArg == null) + ? null + : resolutionSelectorIdentifierArg.longValue(), (aspectRatioStrategyIdentifierArg == null) ? null : aspectRatioStrategyIdentifierArg.longValue()); @@ -4189,4 +4194,77 @@ public void error(Throwable error) { } } } + + private static class ResolutionFilterHostApiCodec extends StandardMessageCodec { + public static final ResolutionFilterHostApiCodec INSTANCE = new ResolutionFilterHostApiCodec(); + + private ResolutionFilterHostApiCodec() {} + + @Override + protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { + switch (type) { + case (byte) 128: + return ResolutionInfo.fromList((ArrayList) readValue(buffer)); + default: + return super.readValueOfType(type, buffer); + } + } + + @Override + protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { + if (value instanceof ResolutionInfo) { + stream.write(128); + writeValue(stream, ((ResolutionInfo) value).toList()); + } else { + super.writeValue(stream, value); + } + } + } + + /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ + public interface ResolutionFilterHostApi { + + void createWithOnePreferredSize( + @NonNull Long identifier, @NonNull ResolutionInfo preferredResolution); + + /** The codec used by ResolutionFilterHostApi. */ + static @NonNull MessageCodec getCodec() { + return ResolutionFilterHostApiCodec.INSTANCE; + } + /** + * Sets up an instance of `ResolutionFilterHostApi` to handle messages through the + * `binaryMessenger`. + */ + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable ResolutionFilterHostApi api) { + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.ResolutionFilterHostApi.createWithOnePreferredSize", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number identifierArg = (Number) args.get(0); + ResolutionInfo preferredResolutionArg = (ResolutionInfo) args.get(1); + try { + api.createWithOnePreferredSize( + (identifierArg == null) ? null : identifierArg.longValue(), + preferredResolutionArg); + wrapped.add(0, null); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } } diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionFilterHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionFilterHostApiImpl.java new file mode 100644 index 000000000000..b2c3c9e69123 --- /dev/null +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionFilterHostApiImpl.java @@ -0,0 +1,94 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.camerax; + +import android.util.Size; +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import androidx.camera.core.resolutionselector.ResolutionFilter; +import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionFilterHostApi; +import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionInfo; +import java.util.List; + +/** + * Host API implementation for {@link ResolutionFilter}. + * + *

This class handles instantiating and adding native object instances that are attached to a + * Dart instance or handle method calls on the associated native class or an instance of the class. + */ +public class ResolutionFilterHostApiImpl implements ResolutionFilterHostApi { + private final InstanceManager instanceManager; + private final ResolutionFilterFactory resolutionFilterFactory; + + /** + * Proxy for constructing {@link ResolutionFilter}s with particular attributes, as detailed by + * documentation below. + */ + @VisibleForTesting + public static class ResolutionFilterFactory { + /** + * Creates an instance of {@link ResolutionFilter} that moves the {@code preferredSize} to the + * front of the list of supported resolutions so that it can be prioritized by CameraX. + * + *

If the preferred {@code Size} is not found, then this creates a {@link ResolutionFilter} + * that leaves the priority of supported resolutions unadjusted. + */ + @NonNull + public ResolutionFilter createWithOnePreferredSize(@NonNull Size preferredSize) { + return new ResolutionFilter() { + @Override + @NonNull + public List filter(@NonNull List supportedSizes, int rotationDegrees) { + int preferredSizeIndex = supportedSizes.indexOf(preferredSize); + + if (preferredSizeIndex > -1) { + supportedSizes.remove(preferredSizeIndex); + supportedSizes.add(0, preferredSize); + } + + return supportedSizes; + } + }; + } + } + + /** + * Constructs a {@link ResolutionFilterHostApiImpl}. + * + * @param instanceManager maintains instances stored to communicate with attached Dart objects + */ + public ResolutionFilterHostApiImpl(@NonNull InstanceManager instanceManager) { + this(instanceManager, new ResolutionFilterFactory()); + } + + /** + * Constructs a {@link ResolutionFilterHostApiImpl}. + * + * @param instanceManager maintains instances stored to communicate with attached Dart objects + * @param resolutionFilterFactory proxy for constructing different kinds of {@link + * ResolutionFilter}s + */ + @VisibleForTesting + ResolutionFilterHostApiImpl( + @NonNull InstanceManager instanceManager, + @NonNull ResolutionFilterFactory resolutionFilterFactory) { + this.instanceManager = instanceManager; + this.resolutionFilterFactory = resolutionFilterFactory; + } + + /** + * Creates a {@link ResolutionFilter} that prioritizes the specified {@code preferredResolution} + * over all other resolutions. + */ + @Override + public void createWithOnePreferredSize( + @NonNull Long identifier, @NonNull ResolutionInfo preferredResolution) { + Size preferredSize = + new Size( + preferredResolution.getWidth().intValue(), preferredResolution.getHeight().intValue()); + instanceManager.addDartCreatedInstance( + resolutionFilterFactory.createWithOnePreferredSize(preferredSize), identifier); + } +} diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionSelectorHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionSelectorHostApiImpl.java index 4aa11cd593f2..0a5fe750d163 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionSelectorHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionSelectorHostApiImpl.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.camera.core.resolutionselector.AspectRatioStrategy; +import androidx.camera.core.resolutionselector.ResolutionFilter; import androidx.camera.core.resolutionselector.ResolutionSelector; import androidx.camera.core.resolutionselector.ResolutionStrategy; import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionSelectorHostApi; @@ -30,7 +31,8 @@ public static class ResolutionSelectorProxy { @NonNull public ResolutionSelector create( @Nullable ResolutionStrategy resolutionStrategy, - @Nullable AspectRatioStrategy aspectRatioStrategy) { + @Nullable AspectRatioStrategy aspectRatioStrategy, + @Nullable ResolutionFilter resolutionFilter) { final ResolutionSelector.Builder builder = new ResolutionSelector.Builder(); if (resolutionStrategy != null) { builder.setResolutionStrategy(resolutionStrategy); @@ -38,6 +40,9 @@ public ResolutionSelector create( if (aspectRatioStrategy != null) { builder.setAspectRatioStrategy(aspectRatioStrategy); } + if (resolutionFilter != null) { + builder.setResolutionFilter(resolutionFilter); + } return builder.build(); } } @@ -65,13 +70,14 @@ public ResolutionSelectorHostApiImpl(@NonNull InstanceManager instanceManager) { } /** - * Creates a {@link ResolutionSelector} instance with the {@link ResolutionStrategy} and {@link - * AspectRatio} that have the identifiers specified if provided. + * Creates a {@link ResolutionSelector} instance with the {@link ResolutionStrategy}, {@link + * ResolutionFilter}, and {@link AspectRatio} that have the identifiers specified if provided. */ @Override public void create( @NonNull Long identifier, @Nullable Long resolutionStrategyIdentifier, + @Nullable Long resolutionFilterIdentifier, @Nullable Long aspectRatioStrategyIdentifier) { instanceManager.addDartCreatedInstance( proxy.create( @@ -81,7 +87,10 @@ public void create( aspectRatioStrategyIdentifier == null ? null : Objects.requireNonNull( - instanceManager.getInstance(aspectRatioStrategyIdentifier))), + instanceManager.getInstance(aspectRatioStrategyIdentifier)), + resolutionFilterIdentifier == null + ? null + : Objects.requireNonNull(instanceManager.getInstance(resolutionFilterIdentifier))), identifier); } } diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionFilterTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionFilterTest.java new file mode 100644 index 000000000000..150f5676739a --- /dev/null +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionFilterTest.java @@ -0,0 +1,76 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.camerax; + +import static org.junit.Assert.assertEquals; + +import android.util.Size; +import androidx.camera.core.resolutionselector.ResolutionFilter; +import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionInfo; +import java.util.ArrayList; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class ResolutionFilterTest { + @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + + InstanceManager instanceManager; + + @Before + public void setUp() { + instanceManager = InstanceManager.create(identifier -> {}); + } + + @After + public void tearDown() { + instanceManager.stopFinalizationListener(); + } + + @Test + public void hostApiCreateWithOnePreferredSize_createsExpectedResolutionFilterInstance() { + final ResolutionFilterHostApiImpl hostApi = new ResolutionFilterHostApiImpl(instanceManager); + final long instanceIdentifier = 50; + final long preferredResolutionWidth = 20; + final long preferredResolutionHeight = 80; + final ResolutionInfo preferredResolution = + new ResolutionInfo.Builder() + .setWidth(preferredResolutionWidth) + .setHeight(preferredResolutionHeight) + .build(); + + hostApi.createWithOnePreferredSize(instanceIdentifier, preferredResolution); + + // Test that instance filters supported resolutions as expected. + final ResolutionFilter resolutionFilter = instanceManager.getInstance(instanceIdentifier); + final Size fakeSupportedSize1 = new Size(720, 480); + final Size fakeSupportedSize2 = new Size(20, 80); + final Size fakeSupportedSize3 = new Size(2, 8); + final Size preferredSize = + new Size((int) preferredResolutionWidth, (int) preferredResolutionHeight); + + final ArrayList fakeSupportedSizes = new ArrayList(); + fakeSupportedSizes.add(fakeSupportedSize1); + fakeSupportedSizes.add(fakeSupportedSize2); + fakeSupportedSizes.add(preferredSize); + fakeSupportedSizes.add(fakeSupportedSize3); + + // Test the case where preferred resolution is supported. + List filteredSizes = resolutionFilter.filter(fakeSupportedSizes, 90); + assertEquals(filteredSizes.get(0), preferredSize); + + // Test the case where preferred resolution is not supported. + fakeSupportedSizes.remove(0); + filteredSizes = resolutionFilter.filter(fakeSupportedSizes, 90); + assertEquals(filteredSizes, fakeSupportedSizes); + } +} diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionSelectorTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionSelectorTest.java index f323e4706c9b..0f45f07b4f7a 100644 --- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionSelectorTest.java +++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionSelectorTest.java @@ -9,6 +9,7 @@ import static org.mockito.Mockito.when; import androidx.camera.core.resolutionselector.AspectRatioStrategy; +import androidx.camera.core.resolutionselector.ResolutionFilter; import androidx.camera.core.resolutionselector.ResolutionSelector; import androidx.camera.core.resolutionselector.ResolutionStrategy; import org.junit.After; @@ -46,13 +47,21 @@ public void hostApiCreate_createsExpectedResolutionSelectorInstance() { final long aspectRatioStrategyIdentifier = 15; instanceManager.addDartCreatedInstance(mockAspectRatioStrategy, aspectRatioStrategyIdentifier); - when(mockProxy.create(mockResolutionStrategy, mockAspectRatioStrategy)) + final ResolutionFilter mockResolutionFilter = mock(ResolutionFilter.class); + final long resolutionFilterIdentifier = 33; + instanceManager.addDartCreatedInstance(mockResolutionFilter, resolutionFilterIdentifier); + + when(mockProxy.create(mockResolutionStrategy, mockAspectRatioStrategy, mockResolutionFilter)) .thenReturn(mockResolutionSelector); final ResolutionSelectorHostApiImpl hostApi = new ResolutionSelectorHostApiImpl(instanceManager, mockProxy); final long instanceIdentifier = 0; - hostApi.create(instanceIdentifier, resolutionStrategyIdentifier, aspectRatioStrategyIdentifier); + hostApi.create( + instanceIdentifier, + resolutionStrategyIdentifier, + resolutionFilterIdentifier, + aspectRatioStrategyIdentifier); assertEquals(instanceManager.getInstance(instanceIdentifier), mockResolutionSelector); } 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 1612ab512d32..19aaea83fa3d 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 @@ -9,10 +9,12 @@ import 'package:async/async.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart' show DeviceOrientation, PlatformException; -import 'package:flutter/widgets.dart'; +import 'package:flutter/widgets.dart' + show Size, Texture, Widget, visibleForTesting; import 'package:stream_transform/stream_transform.dart'; import 'analyzer.dart'; +import 'aspect_ratio_strategy.dart'; import 'camera.dart'; import 'camera2_camera_control.dart'; import 'camera_control.dart'; @@ -40,6 +42,7 @@ import 'process_camera_provider.dart'; import 'quality_selector.dart'; import 'recorder.dart'; import 'recording.dart'; +import 'resolution_filter.dart'; import 'resolution_selector.dart'; import 'resolution_strategy.dart'; import 'surface.dart'; @@ -1150,23 +1153,29 @@ class AndroidCameraCameraX extends CameraPlatform { ResolutionStrategy.fallbackRuleClosestLowerThenHigher; Size? boundSize; + int? aspectRatio; ResolutionStrategy? resolutionStrategy; switch (preset) { case ResolutionPreset.low: boundSize = const Size(320, 240); + aspectRatio = AspectRatio.ratio4To3; case ResolutionPreset.medium: boundSize = const Size(720, 480); case ResolutionPreset.high: boundSize = const Size(1280, 720); + aspectRatio = AspectRatio.ratio16To9; case ResolutionPreset.veryHigh: boundSize = const Size(1920, 1080); + aspectRatio = AspectRatio.ratio16To9; case ResolutionPreset.ultraHigh: boundSize = const Size(3840, 2160); + aspectRatio = AspectRatio.ratio16To9; case ResolutionPreset.max: // Automatically set strategy to choose highest available. resolutionStrategy = proxy.createResolutionStrategy(highestAvailable: true); - return proxy.createResolutionSelector(resolutionStrategy); + return proxy.createResolutionSelector(resolutionStrategy, + /* ResolutionFilter */ null, /* AspectRatioStrategy */ null); case null: // If no preset is specified, default to CameraX's default behavior // for each UseCase. @@ -1175,7 +1184,14 @@ class AndroidCameraCameraX extends CameraPlatform { resolutionStrategy = proxy.createResolutionStrategy( boundSize: boundSize, fallbackRule: fallbackRule); - return proxy.createResolutionSelector(resolutionStrategy); + final ResolutionFilter resolutionFilter = + proxy.createResolutionFilterWithOnePreferredSize(boundSize); + final AspectRatioStrategy? aspectRatioStrategy = aspectRatio == null + ? null + : proxy.createAspectRatioStrategy( + aspectRatio, AspectRatioStrategy.fallbackRuleAuto); + return proxy.createResolutionSelector( + resolutionStrategy, resolutionFilter, aspectRatioStrategy); } /// Returns the [QualitySelector] that maps to the specified resolution 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 78c167bc4a11..ac66dfd0ae77 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 @@ -1914,7 +1914,10 @@ class ResolutionSelectorHostApi { static const MessageCodec codec = StandardMessageCodec(); - Future create(int arg_identifier, int? arg_resolutionStrategyIdentifier, + Future create( + int arg_identifier, + int? arg_resolutionStrategyIdentifier, + int? arg_resolutionSelectorIdentifier, int? arg_aspectRatioStrategyIdentifier) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.ResolutionSelectorHostApi.create', codec, @@ -1922,6 +1925,7 @@ class ResolutionSelectorHostApi { final List? replyList = await channel.send([ arg_identifier, arg_resolutionStrategyIdentifier, + arg_resolutionSelectorIdentifier, arg_aspectRatioStrategyIdentifier ]) as List?; if (replyList == null) { @@ -3340,3 +3344,62 @@ class Camera2CameraControlHostApi { } } } + +class _ResolutionFilterHostApiCodec extends StandardMessageCodec { + const _ResolutionFilterHostApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is ResolutionInfo) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return ResolutionInfo.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class ResolutionFilterHostApi { + /// Constructor for [ResolutionFilterHostApi]. 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. + ResolutionFilterHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _ResolutionFilterHostApiCodec(); + + Future createWithOnePreferredSize( + int arg_identifier, ResolutionInfo arg_preferredResolution) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.ResolutionFilterHostApi.createWithOnePreferredSize', + codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_identifier, arg_preferredResolution]) + as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +} diff --git a/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart b/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart index fb100ddb20a2..6fec50ce3983 100644 --- a/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart +++ b/packages/camera/camera_android_camerax/lib/src/camerax_proxy.dart @@ -5,6 +5,7 @@ import 'dart:ui' show Size; import 'analyzer.dart'; +import 'aspect_ratio_strategy.dart'; import 'camera2_camera_control.dart'; import 'camera_control.dart'; import 'camera_info.dart'; @@ -24,6 +25,7 @@ import 'preview.dart'; import 'process_camera_provider.dart'; import 'quality_selector.dart'; import 'recorder.dart'; +import 'resolution_filter.dart'; import 'resolution_selector.dart'; import 'resolution_strategy.dart'; import 'system_services.dart'; @@ -59,6 +61,9 @@ class CameraXProxy { this.createCaptureRequestOptions = _createAttachedCaptureRequestOptions, this.createMeteringPoint = _createAttachedMeteringPoint, this.createFocusMeteringAction = _createAttachedFocusMeteringAction, + this.createAspectRatioStrategy = _createAttachedAspectRatioStrategy, + this.createResolutionFilterWithOnePreferredSize = + _createAttachedResolutionFilterWithOnePreferredSize, }); /// Returns a [ProcessCameraProvider] instance. @@ -115,9 +120,11 @@ class CameraXProxy { int? fallbackRule}) createResolutionStrategy; /// Returns a [ResolutionSelector] configured with the specified - /// [ResolutionStrategy]. - ResolutionSelector Function(ResolutionStrategy resolutionStrategy) - createResolutionSelector; + /// [ResolutionStrategy], [ResolutionFilter], and [AspectRatioStrategy]. + ResolutionSelector Function( + ResolutionStrategy resolutionStrategy, + ResolutionFilter? resolutionFilter, + AspectRatioStrategy? aspectRatioStrategy) createResolutionSelector; /// Returns a [FallbackStrategy] configured with the specified [VideoQuality] /// and [VideoResolutionFallbackRule]. @@ -151,7 +158,7 @@ class CameraXProxy { Camera2CameraControl Function(CameraControl cameraControl) getCamera2CameraControl; - /// Create [CapureRequestOptions] with specified options. + /// Creates a [CaptureRequestOptions] with specified options. CaptureRequestOptions Function( List<(CaptureRequestKeySupportedType, Object?)> options) createCaptureRequestOptions; @@ -167,6 +174,15 @@ class CameraXProxy { FocusMeteringAction Function(List<(MeteringPoint, int?)> meteringPointInfos, bool? disableAutoCancel) createFocusMeteringAction; + /// Creates an [AspectRatioStrategy] with specified aspect ratio and fallback + /// rule. + AspectRatioStrategy Function(int aspectRatio, int fallbackRule) + createAspectRatioStrategy; + + /// Creates a [ResolutionFilter] that prioritizes specified resolution. + ResolutionFilter Function(Size preferredResolution) + createResolutionFilterWithOnePreferredSize; + static Future _getProcessCameraProvider() { return ProcessCameraProvider.getInstance(); } @@ -234,8 +250,13 @@ class CameraXProxy { } static ResolutionSelector _createAttachedResolutionSelector( - ResolutionStrategy resolutionStrategy) { - return ResolutionSelector(resolutionStrategy: resolutionStrategy); + ResolutionStrategy resolutionStrategy, + ResolutionFilter? resolutionFilter, + AspectRatioStrategy? aspectRatioStrategy) { + return ResolutionSelector( + resolutionStrategy: resolutionStrategy, + resolutionFilter: resolutionFilter, + aspectRatioStrategy: aspectRatioStrategy); } static FallbackStrategy _createAttachedFallbackStrategy( @@ -291,4 +312,16 @@ class CameraXProxy { meteringPointInfos: meteringPointInfos, disableAutoCancel: disableAutoCancel); } + + static AspectRatioStrategy _createAttachedAspectRatioStrategy( + int preferredAspectRatio, int fallbackRule) { + return AspectRatioStrategy( + preferredAspectRatio: preferredAspectRatio, fallbackRule: fallbackRule); + } + + static ResolutionFilter _createAttachedResolutionFilterWithOnePreferredSize( + Size preferredSize) { + return ResolutionFilter.onePreferredSize( + preferredResolution: preferredSize); + } } diff --git a/packages/camera/camera_android_camerax/lib/src/resolution_filter.dart b/packages/camera/camera_android_camerax/lib/src/resolution_filter.dart new file mode 100644 index 000000000000..3a428a00e73a --- /dev/null +++ b/packages/camera/camera_android_camerax/lib/src/resolution_filter.dart @@ -0,0 +1,107 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable; + +import 'camerax_library.g.dart'; +import 'instance_manager.dart'; +import 'java_object.dart'; + +/// Filterer for applications to specify preferred resolutions. +/// +/// This is an indirect wrapping of the native Android `ResolutionFilter`, +/// an interface that requires a synchronous response. Achieving such is not +/// possible through pigeon. Thus, constructing a [ResolutionFilter] with a +/// particular constructor will create a native `ResolutionFilter` with the +/// characteristics described in the documentation for that constructor, +/// respectively. +/// +/// If the provided constructors do not meet your needs, feel free to add a new +/// constructor; see CONTRIBUTING.MD for more information on how to do so. +/// +/// See https://developer.android.com/reference/androidx/camera/core/ResolutionFilter/ResolutionFilter. +@immutable +class ResolutionFilter extends JavaObject { + /// Constructs a [ResolutionFilter]. + /// + /// This will construct a native `ResolutionFilter` that will prioritize the + /// specified [preferredResolution] (if supported) over other supported + /// resolutions, whose priorities (as determined by CameraX) will remain the + /// same. + ResolutionFilter.onePreferredSize({ + required this.preferredResolution, + super.binaryMessenger, + super.instanceManager, + }) : _api = _ResolutionFilterHostApiImpl( + instanceManager: instanceManager, + binaryMessenger: binaryMessenger, + ), + super.detached() { + _api.createWithOnePreferredSizeFromInstances(this, preferredResolution); + } + + /// Instantiates a [ResolutionFilter.onePreferredSize] that is not + /// automatically attached to a native object. + ResolutionFilter.onePreferredSizeDetached({ + required this.preferredResolution, + super.binaryMessenger, + super.instanceManager, + }) : _api = _ResolutionFilterHostApiImpl( + instanceManager: instanceManager, + binaryMessenger: binaryMessenger, + ), + super.detached(); + + final _ResolutionFilterHostApiImpl _api; + + /// The resolution for a [ResolutionFilter.onePreferredSize] to prioritize. + final Size preferredResolution; +} + +/// Host API implementation of [ResolutionFilter]. +class _ResolutionFilterHostApiImpl extends ResolutionFilterHostApi { + /// Constructs an [_ResolutionFilterHostApiImpl]. + /// + /// If [binaryMessenger] is null, the default [BinaryMessenger] will be used, + /// which routes to the host platform. + /// + /// An [instanceManager] is typically passed when a copy of an instance + /// contained by an [InstanceManager] is being created. If left null, it + /// will default to the global instance defined in [JavaObject]. + _ResolutionFilterHostApiImpl({ + this.binaryMessenger, + InstanceManager? instanceManager, + }) : instanceManager = instanceManager ?? JavaObject.globalInstanceManager, + super(binaryMessenger: binaryMessenger); + + /// Receives binary data across the Flutter platform barrier. + final BinaryMessenger? binaryMessenger; + + /// Maintains instances stored to communicate with native language objects. + final InstanceManager instanceManager; + + /// Creates a [ResolutionFilter] on the native side that will prioritize + /// the specified [preferredResolution]. + Future createWithOnePreferredSizeFromInstances( + ResolutionFilter instance, + Size preferredResolution, + ) { + return createWithOnePreferredSize( + instanceManager.addDartCreatedInstance( + instance, + onCopy: (ResolutionFilter original) => + ResolutionFilter.onePreferredSizeDetached( + preferredResolution: original.preferredResolution, + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + ), + ResolutionInfo( + width: preferredResolution.width.toInt(), + height: preferredResolution.height.toInt(), + ), + ); + } +} diff --git a/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart b/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart index 74191724e5ce..3017daab811a 100644 --- a/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart +++ b/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart @@ -9,6 +9,7 @@ import 'aspect_ratio_strategy.dart'; import 'camerax_library.g.dart'; import 'instance_manager.dart'; import 'java_object.dart'; +import 'resolution_filter.dart'; import 'resolution_strategy.dart'; /// A set of requirements and priorities used to select a resolution for a @@ -20,6 +21,7 @@ class ResolutionSelector extends JavaObject { /// Construct a [ResolutionSelector]. ResolutionSelector({ this.resolutionStrategy, + this.resolutionFilter, this.aspectRatioStrategy, super.binaryMessenger, super.instanceManager, @@ -28,7 +30,8 @@ class ResolutionSelector extends JavaObject { binaryMessenger: binaryMessenger, ), super.detached() { - _api.createFromInstances(this, resolutionStrategy, aspectRatioStrategy); + _api.createFromInstances( + this, resolutionStrategy, resolutionFilter, aspectRatioStrategy); } /// Instantiates a [ResolutionSelector] without creating and attaching to an @@ -38,6 +41,7 @@ class ResolutionSelector extends JavaObject { /// library or to create a copy for an [InstanceManager]. ResolutionSelector.detached({ this.resolutionStrategy, + this.resolutionFilter, this.aspectRatioStrategy, super.binaryMessenger, super.instanceManager, @@ -53,6 +57,9 @@ class ResolutionSelector extends JavaObject { /// image. final ResolutionStrategy? resolutionStrategy; + /// Filter for CameraX to automatically select a desirable resolution. + final ResolutionFilter? resolutionFilter; + /// Determines how the UseCase will choose the aspect ratio of the captured /// image. final AspectRatioStrategy? aspectRatioStrategy; @@ -81,10 +88,12 @@ class _ResolutionSelectorHostApiImpl extends ResolutionSelectorHostApi { final InstanceManager instanceManager; /// Creates a [ResolutionSelector] on the native side with the - /// [ResolutionStrategy] and [AspectRatioStrategy] if specified. + /// [ResolutionStrategy], [ResolutionFilter], and [AspectRatioStrategy] if + /// specified. Future createFromInstances( ResolutionSelector instance, ResolutionStrategy? resolutionStrategy, + ResolutionFilter? resolutionFilter, AspectRatioStrategy? aspectRatioStrategy, ) { return create( @@ -100,6 +109,9 @@ class _ResolutionSelectorHostApiImpl extends ResolutionSelectorHostApi { resolutionStrategy == null ? null : instanceManager.getIdentifier(resolutionStrategy)!, + resolutionFilter == null + ? null + : instanceManager.getIdentifier(resolutionFilter)!, aspectRatioStrategy == null ? null : instanceManager.getIdentifier(aspectRatioStrategy)!, diff --git a/packages/camera/camera_android_camerax/lib/src/zoom_state.dart b/packages/camera/camera_android_camerax/lib/src/zoom_state.dart index 4c93d41e0249..6fe5321389b6 100644 --- a/packages/camera/camera_android_camerax/lib/src/zoom_state.dart +++ b/packages/camera/camera_android_camerax/lib/src/zoom_state.dart @@ -15,7 +15,7 @@ import 'java_object.dart'; /// See https://developer.android.com/reference/androidx/camera/core/ZoomState. @immutable class ZoomState extends JavaObject { - /// Constructs a [CameraInfo] that is not automatically attached to a native object. + /// Constructs a [ZoomState] that is not automatically attached to a native object. ZoomState.detached( {super.binaryMessenger, super.instanceManager, diff --git a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart index 103c260c25c1..18741904a8d0 100644 --- a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart +++ b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart @@ -366,6 +366,7 @@ abstract class ResolutionSelectorHostApi { void create( int identifier, int? resolutionStrategyIdentifier, + int? resolutionSelectorIdentifier, int? aspectRatioStrategyIdentifier, ); } @@ -536,3 +537,9 @@ abstract class Camera2CameraControlHostApi { void addCaptureRequestOptions( int identifier, int captureRequestOptionsIdentifier); } + +@HostApi(dartHostTestHandler: 'TestResolutionFilterHostApi') +abstract class ResolutionFilterHostApi { + void createWithOnePreferredSize( + int identifier, ResolutionInfo preferredResolution); +} diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index 248da8bbd97d..0f4756be1bb7 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.6.0+1 +version: 0.6.1 environment: sdk: ^3.1.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 d9ff081383e9..f08a2e02ad49 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 @@ -8,6 +8,7 @@ import 'dart:math' show Point; import 'package:async/async.dart'; import 'package:camera_android_camerax/camera_android_camerax.dart'; import 'package:camera_android_camerax/src/analyzer.dart'; +import 'package:camera_android_camerax/src/aspect_ratio_strategy.dart'; import 'package:camera_android_camerax/src/camera.dart'; import 'package:camera_android_camerax/src/camera2_camera_control.dart'; import 'package:camera_android_camerax/src/camera_control.dart'; @@ -36,6 +37,7 @@ import 'package:camera_android_camerax/src/process_camera_provider.dart'; import 'package:camera_android_camerax/src/quality_selector.dart'; import 'package:camera_android_camerax/src/recorder.dart'; import 'package:camera_android_camerax/src/recording.dart'; +import 'package:camera_android_camerax/src/resolution_filter.dart'; import 'package:camera_android_camerax/src/resolution_selector.dart'; import 'package:camera_android_camerax/src/resolution_strategy.dart'; import 'package:camera_android_camerax/src/surface.dart'; @@ -46,7 +48,7 @@ import 'package:camera_android_camerax/src/zoom_state.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart' show DeviceOrientation, PlatformException, Uint8List; -import 'package:flutter/widgets.dart'; +import 'package:flutter/widgets.dart' show BuildContext, Size, Texture, Widget; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -56,6 +58,7 @@ import 'test_camerax_library.g.dart'; @GenerateNiceMocks(>[ MockSpec(), + MockSpec(), MockSpec(), MockSpec(), MockSpec(), @@ -75,6 +78,7 @@ import 'test_camerax_library.g.dart'; MockSpec(), MockSpec(), MockSpec(), + MockSpec(), MockSpec(), MockSpec(), MockSpec(), @@ -122,6 +126,76 @@ void main() { return cameraClosingEventSent && cameraErrorSent; } + /// CameraXProxy for testing functionality related to the camera resolution + /// preset (setting expected ResolutionSelectors, QualitySelectors, etc.). + CameraXProxy getProxyForTestingResolutionPreset( + MockProcessCameraProvider mockProcessCameraProvider) => + CameraXProxy( + getProcessCameraProvider: () => + Future.value(mockProcessCameraProvider), + createCameraSelector: (int cameraSelectorLensDirection) => + MockCameraSelector(), + createPreview: + (ResolutionSelector? resolutionSelector, int? targetRotation) => + Preview.detached( + initialTargetRotation: targetRotation, + resolutionSelector: resolutionSelector), + createImageCapture: + (ResolutionSelector? resolutionSelector, int? targetRotation) => + ImageCapture.detached( + resolutionSelector: resolutionSelector, + initialTargetRotation: targetRotation), + createRecorder: (QualitySelector? qualitySelector) => + Recorder.detached(qualitySelector: qualitySelector), + createVideoCapture: (_) => + Future.value(MockVideoCapture()), + createImageAnalysis: + (ResolutionSelector? resolutionSelector, int? targetRotation) => + ImageAnalysis.detached( + resolutionSelector: resolutionSelector, + initialTargetRotation: targetRotation), + createResolutionStrategy: ( + {bool highestAvailable = false, + Size? boundSize, + int? fallbackRule}) { + if (highestAvailable) { + return ResolutionStrategy.detachedHighestAvailableStrategy(); + } + return ResolutionStrategy.detached( + boundSize: boundSize, fallbackRule: fallbackRule); + }, + createResolutionSelector: (ResolutionStrategy resolutionStrategy, + ResolutionFilter? resolutionFilter, + AspectRatioStrategy? aspectRatioStrategy) => + ResolutionSelector.detached( + resolutionStrategy: resolutionStrategy, + resolutionFilter: resolutionFilter, + aspectRatioStrategy: aspectRatioStrategy), + createFallbackStrategy: ( + {required VideoQuality quality, + required VideoResolutionFallbackRule fallbackRule}) => + FallbackStrategy.detached( + quality: quality, fallbackRule: fallbackRule), + createQualitySelector: ( + {required VideoQuality videoQuality, + required FallbackStrategy fallbackStrategy}) => + QualitySelector.detached(qualityList: [ + VideoQualityData(quality: videoQuality) + ], fallbackStrategy: fallbackStrategy), + createCameraStateObserver: (_) => MockObserver(), + requestCameraPermissions: (_) => Future.value(), + startListeningForDeviceOrientationChange: (_, __) {}, + setPreviewSurfaceProvider: (_) => Future.value( + 3), // 3 is a random Flutter SurfaceTexture ID for testing, + createAspectRatioStrategy: (int aspectRatio, int fallbackRule) => + AspectRatioStrategy.detached( + preferredAspectRatio: aspectRatio, fallbackRule: fallbackRule), + createResolutionFilterWithOnePreferredSize: + (Size preferredResolution) => + ResolutionFilter.onePreferredSizeDetached( + preferredResolution: preferredResolution), + ); + /// CameraXProxy for testing exposure and focus related controls. /// /// Modifies the creation of [MeteringPoint]s and [FocusMeteringAction]s to @@ -289,7 +363,7 @@ void main() { Size? boundSize, int? fallbackRule}) => MockResolutionStrategy(), - createResolutionSelector: (_) => MockResolutionSelector(), + createResolutionSelector: (_, __, ___) => MockResolutionSelector(), createFallbackStrategy: ( {required VideoQuality quality, required VideoResolutionFallbackRule fallbackRule}) => @@ -307,6 +381,8 @@ void main() { startListeningForDeviceOrientationChange: (_, __) { startedListeningForDeviceOrientationChanges = true; }, + createAspectRatioStrategy: (_, __) => MockAspectRatioStrategy(), + createResolutionFilterWithOnePreferredSize: (_) => MockResolutionFilter(), ); when(mockPreview.setSurfaceProvider()) @@ -405,7 +481,7 @@ void main() { Size? boundSize, int? fallbackRule}) => MockResolutionStrategy(), - createResolutionSelector: (_) => MockResolutionSelector(), + createResolutionSelector: (_, __, ___) => MockResolutionSelector(), createFallbackStrategy: ( {required VideoQuality quality, required VideoResolutionFallbackRule fallbackRule}) => @@ -418,6 +494,8 @@ void main() { Observer.detached(onChanged: onChanged), requestCameraPermissions: (_) => Future.value(), startListeningForDeviceOrientationChange: (_, __) {}, + createAspectRatioStrategy: (_, __) => MockAspectRatioStrategy(), + createResolutionFilterWithOnePreferredSize: (_) => MockResolutionFilter(), ); when(mockProcessCameraProvider.bindToLifecycle(mockBackCameraSelector, @@ -449,7 +527,7 @@ void main() { }); test( - 'createCamera properly sets preset resolution for non-video capture use cases', + 'createCamera properly sets preset resolution selection strategy for non-video capture use cases', () async { final AndroidCameraCameraX camera = AndroidCameraCameraX(); const CameraLensDirection testLensDirection = CameraLensDirection.back; @@ -466,69 +544,13 @@ void main() { final MockProcessCameraProvider mockProcessCameraProvider = MockProcessCameraProvider(); final MockCameraInfo mockCameraInfo = MockCameraInfo(); - final MockCameraSelector mockBackCameraSelector = MockCameraSelector(); - final MockCameraSelector mockFrontCameraSelector = MockCameraSelector(); - final MockVideoCapture mockVideoCapture = MockVideoCapture(); - final MockRecorder mockRecorder = MockRecorder(); // Tell plugin to create mock/detached objects for testing createCamera // as needed. - camera.proxy = CameraXProxy( - getProcessCameraProvider: () => - Future.value(mockProcessCameraProvider), - createCameraSelector: (int cameraSelectorLensDirection) { - switch (cameraSelectorLensDirection) { - case CameraSelector.lensFacingFront: - return mockFrontCameraSelector; - case CameraSelector.lensFacingBack: - default: - return mockBackCameraSelector; - } - }, - createPreview: - (ResolutionSelector? resolutionSelector, int? targetRotation) => - Preview.detached( - initialTargetRotation: targetRotation, - resolutionSelector: resolutionSelector), - createImageCapture: - (ResolutionSelector? resolutionSelector, int? targetRotation) => - ImageCapture.detached( - resolutionSelector: resolutionSelector, - initialTargetRotation: targetRotation), - createRecorder: (_) => mockRecorder, - createVideoCapture: (_) => Future.value(mockVideoCapture), - createImageAnalysis: - (ResolutionSelector? resolutionSelector, int? targetRotation) => - ImageAnalysis.detached( - resolutionSelector: resolutionSelector, - initialTargetRotation: targetRotation), - createResolutionStrategy: ( - {bool highestAvailable = false, Size? boundSize, int? fallbackRule}) { - if (highestAvailable) { - return ResolutionStrategy.detachedHighestAvailableStrategy(); - } - - return ResolutionStrategy.detached( - boundSize: boundSize, fallbackRule: fallbackRule); - }, - createResolutionSelector: (ResolutionStrategy resolutionStrategy) => - ResolutionSelector.detached(resolutionStrategy: resolutionStrategy), - createFallbackStrategy: ( - {required VideoQuality quality, - required VideoResolutionFallbackRule fallbackRule}) => - MockFallbackStrategy(), - createQualitySelector: ( - {required VideoQuality videoQuality, - required FallbackStrategy fallbackStrategy}) => - MockQualitySelector(), - createCameraStateObserver: (_) => MockObserver(), - requestCameraPermissions: (_) => Future.value(), - startListeningForDeviceOrientationChange: (_, __) {}, - setPreviewSurfaceProvider: (_) => Future.value( - 3), // 3 is a random Flutter SurfaceTexture ID for testing}, - ); + camera.proxy = + getProxyForTestingResolutionPreset(mockProcessCameraProvider); - when(mockProcessCameraProvider.bindToLifecycle(mockBackCameraSelector, any)) + when(mockProcessCameraProvider.bindToLifecycle(any, any)) .thenAnswer((_) async => mockCamera); when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); when(mockCameraInfo.getCameraState()) @@ -595,6 +617,189 @@ void main() { expect(camera.imageAnalysis!.resolutionSelector, isNull); }); + test( + 'createCamera properly sets filter for resolution preset for non-video capture use cases', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const CameraLensDirection testLensDirection = CameraLensDirection.front; + const int testSensorOrientation = 180; + const CameraDescription testCameraDescription = CameraDescription( + name: 'cameraName', + lensDirection: testLensDirection, + sensorOrientation: testSensorOrientation); + const bool enableAudio = true; + final MockCamera mockCamera = MockCamera(); + + // Mock/Detached objects for (typically attached) objects created by + // createCamera. + final MockProcessCameraProvider mockProcessCameraProvider = + MockProcessCameraProvider(); + final MockCameraInfo mockCameraInfo = MockCameraInfo(); + + // Tell plugin to create mock/detached objects for testing createCamera + // as needed. + camera.proxy = + getProxyForTestingResolutionPreset(mockProcessCameraProvider); + + when(mockProcessCameraProvider.bindToLifecycle(any, any)) + .thenAnswer((_) async => mockCamera); + when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); + when(mockCameraInfo.getCameraState()) + .thenAnswer((_) async => MockLiveCameraState()); + camera.processCameraProvider = mockProcessCameraProvider; + + // Test non-null resolution presets. + for (final ResolutionPreset resolutionPreset in ResolutionPreset.values) { + await camera.createCamera(testCameraDescription, resolutionPreset, + enableAudio: enableAudio); + + Size? expectedPreferredResolution; + switch (resolutionPreset) { + case ResolutionPreset.low: + expectedPreferredResolution = const Size(320, 240); + case ResolutionPreset.medium: + expectedPreferredResolution = const Size(720, 480); + case ResolutionPreset.high: + expectedPreferredResolution = const Size(1280, 720); + case ResolutionPreset.veryHigh: + expectedPreferredResolution = const Size(1920, 1080); + case ResolutionPreset.ultraHigh: + expectedPreferredResolution = const Size(3840, 2160); + case ResolutionPreset.max: + expectedPreferredResolution = null; + } + + if (expectedPreferredResolution == null) { + expect(camera.preview!.resolutionSelector!.resolutionFilter, isNull); + expect( + camera.imageCapture!.resolutionSelector!.resolutionFilter, isNull); + expect( + camera.imageAnalysis!.resolutionSelector!.resolutionFilter, isNull); + continue; + } + + expect( + camera.preview!.resolutionSelector!.resolutionFilter! + .preferredResolution, + equals(expectedPreferredResolution)); + expect( + camera + .imageCapture!.resolutionSelector!.resolutionStrategy!.boundSize, + equals(expectedPreferredResolution)); + expect( + camera + .imageAnalysis!.resolutionSelector!.resolutionStrategy!.boundSize, + equals(expectedPreferredResolution)); + } + + // Test null case. + await camera.createCamera(testCameraDescription, null); + expect(camera.preview!.resolutionSelector, isNull); + expect(camera.imageCapture!.resolutionSelector, isNull); + expect(camera.imageAnalysis!.resolutionSelector, isNull); + }); + + test( + 'createCamera properly sets aspect ratio based on preset resolution for non-video capture use cases', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const CameraLensDirection testLensDirection = CameraLensDirection.back; + const int testSensorOrientation = 90; + const CameraDescription testCameraDescription = CameraDescription( + name: 'cameraName', + lensDirection: testLensDirection, + sensorOrientation: testSensorOrientation); + const bool enableAudio = true; + final MockCamera mockCamera = MockCamera(); + + // Mock/Detached objects for (typically attached) objects created by + // createCamera. + final MockProcessCameraProvider mockProcessCameraProvider = + MockProcessCameraProvider(); + final MockCameraInfo mockCameraInfo = MockCameraInfo(); + + // Tell plugin to create mock/detached objects for testing createCamera + // as needed. + camera.proxy = + getProxyForTestingResolutionPreset(mockProcessCameraProvider); + when(mockProcessCameraProvider.bindToLifecycle(any, any)) + .thenAnswer((_) async => mockCamera); + when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); + when(mockCameraInfo.getCameraState()) + .thenAnswer((_) async => MockLiveCameraState()); + camera.processCameraProvider = mockProcessCameraProvider; + + // Test non-null resolution presets. + for (final ResolutionPreset resolutionPreset in ResolutionPreset.values) { + await camera.createCamera(testCameraDescription, resolutionPreset, + enableAudio: enableAudio); + + int? expectedAspectRatio; + AspectRatioStrategy? expectedAspectRatioStrategy; + switch (resolutionPreset) { + case ResolutionPreset.low: + expectedAspectRatio = AspectRatio.ratio4To3; + case ResolutionPreset.high: + case ResolutionPreset.veryHigh: + case ResolutionPreset.ultraHigh: + expectedAspectRatio = AspectRatio.ratio16To9; + case ResolutionPreset.medium: + // Medium resolution preset uses aspect ratio 3:2 which is unsupported + // by CameraX. + case ResolutionPreset.max: + expectedAspectRatioStrategy = null; + } + + expectedAspectRatioStrategy = expectedAspectRatio == null + ? null + : AspectRatioStrategy.detached( + preferredAspectRatio: expectedAspectRatio, + fallbackRule: AspectRatioStrategy.fallbackRuleAuto); + + if (expectedAspectRatio == null) { + expect(camera.preview!.resolutionSelector!.aspectRatioStrategy, isNull); + expect(camera.imageCapture!.resolutionSelector!.aspectRatioStrategy, + isNull); + expect(camera.imageAnalysis!.resolutionSelector!.aspectRatioStrategy, + isNull); + continue; + } + + // Check aspect ratio. + expect( + camera.preview!.resolutionSelector!.aspectRatioStrategy! + .preferredAspectRatio, + equals(expectedAspectRatioStrategy!.preferredAspectRatio)); + expect( + camera.imageCapture!.resolutionSelector!.aspectRatioStrategy! + .preferredAspectRatio, + equals(expectedAspectRatioStrategy.preferredAspectRatio)); + expect( + camera.imageAnalysis!.resolutionSelector!.aspectRatioStrategy! + .preferredAspectRatio, + equals(expectedAspectRatioStrategy.preferredAspectRatio)); + + // Check fallback rule. + expect( + camera.preview!.resolutionSelector!.aspectRatioStrategy!.fallbackRule, + equals(expectedAspectRatioStrategy.fallbackRule)); + expect( + camera.imageCapture!.resolutionSelector!.aspectRatioStrategy! + .fallbackRule, + equals(expectedAspectRatioStrategy.fallbackRule)); + expect( + camera.imageAnalysis!.resolutionSelector!.aspectRatioStrategy! + .fallbackRule, + equals(expectedAspectRatioStrategy.fallbackRule)); + } + + // Test null case. + await camera.createCamera(testCameraDescription, null); + expect(camera.preview!.resolutionSelector, isNull); + expect(camera.imageCapture!.resolutionSelector, isNull); + expect(camera.imageAnalysis!.resolutionSelector, isNull); + }); + test( 'createCamera properly sets preset resolution for video capture use case', () async { @@ -613,58 +818,13 @@ void main() { final MockProcessCameraProvider mockProcessCameraProvider = MockProcessCameraProvider(); final MockCameraInfo mockCameraInfo = MockCameraInfo(); - final MockCameraSelector mockBackCameraSelector = MockCameraSelector(); - final MockCameraSelector mockFrontCameraSelector = MockCameraSelector(); - final MockPreview mockPreview = MockPreview(); - final MockImageCapture mockImageCapture = MockImageCapture(); - final MockVideoCapture mockVideoCapture = MockVideoCapture(); - final MockImageAnalysis mockImageAnalysis = MockImageAnalysis(); // Tell plugin to create mock/detached objects for testing createCamera // as needed. - camera.proxy = CameraXProxy( - getProcessCameraProvider: () => - Future.value(mockProcessCameraProvider), - createCameraSelector: (int cameraSelectorLensDirection) { - switch (cameraSelectorLensDirection) { - case CameraSelector.lensFacingFront: - return mockFrontCameraSelector; - case CameraSelector.lensFacingBack: - default: - return mockBackCameraSelector; - } - }, - createPreview: (_, __) => mockPreview, - createImageCapture: (_, __) => mockImageCapture, - createRecorder: (QualitySelector? qualitySelector) => - Recorder.detached(qualitySelector: qualitySelector), - createVideoCapture: (_) => Future.value(mockVideoCapture), - createImageAnalysis: (_, __) => mockImageAnalysis, - createResolutionStrategy: ( - {bool highestAvailable = false, - Size? boundSize, - int? fallbackRule}) => - MockResolutionStrategy(), - createResolutionSelector: (_) => MockResolutionSelector(), - createFallbackStrategy: ( - {required VideoQuality quality, - required VideoResolutionFallbackRule fallbackRule}) => - FallbackStrategy.detached( - quality: quality, fallbackRule: fallbackRule), - createQualitySelector: ( - {required VideoQuality videoQuality, - required FallbackStrategy fallbackStrategy}) => - QualitySelector.detached(qualityList: [ - VideoQualityData(quality: videoQuality) - ], fallbackStrategy: fallbackStrategy), - createCameraStateObserver: (void Function(Object) onChanged) => - Observer.detached(onChanged: onChanged), - requestCameraPermissions: (_) => Future.value(), - startListeningForDeviceOrientationChange: (_, __) {}, - ); + camera.proxy = + getProxyForTestingResolutionPreset(mockProcessCameraProvider); - when(mockProcessCameraProvider.bindToLifecycle(mockBackCameraSelector, - [mockPreview, mockImageCapture, mockImageAnalysis])) + when(mockProcessCameraProvider.bindToLifecycle(any, any)) .thenAnswer((_) async => mockCamera); when(mockCamera.getCameraInfo()).thenAnswer((_) async => mockCameraInfo); when(mockCameraInfo.getCameraState()) @@ -773,7 +933,7 @@ void main() { Size? boundSize, int? fallbackRule}) => MockResolutionStrategy(), - createResolutionSelector: (_) => MockResolutionSelector(), + createResolutionSelector: (_, __, ___) => MockResolutionSelector(), createFallbackStrategy: ( {required VideoQuality quality, required VideoResolutionFallbackRule fallbackRule}) => @@ -786,6 +946,8 @@ void main() { Observer.detached(onChanged: onChanged), requestCameraPermissions: (_) => Future.value(), startListeningForDeviceOrientationChange: (_, __) {}, + createAspectRatioStrategy: (_, __) => MockAspectRatioStrategy(), + createResolutionFilterWithOnePreferredSize: (_) => MockResolutionFilter(), ); final CameraInitializedEvent testCameraInitializedEvent = diff --git a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart index 80d76d8339ca..5d6d2051212d 100644 --- a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart +++ b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.mocks.dart @@ -3,50 +3,53 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i16; -import 'dart:typed_data' as _i31; +import 'dart:async' as _i17; +import 'dart:typed_data' as _i33; +import 'dart:ui' as _i11; -import 'package:camera_android_camerax/src/analyzer.dart' as _i15; +import 'package:camera_android_camerax/src/analyzer.dart' as _i16; +import 'package:camera_android_camerax/src/aspect_ratio_strategy.dart' as _i19; import 'package:camera_android_camerax/src/camera.dart' as _i9; -import 'package:camera_android_camerax/src/camera2_camera_control.dart' as _i22; +import 'package:camera_android_camerax/src/camera2_camera_control.dart' as _i24; import 'package:camera_android_camerax/src/camera_control.dart' as _i3; import 'package:camera_android_camerax/src/camera_info.dart' as _i2; -import 'package:camera_android_camerax/src/camera_selector.dart' as _i24; -import 'package:camera_android_camerax/src/camera_state.dart' as _i18; +import 'package:camera_android_camerax/src/camera_selector.dart' as _i26; +import 'package:camera_android_camerax/src/camera_state.dart' as _i20; import 'package:camera_android_camerax/src/camerax_library.g.dart' as _i7; import 'package:camera_android_camerax/src/capture_request_options.dart' - as _i23; + as _i25; import 'package:camera_android_camerax/src/exposure_state.dart' as _i5; -import 'package:camera_android_camerax/src/fallback_strategy.dart' as _i25; -import 'package:camera_android_camerax/src/focus_metering_action.dart' as _i21; -import 'package:camera_android_camerax/src/focus_metering_result.dart' as _i20; -import 'package:camera_android_camerax/src/image_analysis.dart' as _i26; -import 'package:camera_android_camerax/src/image_capture.dart' as _i27; -import 'package:camera_android_camerax/src/image_proxy.dart' as _i17; +import 'package:camera_android_camerax/src/fallback_strategy.dart' as _i27; +import 'package:camera_android_camerax/src/focus_metering_action.dart' as _i23; +import 'package:camera_android_camerax/src/focus_metering_result.dart' as _i22; +import 'package:camera_android_camerax/src/image_analysis.dart' as _i28; +import 'package:camera_android_camerax/src/image_capture.dart' as _i29; +import 'package:camera_android_camerax/src/image_proxy.dart' as _i18; import 'package:camera_android_camerax/src/live_data.dart' as _i4; -import 'package:camera_android_camerax/src/observer.dart' as _i30; +import 'package:camera_android_camerax/src/observer.dart' as _i32; import 'package:camera_android_camerax/src/pending_recording.dart' as _i10; -import 'package:camera_android_camerax/src/plane_proxy.dart' as _i29; -import 'package:camera_android_camerax/src/preview.dart' as _i32; +import 'package:camera_android_camerax/src/plane_proxy.dart' as _i31; +import 'package:camera_android_camerax/src/preview.dart' as _i34; import 'package:camera_android_camerax/src/process_camera_provider.dart' - as _i33; -import 'package:camera_android_camerax/src/quality_selector.dart' as _i35; -import 'package:camera_android_camerax/src/recorder.dart' as _i11; + as _i35; +import 'package:camera_android_camerax/src/quality_selector.dart' as _i37; +import 'package:camera_android_camerax/src/recorder.dart' as _i12; import 'package:camera_android_camerax/src/recording.dart' as _i8; -import 'package:camera_android_camerax/src/resolution_selector.dart' as _i36; -import 'package:camera_android_camerax/src/resolution_strategy.dart' as _i37; -import 'package:camera_android_camerax/src/use_case.dart' as _i34; -import 'package:camera_android_camerax/src/video_capture.dart' as _i38; -import 'package:camera_android_camerax/src/zoom_state.dart' as _i19; +import 'package:camera_android_camerax/src/resolution_filter.dart' as _i38; +import 'package:camera_android_camerax/src/resolution_selector.dart' as _i39; +import 'package:camera_android_camerax/src/resolution_strategy.dart' as _i40; +import 'package:camera_android_camerax/src/use_case.dart' as _i36; +import 'package:camera_android_camerax/src/video_capture.dart' as _i41; +import 'package:camera_android_camerax/src/zoom_state.dart' as _i21; import 'package:camera_platform_interface/camera_platform_interface.dart' as _i6; -import 'package:flutter/foundation.dart' as _i14; -import 'package:flutter/services.dart' as _i13; -import 'package:flutter/widgets.dart' as _i12; +import 'package:flutter/foundation.dart' as _i15; +import 'package:flutter/services.dart' as _i14; +import 'package:flutter/widgets.dart' as _i13; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i28; +import 'package:mockito/src/dummies.dart' as _i30; -import 'test_camerax_library.g.dart' as _i39; +import 'test_camerax_library.g.dart' as _i42; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -166,8 +169,8 @@ class _FakePendingRecording_9 extends _i1.SmartFake ); } -class _FakeRecorder_10 extends _i1.SmartFake implements _i11.Recorder { - _FakeRecorder_10( +class _FakeSize_10 extends _i1.SmartFake implements _i11.Size { + _FakeSize_10( Object parent, Invocation parentInvocation, ) : super( @@ -176,8 +179,18 @@ class _FakeRecorder_10 extends _i1.SmartFake implements _i11.Recorder { ); } -class _FakeWidget_11 extends _i1.SmartFake implements _i12.Widget { - _FakeWidget_11( +class _FakeRecorder_11 extends _i1.SmartFake implements _i12.Recorder { + _FakeRecorder_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeWidget_12 extends _i1.SmartFake implements _i13.Widget { + _FakeWidget_12( Object parent, Invocation parentInvocation, ) : super( @@ -187,13 +200,13 @@ class _FakeWidget_11 extends _i1.SmartFake implements _i12.Widget { @override String toString( - {_i13.DiagnosticLevel? minLevel = _i13.DiagnosticLevel.info}) => + {_i14.DiagnosticLevel? minLevel = _i14.DiagnosticLevel.info}) => super.toString(); } -class _FakeInheritedWidget_12 extends _i1.SmartFake - implements _i12.InheritedWidget { - _FakeInheritedWidget_12( +class _FakeInheritedWidget_13 extends _i1.SmartFake + implements _i13.InheritedWidget { + _FakeInheritedWidget_13( Object parent, Invocation parentInvocation, ) : super( @@ -203,13 +216,13 @@ class _FakeInheritedWidget_12 extends _i1.SmartFake @override String toString( - {_i13.DiagnosticLevel? minLevel = _i13.DiagnosticLevel.info}) => + {_i14.DiagnosticLevel? minLevel = _i14.DiagnosticLevel.info}) => super.toString(); } -class _FakeDiagnosticsNode_13 extends _i1.SmartFake - implements _i14.DiagnosticsNode { - _FakeDiagnosticsNode_13( +class _FakeDiagnosticsNode_14 extends _i1.SmartFake + implements _i15.DiagnosticsNode { + _FakeDiagnosticsNode_14( Object parent, Invocation parentInvocation, ) : super( @@ -219,8 +232,8 @@ class _FakeDiagnosticsNode_13 extends _i1.SmartFake @override String toString({ - _i14.TextTreeConfiguration? parentConfiguration, - _i13.DiagnosticLevel? minLevel = _i13.DiagnosticLevel.info, + _i15.TextTreeConfiguration? parentConfiguration, + _i14.DiagnosticLevel? minLevel = _i14.DiagnosticLevel.info, }) => super.toString(); } @@ -229,15 +242,36 @@ class _FakeDiagnosticsNode_13 extends _i1.SmartFake /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockAnalyzer extends _i1.Mock implements _i15.Analyzer { +class MockAnalyzer extends _i1.Mock implements _i16.Analyzer { @override - _i16.Future Function(_i17.ImageProxy) get analyze => + _i17.Future Function(_i18.ImageProxy) get analyze => (super.noSuchMethod( Invocation.getter(#analyze), - returnValue: (_i17.ImageProxy imageProxy) => _i16.Future.value(), - returnValueForMissingStub: (_i17.ImageProxy imageProxy) => - _i16.Future.value(), - ) as _i16.Future Function(_i17.ImageProxy)); + returnValue: (_i18.ImageProxy imageProxy) => _i17.Future.value(), + returnValueForMissingStub: (_i18.ImageProxy imageProxy) => + _i17.Future.value(), + ) as _i17.Future Function(_i18.ImageProxy)); +} + +/// A class which mocks [AspectRatioStrategy]. +/// +/// See the documentation for Mockito's code generation for more information. +// ignore: must_be_immutable +class MockAspectRatioStrategy extends _i1.Mock + implements _i19.AspectRatioStrategy { + @override + int get preferredAspectRatio => (super.noSuchMethod( + Invocation.getter(#preferredAspectRatio), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + int get fallbackRule => (super.noSuchMethod( + Invocation.getter(#fallbackRule), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); } /// A class which mocks [Camera]. @@ -246,12 +280,12 @@ class MockAnalyzer extends _i1.Mock implements _i15.Analyzer { // ignore: must_be_immutable class MockCamera extends _i1.Mock implements _i9.Camera { @override - _i16.Future<_i2.CameraInfo> getCameraInfo() => (super.noSuchMethod( + _i17.Future<_i2.CameraInfo> getCameraInfo() => (super.noSuchMethod( Invocation.method( #getCameraInfo, [], ), - returnValue: _i16.Future<_i2.CameraInfo>.value(_FakeCameraInfo_0( + returnValue: _i17.Future<_i2.CameraInfo>.value(_FakeCameraInfo_0( this, Invocation.method( #getCameraInfo, @@ -259,22 +293,22 @@ class MockCamera extends _i1.Mock implements _i9.Camera { ), )), returnValueForMissingStub: - _i16.Future<_i2.CameraInfo>.value(_FakeCameraInfo_0( + _i17.Future<_i2.CameraInfo>.value(_FakeCameraInfo_0( this, Invocation.method( #getCameraInfo, [], ), )), - ) as _i16.Future<_i2.CameraInfo>); + ) as _i17.Future<_i2.CameraInfo>); @override - _i16.Future<_i3.CameraControl> getCameraControl() => (super.noSuchMethod( + _i17.Future<_i3.CameraControl> getCameraControl() => (super.noSuchMethod( Invocation.method( #getCameraControl, [], ), - returnValue: _i16.Future<_i3.CameraControl>.value(_FakeCameraControl_1( + returnValue: _i17.Future<_i3.CameraControl>.value(_FakeCameraControl_1( this, Invocation.method( #getCameraControl, @@ -282,14 +316,14 @@ class MockCamera extends _i1.Mock implements _i9.Camera { ), )), returnValueForMissingStub: - _i16.Future<_i3.CameraControl>.value(_FakeCameraControl_1( + _i17.Future<_i3.CameraControl>.value(_FakeCameraControl_1( this, Invocation.method( #getCameraControl, [], ), )), - ) as _i16.Future<_i3.CameraControl>); + ) as _i17.Future<_i3.CameraControl>); } /// A class which mocks [CameraInfo]. @@ -298,24 +332,24 @@ class MockCamera extends _i1.Mock implements _i9.Camera { // ignore: must_be_immutable class MockCameraInfo extends _i1.Mock implements _i2.CameraInfo { @override - _i16.Future getSensorRotationDegrees() => (super.noSuchMethod( + _i17.Future getSensorRotationDegrees() => (super.noSuchMethod( Invocation.method( #getSensorRotationDegrees, [], ), - returnValue: _i16.Future.value(0), - returnValueForMissingStub: _i16.Future.value(0), - ) as _i16.Future); + returnValue: _i17.Future.value(0), + returnValueForMissingStub: _i17.Future.value(0), + ) as _i17.Future); @override - _i16.Future<_i4.LiveData<_i18.CameraState>> getCameraState() => + _i17.Future<_i4.LiveData<_i20.CameraState>> getCameraState() => (super.noSuchMethod( Invocation.method( #getCameraState, [], ), - returnValue: _i16.Future<_i4.LiveData<_i18.CameraState>>.value( - _FakeLiveData_2<_i18.CameraState>( + returnValue: _i17.Future<_i4.LiveData<_i20.CameraState>>.value( + _FakeLiveData_2<_i20.CameraState>( this, Invocation.method( #getCameraState, @@ -323,23 +357,23 @@ class MockCameraInfo extends _i1.Mock implements _i2.CameraInfo { ), )), returnValueForMissingStub: - _i16.Future<_i4.LiveData<_i18.CameraState>>.value( - _FakeLiveData_2<_i18.CameraState>( + _i17.Future<_i4.LiveData<_i20.CameraState>>.value( + _FakeLiveData_2<_i20.CameraState>( this, Invocation.method( #getCameraState, [], ), )), - ) as _i16.Future<_i4.LiveData<_i18.CameraState>>); + ) as _i17.Future<_i4.LiveData<_i20.CameraState>>); @override - _i16.Future<_i5.ExposureState> getExposureState() => (super.noSuchMethod( + _i17.Future<_i5.ExposureState> getExposureState() => (super.noSuchMethod( Invocation.method( #getExposureState, [], ), - returnValue: _i16.Future<_i5.ExposureState>.value(_FakeExposureState_3( + returnValue: _i17.Future<_i5.ExposureState>.value(_FakeExposureState_3( this, Invocation.method( #getExposureState, @@ -347,24 +381,24 @@ class MockCameraInfo extends _i1.Mock implements _i2.CameraInfo { ), )), returnValueForMissingStub: - _i16.Future<_i5.ExposureState>.value(_FakeExposureState_3( + _i17.Future<_i5.ExposureState>.value(_FakeExposureState_3( this, Invocation.method( #getExposureState, [], ), )), - ) as _i16.Future<_i5.ExposureState>); + ) as _i17.Future<_i5.ExposureState>); @override - _i16.Future<_i4.LiveData<_i19.ZoomState>> getZoomState() => + _i17.Future<_i4.LiveData<_i21.ZoomState>> getZoomState() => (super.noSuchMethod( Invocation.method( #getZoomState, [], ), - returnValue: _i16.Future<_i4.LiveData<_i19.ZoomState>>.value( - _FakeLiveData_2<_i19.ZoomState>( + returnValue: _i17.Future<_i4.LiveData<_i21.ZoomState>>.value( + _FakeLiveData_2<_i21.ZoomState>( this, Invocation.method( #getZoomState, @@ -372,15 +406,15 @@ class MockCameraInfo extends _i1.Mock implements _i2.CameraInfo { ), )), returnValueForMissingStub: - _i16.Future<_i4.LiveData<_i19.ZoomState>>.value( - _FakeLiveData_2<_i19.ZoomState>( + _i17.Future<_i4.LiveData<_i21.ZoomState>>.value( + _FakeLiveData_2<_i21.ZoomState>( this, Invocation.method( #getZoomState, [], ), )), - ) as _i16.Future<_i4.LiveData<_i19.ZoomState>>); + ) as _i17.Future<_i4.LiveData<_i21.ZoomState>>); } /// A class which mocks [CameraControl]. @@ -389,58 +423,58 @@ class MockCameraInfo extends _i1.Mock implements _i2.CameraInfo { // ignore: must_be_immutable class MockCameraControl extends _i1.Mock implements _i3.CameraControl { @override - _i16.Future enableTorch(bool? torch) => (super.noSuchMethod( + _i17.Future enableTorch(bool? torch) => (super.noSuchMethod( Invocation.method( #enableTorch, [torch], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future setZoomRatio(double? ratio) => (super.noSuchMethod( + _i17.Future setZoomRatio(double? ratio) => (super.noSuchMethod( Invocation.method( #setZoomRatio, [ratio], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future<_i20.FocusMeteringResult?> startFocusAndMetering( - _i21.FocusMeteringAction? action) => + _i17.Future<_i22.FocusMeteringResult?> startFocusAndMetering( + _i23.FocusMeteringAction? action) => (super.noSuchMethod( Invocation.method( #startFocusAndMetering, [action], ), - returnValue: _i16.Future<_i20.FocusMeteringResult?>.value(), + returnValue: _i17.Future<_i22.FocusMeteringResult?>.value(), returnValueForMissingStub: - _i16.Future<_i20.FocusMeteringResult?>.value(), - ) as _i16.Future<_i20.FocusMeteringResult?>); + _i17.Future<_i22.FocusMeteringResult?>.value(), + ) as _i17.Future<_i22.FocusMeteringResult?>); @override - _i16.Future cancelFocusAndMetering() => (super.noSuchMethod( + _i17.Future cancelFocusAndMetering() => (super.noSuchMethod( Invocation.method( #cancelFocusAndMetering, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future setExposureCompensationIndex(int? index) => + _i17.Future setExposureCompensationIndex(int? index) => (super.noSuchMethod( Invocation.method( #setExposureCompensationIndex, [index], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } /// A class which mocks [Camera2CameraControl]. @@ -448,7 +482,7 @@ class MockCameraControl extends _i1.Mock implements _i3.CameraControl { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockCamera2CameraControl extends _i1.Mock - implements _i22.Camera2CameraControl { + implements _i24.Camera2CameraControl { @override _i3.CameraControl get cameraControl => (super.noSuchMethod( Invocation.getter(#cameraControl), @@ -463,16 +497,16 @@ class MockCamera2CameraControl extends _i1.Mock ) as _i3.CameraControl); @override - _i16.Future addCaptureRequestOptions( - _i23.CaptureRequestOptions? captureRequestOptions) => + _i17.Future addCaptureRequestOptions( + _i25.CaptureRequestOptions? captureRequestOptions) => (super.noSuchMethod( Invocation.method( #addCaptureRequestOptions, [captureRequestOptions], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } /// A class which mocks [CameraImageData]. @@ -519,19 +553,19 @@ class MockCameraImageData extends _i1.Mock implements _i6.CameraImageData { /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockCameraSelector extends _i1.Mock implements _i24.CameraSelector { +class MockCameraSelector extends _i1.Mock implements _i26.CameraSelector { @override - _i16.Future> filter(List<_i2.CameraInfo>? cameraInfos) => + _i17.Future> filter(List<_i2.CameraInfo>? cameraInfos) => (super.noSuchMethod( Invocation.method( #filter, [cameraInfos], ), returnValue: - _i16.Future>.value(<_i2.CameraInfo>[]), + _i17.Future>.value(<_i2.CameraInfo>[]), returnValueForMissingStub: - _i16.Future>.value(<_i2.CameraInfo>[]), - ) as _i16.Future>); + _i17.Future>.value(<_i2.CameraInfo>[]), + ) as _i17.Future>); } /// A class which mocks [ExposureState]. @@ -565,7 +599,7 @@ class MockExposureState extends _i1.Mock implements _i5.ExposureState { /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockFallbackStrategy extends _i1.Mock implements _i25.FallbackStrategy { +class MockFallbackStrategy extends _i1.Mock implements _i27.FallbackStrategy { @override _i7.VideoQuality get quality => (super.noSuchMethod( Invocation.getter(#quality), @@ -587,86 +621,86 @@ class MockFallbackStrategy extends _i1.Mock implements _i25.FallbackStrategy { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockFocusMeteringResult extends _i1.Mock - implements _i20.FocusMeteringResult { + implements _i22.FocusMeteringResult { @override - _i16.Future isFocusSuccessful() => (super.noSuchMethod( + _i17.Future isFocusSuccessful() => (super.noSuchMethod( Invocation.method( #isFocusSuccessful, [], ), - returnValue: _i16.Future.value(false), - returnValueForMissingStub: _i16.Future.value(false), - ) as _i16.Future); + returnValue: _i17.Future.value(false), + returnValueForMissingStub: _i17.Future.value(false), + ) as _i17.Future); } /// A class which mocks [ImageAnalysis]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockImageAnalysis extends _i1.Mock implements _i26.ImageAnalysis { +class MockImageAnalysis extends _i1.Mock implements _i28.ImageAnalysis { @override - _i16.Future setTargetRotation(int? rotation) => (super.noSuchMethod( + _i17.Future setTargetRotation(int? rotation) => (super.noSuchMethod( Invocation.method( #setTargetRotation, [rotation], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future setAnalyzer(_i15.Analyzer? analyzer) => (super.noSuchMethod( + _i17.Future setAnalyzer(_i16.Analyzer? analyzer) => (super.noSuchMethod( Invocation.method( #setAnalyzer, [analyzer], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future clearAnalyzer() => (super.noSuchMethod( + _i17.Future clearAnalyzer() => (super.noSuchMethod( Invocation.method( #clearAnalyzer, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } /// A class which mocks [ImageCapture]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockImageCapture extends _i1.Mock implements _i27.ImageCapture { +class MockImageCapture extends _i1.Mock implements _i29.ImageCapture { @override - _i16.Future setTargetRotation(int? rotation) => (super.noSuchMethod( + _i17.Future setTargetRotation(int? rotation) => (super.noSuchMethod( Invocation.method( #setTargetRotation, [rotation], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future setFlashMode(int? newFlashMode) => (super.noSuchMethod( + _i17.Future setFlashMode(int? newFlashMode) => (super.noSuchMethod( Invocation.method( #setFlashMode, [newFlashMode], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future takePicture() => (super.noSuchMethod( + _i17.Future takePicture() => (super.noSuchMethod( Invocation.method( #takePicture, [], ), - returnValue: _i16.Future.value(_i28.dummyValue( + returnValue: _i17.Future.value(_i30.dummyValue( this, Invocation.method( #takePicture, @@ -674,21 +708,21 @@ class MockImageCapture extends _i1.Mock implements _i27.ImageCapture { ), )), returnValueForMissingStub: - _i16.Future.value(_i28.dummyValue( + _i17.Future.value(_i30.dummyValue( this, Invocation.method( #takePicture, [], ), )), - ) as _i16.Future); + ) as _i17.Future); } /// A class which mocks [ImageProxy]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockImageProxy extends _i1.Mock implements _i17.ImageProxy { +class MockImageProxy extends _i1.Mock implements _i18.ImageProxy { @override int get format => (super.noSuchMethod( Invocation.getter(#format), @@ -711,33 +745,33 @@ class MockImageProxy extends _i1.Mock implements _i17.ImageProxy { ) as int); @override - _i16.Future> getPlanes() => (super.noSuchMethod( + _i17.Future> getPlanes() => (super.noSuchMethod( Invocation.method( #getPlanes, [], ), returnValue: - _i16.Future>.value(<_i29.PlaneProxy>[]), + _i17.Future>.value(<_i31.PlaneProxy>[]), returnValueForMissingStub: - _i16.Future>.value(<_i29.PlaneProxy>[]), - ) as _i16.Future>); + _i17.Future>.value(<_i31.PlaneProxy>[]), + ) as _i17.Future>); @override - _i16.Future close() => (super.noSuchMethod( + _i17.Future close() => (super.noSuchMethod( Invocation.method( #close, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } /// A class which mocks [Observer]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockObserver extends _i1.Mock implements _i30.Observer<_i18.CameraState> { +class MockObserver extends _i1.Mock implements _i32.Observer<_i20.CameraState> { @override void Function(Object) get onChanged => (super.noSuchMethod( Invocation.getter(#onChanged), @@ -761,12 +795,12 @@ class MockObserver extends _i1.Mock implements _i30.Observer<_i18.CameraState> { // ignore: must_be_immutable class MockPendingRecording extends _i1.Mock implements _i10.PendingRecording { @override - _i16.Future<_i8.Recording> start() => (super.noSuchMethod( + _i17.Future<_i8.Recording> start() => (super.noSuchMethod( Invocation.method( #start, [], ), - returnValue: _i16.Future<_i8.Recording>.value(_FakeRecording_6( + returnValue: _i17.Future<_i8.Recording>.value(_FakeRecording_6( this, Invocation.method( #start, @@ -774,27 +808,27 @@ class MockPendingRecording extends _i1.Mock implements _i10.PendingRecording { ), )), returnValueForMissingStub: - _i16.Future<_i8.Recording>.value(_FakeRecording_6( + _i17.Future<_i8.Recording>.value(_FakeRecording_6( this, Invocation.method( #start, [], ), )), - ) as _i16.Future<_i8.Recording>); + ) as _i17.Future<_i8.Recording>); } /// A class which mocks [PlaneProxy]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockPlaneProxy extends _i1.Mock implements _i29.PlaneProxy { +class MockPlaneProxy extends _i1.Mock implements _i31.PlaneProxy { @override - _i31.Uint8List get buffer => (super.noSuchMethod( + _i33.Uint8List get buffer => (super.noSuchMethod( Invocation.getter(#buffer), - returnValue: _i31.Uint8List(0), - returnValueForMissingStub: _i31.Uint8List(0), - ) as _i31.Uint8List); + returnValue: _i33.Uint8List(0), + returnValueForMissingStub: _i33.Uint8List(0), + ) as _i33.Uint8List); @override int get pixelStride => (super.noSuchMethod( @@ -815,26 +849,26 @@ class MockPlaneProxy extends _i1.Mock implements _i29.PlaneProxy { /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockPreview extends _i1.Mock implements _i32.Preview { +class MockPreview extends _i1.Mock implements _i34.Preview { @override - _i16.Future setTargetRotation(int? rotation) => (super.noSuchMethod( + _i17.Future setTargetRotation(int? rotation) => (super.noSuchMethod( Invocation.method( #setTargetRotation, [rotation], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future setSurfaceProvider() => (super.noSuchMethod( + _i17.Future setSurfaceProvider() => (super.noSuchMethod( Invocation.method( #setSurfaceProvider, [], ), - returnValue: _i16.Future.value(0), - returnValueForMissingStub: _i16.Future.value(0), - ) as _i16.Future); + returnValue: _i17.Future.value(0), + returnValueForMissingStub: _i17.Future.value(0), + ) as _i17.Future); @override void releaseFlutterSurfaceTexture() => super.noSuchMethod( @@ -846,13 +880,13 @@ class MockPreview extends _i1.Mock implements _i32.Preview { ); @override - _i16.Future<_i7.ResolutionInfo> getResolutionInfo() => (super.noSuchMethod( + _i17.Future<_i7.ResolutionInfo> getResolutionInfo() => (super.noSuchMethod( Invocation.method( #getResolutionInfo, [], ), returnValue: - _i16.Future<_i7.ResolutionInfo>.value(_FakeResolutionInfo_7( + _i17.Future<_i7.ResolutionInfo>.value(_FakeResolutionInfo_7( this, Invocation.method( #getResolutionInfo, @@ -860,14 +894,14 @@ class MockPreview extends _i1.Mock implements _i32.Preview { ), )), returnValueForMissingStub: - _i16.Future<_i7.ResolutionInfo>.value(_FakeResolutionInfo_7( + _i17.Future<_i7.ResolutionInfo>.value(_FakeResolutionInfo_7( this, Invocation.method( #getResolutionInfo, [], ), )), - ) as _i16.Future<_i7.ResolutionInfo>); + ) as _i17.Future<_i7.ResolutionInfo>); } /// A class which mocks [ProcessCameraProvider]. @@ -875,24 +909,24 @@ class MockPreview extends _i1.Mock implements _i32.Preview { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockProcessCameraProvider extends _i1.Mock - implements _i33.ProcessCameraProvider { + implements _i35.ProcessCameraProvider { @override - _i16.Future> getAvailableCameraInfos() => + _i17.Future> getAvailableCameraInfos() => (super.noSuchMethod( Invocation.method( #getAvailableCameraInfos, [], ), returnValue: - _i16.Future>.value(<_i2.CameraInfo>[]), + _i17.Future>.value(<_i2.CameraInfo>[]), returnValueForMissingStub: - _i16.Future>.value(<_i2.CameraInfo>[]), - ) as _i16.Future>); + _i17.Future>.value(<_i2.CameraInfo>[]), + ) as _i17.Future>); @override - _i16.Future<_i9.Camera> bindToLifecycle( - _i24.CameraSelector? cameraSelector, - List<_i34.UseCase>? useCases, + _i17.Future<_i9.Camera> bindToLifecycle( + _i26.CameraSelector? cameraSelector, + List<_i36.UseCase>? useCases, ) => (super.noSuchMethod( Invocation.method( @@ -902,7 +936,7 @@ class MockProcessCameraProvider extends _i1.Mock useCases, ], ), - returnValue: _i16.Future<_i9.Camera>.value(_FakeCamera_8( + returnValue: _i17.Future<_i9.Camera>.value(_FakeCamera_8( this, Invocation.method( #bindToLifecycle, @@ -912,7 +946,7 @@ class MockProcessCameraProvider extends _i1.Mock ], ), )), - returnValueForMissingStub: _i16.Future<_i9.Camera>.value(_FakeCamera_8( + returnValueForMissingStub: _i17.Future<_i9.Camera>.value(_FakeCamera_8( this, Invocation.method( #bindToLifecycle, @@ -922,20 +956,20 @@ class MockProcessCameraProvider extends _i1.Mock ], ), )), - ) as _i16.Future<_i9.Camera>); + ) as _i17.Future<_i9.Camera>); @override - _i16.Future isBound(_i34.UseCase? useCase) => (super.noSuchMethod( + _i17.Future isBound(_i36.UseCase? useCase) => (super.noSuchMethod( Invocation.method( #isBound, [useCase], ), - returnValue: _i16.Future.value(false), - returnValueForMissingStub: _i16.Future.value(false), - ) as _i16.Future); + returnValue: _i17.Future.value(false), + returnValueForMissingStub: _i17.Future.value(false), + ) as _i17.Future); @override - void unbind(List<_i34.UseCase>? useCases) => super.noSuchMethod( + void unbind(List<_i36.UseCase>? useCases) => super.noSuchMethod( Invocation.method( #unbind, [useCases], @@ -957,7 +991,7 @@ class MockProcessCameraProvider extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockQualitySelector extends _i1.Mock implements _i35.QualitySelector { +class MockQualitySelector extends _i1.Mock implements _i37.QualitySelector { @override List<_i7.VideoQualityData> get qualityList => (super.noSuchMethod( Invocation.getter(#qualityList), @@ -970,16 +1004,16 @@ class MockQualitySelector extends _i1.Mock implements _i35.QualitySelector { /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockRecorder extends _i1.Mock implements _i11.Recorder { +class MockRecorder extends _i1.Mock implements _i12.Recorder { @override - _i16.Future<_i10.PendingRecording> prepareRecording(String? path) => + _i17.Future<_i10.PendingRecording> prepareRecording(String? path) => (super.noSuchMethod( Invocation.method( #prepareRecording, [path], ), returnValue: - _i16.Future<_i10.PendingRecording>.value(_FakePendingRecording_9( + _i17.Future<_i10.PendingRecording>.value(_FakePendingRecording_9( this, Invocation.method( #prepareRecording, @@ -987,14 +1021,33 @@ class MockRecorder extends _i1.Mock implements _i11.Recorder { ), )), returnValueForMissingStub: - _i16.Future<_i10.PendingRecording>.value(_FakePendingRecording_9( + _i17.Future<_i10.PendingRecording>.value(_FakePendingRecording_9( this, Invocation.method( #prepareRecording, [path], ), )), - ) as _i16.Future<_i10.PendingRecording>); + ) as _i17.Future<_i10.PendingRecording>); +} + +/// A class which mocks [ResolutionFilter]. +/// +/// See the documentation for Mockito's code generation for more information. +// ignore: must_be_immutable +class MockResolutionFilter extends _i1.Mock implements _i38.ResolutionFilter { + @override + _i11.Size get preferredResolution => (super.noSuchMethod( + Invocation.getter(#preferredResolution), + returnValue: _FakeSize_10( + this, + Invocation.getter(#preferredResolution), + ), + returnValueForMissingStub: _FakeSize_10( + this, + Invocation.getter(#preferredResolution), + ), + ) as _i11.Size); } /// A class which mocks [ResolutionSelector]. @@ -1002,14 +1055,14 @@ class MockRecorder extends _i1.Mock implements _i11.Recorder { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockResolutionSelector extends _i1.Mock - implements _i36.ResolutionSelector {} + implements _i39.ResolutionSelector {} /// A class which mocks [ResolutionStrategy]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockResolutionStrategy extends _i1.Mock - implements _i37.ResolutionStrategy {} + implements _i40.ResolutionStrategy {} /// A class which mocks [Recording]. /// @@ -1017,68 +1070,68 @@ class MockResolutionStrategy extends _i1.Mock // ignore: must_be_immutable class MockRecording extends _i1.Mock implements _i8.Recording { @override - _i16.Future close() => (super.noSuchMethod( + _i17.Future close() => (super.noSuchMethod( Invocation.method( #close, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future pause() => (super.noSuchMethod( + _i17.Future pause() => (super.noSuchMethod( Invocation.method( #pause, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future resume() => (super.noSuchMethod( + _i17.Future resume() => (super.noSuchMethod( Invocation.method( #resume, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future stop() => (super.noSuchMethod( + _i17.Future stop() => (super.noSuchMethod( Invocation.method( #stop, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } /// A class which mocks [VideoCapture]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockVideoCapture extends _i1.Mock implements _i38.VideoCapture { +class MockVideoCapture extends _i1.Mock implements _i41.VideoCapture { @override - _i16.Future setTargetRotation(int? rotation) => (super.noSuchMethod( + _i17.Future setTargetRotation(int? rotation) => (super.noSuchMethod( Invocation.method( #setTargetRotation, [rotation], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future<_i11.Recorder> getOutput() => (super.noSuchMethod( + _i17.Future<_i12.Recorder> getOutput() => (super.noSuchMethod( Invocation.method( #getOutput, [], ), - returnValue: _i16.Future<_i11.Recorder>.value(_FakeRecorder_10( + returnValue: _i17.Future<_i12.Recorder>.value(_FakeRecorder_11( this, Invocation.method( #getOutput, @@ -1086,32 +1139,32 @@ class MockVideoCapture extends _i1.Mock implements _i38.VideoCapture { ), )), returnValueForMissingStub: - _i16.Future<_i11.Recorder>.value(_FakeRecorder_10( + _i17.Future<_i12.Recorder>.value(_FakeRecorder_11( this, Invocation.method( #getOutput, [], ), )), - ) as _i16.Future<_i11.Recorder>); + ) as _i17.Future<_i12.Recorder>); } /// A class which mocks [BuildContext]. /// /// See the documentation for Mockito's code generation for more information. -class MockBuildContext extends _i1.Mock implements _i12.BuildContext { +class MockBuildContext extends _i1.Mock implements _i13.BuildContext { @override - _i12.Widget get widget => (super.noSuchMethod( + _i13.Widget get widget => (super.noSuchMethod( Invocation.getter(#widget), - returnValue: _FakeWidget_11( + returnValue: _FakeWidget_12( this, Invocation.getter(#widget), ), - returnValueForMissingStub: _FakeWidget_11( + returnValueForMissingStub: _FakeWidget_12( this, Invocation.getter(#widget), ), - ) as _i12.Widget); + ) as _i13.Widget); @override bool get mounted => (super.noSuchMethod( @@ -1128,8 +1181,8 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { ) as bool); @override - _i12.InheritedWidget dependOnInheritedElement( - _i12.InheritedElement? ancestor, { + _i13.InheritedWidget dependOnInheritedElement( + _i13.InheritedElement? ancestor, { Object? aspect, }) => (super.noSuchMethod( @@ -1138,7 +1191,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { [ancestor], {#aspect: aspect}, ), - returnValue: _FakeInheritedWidget_12( + returnValue: _FakeInheritedWidget_13( this, Invocation.method( #dependOnInheritedElement, @@ -1146,7 +1199,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { {#aspect: aspect}, ), ), - returnValueForMissingStub: _FakeInheritedWidget_12( + returnValueForMissingStub: _FakeInheritedWidget_13( this, Invocation.method( #dependOnInheritedElement, @@ -1154,10 +1207,10 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { {#aspect: aspect}, ), ), - ) as _i12.InheritedWidget); + ) as _i13.InheritedWidget); @override - void visitAncestorElements(_i12.ConditionalElementVisitor? visitor) => + void visitAncestorElements(_i13.ConditionalElementVisitor? visitor) => super.noSuchMethod( Invocation.method( #visitAncestorElements, @@ -1167,7 +1220,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { ); @override - void visitChildElements(_i12.ElementVisitor? visitor) => super.noSuchMethod( + void visitChildElements(_i13.ElementVisitor? visitor) => super.noSuchMethod( Invocation.method( #visitChildElements, [visitor], @@ -1176,7 +1229,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { ); @override - void dispatchNotification(_i12.Notification? notification) => + void dispatchNotification(_i13.Notification? notification) => super.noSuchMethod( Invocation.method( #dispatchNotification, @@ -1186,9 +1239,9 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { ); @override - _i14.DiagnosticsNode describeElement( + _i15.DiagnosticsNode describeElement( String? name, { - _i14.DiagnosticsTreeStyle? style = _i14.DiagnosticsTreeStyle.errorProperty, + _i15.DiagnosticsTreeStyle? style = _i15.DiagnosticsTreeStyle.errorProperty, }) => (super.noSuchMethod( Invocation.method( @@ -1196,7 +1249,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { [name], {#style: style}, ), - returnValue: _FakeDiagnosticsNode_13( + returnValue: _FakeDiagnosticsNode_14( this, Invocation.method( #describeElement, @@ -1204,7 +1257,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { {#style: style}, ), ), - returnValueForMissingStub: _FakeDiagnosticsNode_13( + returnValueForMissingStub: _FakeDiagnosticsNode_14( this, Invocation.method( #describeElement, @@ -1212,12 +1265,12 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { {#style: style}, ), ), - ) as _i14.DiagnosticsNode); + ) as _i15.DiagnosticsNode); @override - _i14.DiagnosticsNode describeWidget( + _i15.DiagnosticsNode describeWidget( String? name, { - _i14.DiagnosticsTreeStyle? style = _i14.DiagnosticsTreeStyle.errorProperty, + _i15.DiagnosticsTreeStyle? style = _i15.DiagnosticsTreeStyle.errorProperty, }) => (super.noSuchMethod( Invocation.method( @@ -1225,7 +1278,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { [name], {#style: style}, ), - returnValue: _FakeDiagnosticsNode_13( + returnValue: _FakeDiagnosticsNode_14( this, Invocation.method( #describeWidget, @@ -1233,7 +1286,7 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { {#style: style}, ), ), - returnValueForMissingStub: _FakeDiagnosticsNode_13( + returnValueForMissingStub: _FakeDiagnosticsNode_14( this, Invocation.method( #describeWidget, @@ -1241,10 +1294,10 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { {#style: style}, ), ), - ) as _i14.DiagnosticsNode); + ) as _i15.DiagnosticsNode); @override - List<_i14.DiagnosticsNode> describeMissingAncestor( + List<_i15.DiagnosticsNode> describeMissingAncestor( {required Type? expectedAncestorType}) => (super.noSuchMethod( Invocation.method( @@ -1252,39 +1305,39 @@ class MockBuildContext extends _i1.Mock implements _i12.BuildContext { [], {#expectedAncestorType: expectedAncestorType}, ), - returnValue: <_i14.DiagnosticsNode>[], - returnValueForMissingStub: <_i14.DiagnosticsNode>[], - ) as List<_i14.DiagnosticsNode>); + returnValue: <_i15.DiagnosticsNode>[], + returnValueForMissingStub: <_i15.DiagnosticsNode>[], + ) as List<_i15.DiagnosticsNode>); @override - _i14.DiagnosticsNode describeOwnershipChain(String? name) => + _i15.DiagnosticsNode describeOwnershipChain(String? name) => (super.noSuchMethod( Invocation.method( #describeOwnershipChain, [name], ), - returnValue: _FakeDiagnosticsNode_13( + returnValue: _FakeDiagnosticsNode_14( this, Invocation.method( #describeOwnershipChain, [name], ), ), - returnValueForMissingStub: _FakeDiagnosticsNode_13( + returnValueForMissingStub: _FakeDiagnosticsNode_14( this, Invocation.method( #describeOwnershipChain, [name], ), ), - ) as _i14.DiagnosticsNode); + ) as _i15.DiagnosticsNode); } /// A class which mocks [TestInstanceManagerHostApi]. /// /// See the documentation for Mockito's code generation for more information. class MockTestInstanceManagerHostApi extends _i1.Mock - implements _i39.TestInstanceManagerHostApi { + implements _i42.TestInstanceManagerHostApi { @override void clear() => super.noSuchMethod( Invocation.method( @@ -1299,19 +1352,19 @@ class MockTestInstanceManagerHostApi extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTestSystemServicesHostApi extends _i1.Mock - implements _i39.TestSystemServicesHostApi { + implements _i42.TestSystemServicesHostApi { @override - _i16.Future<_i7.CameraPermissionsErrorData?> requestCameraPermissions( + _i17.Future<_i7.CameraPermissionsErrorData?> requestCameraPermissions( bool? enableAudio) => (super.noSuchMethod( Invocation.method( #requestCameraPermissions, [enableAudio], ), - returnValue: _i16.Future<_i7.CameraPermissionsErrorData?>.value(), + returnValue: _i17.Future<_i7.CameraPermissionsErrorData?>.value(), returnValueForMissingStub: - _i16.Future<_i7.CameraPermissionsErrorData?>.value(), - ) as _i16.Future<_i7.CameraPermissionsErrorData?>); + _i17.Future<_i7.CameraPermissionsErrorData?>.value(), + ) as _i17.Future<_i7.CameraPermissionsErrorData?>); @override String getTempFilePath( @@ -1326,7 +1379,7 @@ class MockTestSystemServicesHostApi extends _i1.Mock suffix, ], ), - returnValue: _i28.dummyValue( + returnValue: _i30.dummyValue( this, Invocation.method( #getTempFilePath, @@ -1336,7 +1389,7 @@ class MockTestSystemServicesHostApi extends _i1.Mock ], ), ), - returnValueForMissingStub: _i28.dummyValue( + returnValueForMissingStub: _i30.dummyValue( this, Invocation.method( #getTempFilePath, @@ -1353,7 +1406,7 @@ class MockTestSystemServicesHostApi extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockZoomState extends _i1.Mock implements _i19.ZoomState { +class MockZoomState extends _i1.Mock implements _i21.ZoomState { @override double get minZoomRatio => (super.noSuchMethod( Invocation.getter(#minZoomRatio), @@ -1374,31 +1427,31 @@ class MockZoomState extends _i1.Mock implements _i19.ZoomState { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockLiveCameraState extends _i1.Mock - implements _i4.LiveData<_i18.CameraState> { + implements _i4.LiveData<_i20.CameraState> { MockLiveCameraState() { _i1.throwOnMissingStub(this); } @override - _i16.Future observe(_i30.Observer<_i18.CameraState>? observer) => + _i17.Future observe(_i32.Observer<_i20.CameraState>? observer) => (super.noSuchMethod( Invocation.method( #observe, [observer], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future removeObservers() => (super.noSuchMethod( + _i17.Future removeObservers() => (super.noSuchMethod( Invocation.method( #removeObservers, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } /// A class which mocks [LiveData]. @@ -1406,29 +1459,29 @@ class MockLiveCameraState extends _i1.Mock /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockLiveZoomState extends _i1.Mock - implements _i4.LiveData<_i19.ZoomState> { + implements _i4.LiveData<_i21.ZoomState> { MockLiveZoomState() { _i1.throwOnMissingStub(this); } @override - _i16.Future observe(_i30.Observer<_i19.ZoomState>? observer) => + _i17.Future observe(_i32.Observer<_i21.ZoomState>? observer) => (super.noSuchMethod( Invocation.method( #observe, [observer], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); @override - _i16.Future removeObservers() => (super.noSuchMethod( + _i17.Future removeObservers() => (super.noSuchMethod( Invocation.method( #removeObservers, [], ), - returnValue: _i16.Future.value(), - returnValueForMissingStub: _i16.Future.value(), - ) as _i16.Future); + returnValue: _i17.Future.value(), + returnValueForMissingStub: _i17.Future.value(), + ) as _i17.Future); } diff --git a/packages/camera/camera_android_camerax/test/resolution_filter_test.dart b/packages/camera/camera_android_camerax/test/resolution_filter_test.dart new file mode 100644 index 000000000000..07a96ff68027 --- /dev/null +++ b/packages/camera/camera_android_camerax/test/resolution_filter_test.dart @@ -0,0 +1,90 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ui'; + +import 'package:camera_android_camerax/src/camerax_library.g.dart'; +import 'package:camera_android_camerax/src/instance_manager.dart'; +import 'package:camera_android_camerax/src/resolution_filter.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'resolution_filter_test.mocks.dart'; +import 'test_camerax_library.g.dart'; + +@GenerateMocks([ + TestResolutionFilterHostApi, + TestInstanceManagerHostApi, +]) +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('ResolutionFilter', () { + tearDown(() { + TestResolutionFilterHostApi.setup(null); + TestInstanceManagerHostApi.setup(null); + }); + + test( + 'detached ResolutionFilter.onePreferredSize constructor does not make call to Host API createWithOnePreferredSize', + () { + final MockTestResolutionFilterHostApi mockApi = + MockTestResolutionFilterHostApi(); + TestResolutionFilterHostApi.setup(mockApi); + TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi()); + + final InstanceManager instanceManager = InstanceManager( + onWeakReferenceRemoved: (_) {}, + ); + + const double preferredWidth = 270; + const double preferredHeight = 720; + const Size preferredResolution = Size(preferredWidth, preferredHeight); + + ResolutionFilter.onePreferredSizeDetached( + preferredResolution: preferredResolution, + instanceManager: instanceManager, + ); + + verifyNever(mockApi.createWithOnePreferredSize( + argThat(isA()), + argThat(isA() + .having( + (ResolutionInfo size) => size.width, 'width', preferredWidth) + .having((ResolutionInfo size) => size.height, 'height', + preferredHeight)), + )); + }); + + test('HostApi createWithOnePreferredSize creates expected ResolutionFilter', + () { + final MockTestResolutionFilterHostApi mockApi = + MockTestResolutionFilterHostApi(); + TestResolutionFilterHostApi.setup(mockApi); + TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi()); + + final InstanceManager instanceManager = InstanceManager( + onWeakReferenceRemoved: (_) {}, + ); + + const double preferredWidth = 890; + const double preferredHeight = 980; + const Size preferredResolution = Size(preferredWidth, preferredHeight); + + final ResolutionFilter instance = ResolutionFilter.onePreferredSize( + preferredResolution: preferredResolution, + instanceManager: instanceManager, + ); + verify(mockApi.createWithOnePreferredSize( + instanceManager.getIdentifier(instance), + argThat(isA() + .having( + (ResolutionInfo size) => size.width, 'width', preferredWidth) + .having((ResolutionInfo size) => size.height, 'height', + preferredHeight)), + )); + }); + }); +} diff --git a/packages/camera/camera_android_camerax/test/resolution_filter_test.mocks.dart b/packages/camera/camera_android_camerax/test/resolution_filter_test.mocks.dart new file mode 100644 index 000000000000..cf859c7b6378 --- /dev/null +++ b/packages/camera/camera_android_camerax/test/resolution_filter_test.mocks.dart @@ -0,0 +1,67 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in camera_android_camerax/test/resolution_filter_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:camera_android_camerax/src/camerax_library.g.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; + +import 'test_camerax_library.g.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// 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: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [TestResolutionFilterHostApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTestResolutionFilterHostApi extends _i1.Mock + implements _i2.TestResolutionFilterHostApi { + MockTestResolutionFilterHostApi() { + _i1.throwOnMissingStub(this); + } + + @override + void createWithOnePreferredSize( + int? identifier, + _i3.ResolutionInfo? preferredResolution, + ) => + super.noSuchMethod( + Invocation.method( + #createWithOnePreferredSize, + [ + identifier, + preferredResolution, + ], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [TestInstanceManagerHostApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTestInstanceManagerHostApi extends _i1.Mock + implements _i2.TestInstanceManagerHostApi { + MockTestInstanceManagerHostApi() { + _i1.throwOnMissingStub(this); + } + + @override + void clear() => super.noSuchMethod( + Invocation.method( + #clear, + [], + ), + returnValueForMissingStub: null, + ); +} diff --git a/packages/camera/camera_android_camerax/test/resolution_selector_test.dart b/packages/camera/camera_android_camerax/test/resolution_selector_test.dart index 45ecef576a3a..7aaa37ae1ea0 100644 --- a/packages/camera/camera_android_camerax/test/resolution_selector_test.dart +++ b/packages/camera/camera_android_camerax/test/resolution_selector_test.dart @@ -6,6 +6,7 @@ import 'dart:ui'; import 'package:camera_android_camerax/src/aspect_ratio_strategy.dart'; import 'package:camera_android_camerax/src/instance_manager.dart'; +import 'package:camera_android_camerax/src/resolution_filter.dart'; import 'package:camera_android_camerax/src/resolution_selector.dart'; import 'package:camera_android_camerax/src/resolution_strategy.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -17,6 +18,7 @@ import 'test_camerax_library.g.dart'; @GenerateMocks([ AspectRatioStrategy, + ResolutionFilter, ResolutionStrategy, TestResolutionSelectorHostApi, TestInstanceManagerHostApi, @@ -54,15 +56,13 @@ void main() { ResolutionSelector.detached( resolutionStrategy: MockResolutionStrategy(), + resolutionFilter: MockResolutionFilter(), aspectRatioStrategy: MockAspectRatioStrategy(), instanceManager: instanceManager, ); - verifyNever(mockApi.create( - argThat(isA()), - argThat(isA()), - argThat(isA()), - )); + verifyNever(mockApi.create(argThat(isA()), argThat(isA()), + argThat(isA()), argThat(isA()))); }); test('HostApi create creates expected ResolutionSelector instance', () { @@ -91,6 +91,20 @@ void main() { ), ); + final ResolutionFilter resolutionFilter = + ResolutionFilter.onePreferredSizeDetached( + preferredResolution: const Size(30, 40)); + const int resolutionFilterIdentifier = 54; + instanceManager.addHostCreatedInstance( + resolutionFilter, + resolutionFilterIdentifier, + onCopy: (ResolutionFilter original) => + ResolutionFilter.onePreferredSizeDetached( + preferredResolution: original.preferredResolution, + instanceManager: instanceManager, + ), + ); + final AspectRatioStrategy aspectRatioStrategy = AspectRatioStrategy.detached( preferredAspectRatio: AspectRatio.ratio4To3, @@ -110,6 +124,7 @@ void main() { final ResolutionSelector instance = ResolutionSelector( resolutionStrategy: resolutionStrategy, + resolutionFilter: resolutionFilter, aspectRatioStrategy: aspectRatioStrategy, instanceManager: instanceManager, ); @@ -117,6 +132,7 @@ void main() { verify(mockApi.create( instanceManager.getIdentifier(instance), resolutionStrategyIdentifier, + resolutionFilterIdentifier, aspectRatioStrategyIdentifier, )); }); diff --git a/packages/camera/camera_android_camerax/test/resolution_selector_test.mocks.dart b/packages/camera/camera_android_camerax/test/resolution_selector_test.mocks.dart index 541092f089a9..c36ae699e8ad 100644 --- a/packages/camera/camera_android_camerax/test/resolution_selector_test.mocks.dart +++ b/packages/camera/camera_android_camerax/test/resolution_selector_test.mocks.dart @@ -3,11 +3,14 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:camera_android_camerax/src/aspect_ratio_strategy.dart' as _i2; -import 'package:camera_android_camerax/src/resolution_strategy.dart' as _i3; +import 'dart:ui' as _i2; + +import 'package:camera_android_camerax/src/aspect_ratio_strategy.dart' as _i3; +import 'package:camera_android_camerax/src/resolution_filter.dart' as _i4; +import 'package:camera_android_camerax/src/resolution_strategy.dart' as _i5; import 'package:mockito/mockito.dart' as _i1; -import 'test_camerax_library.g.dart' as _i4; +import 'test_camerax_library.g.dart' as _i6; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -22,12 +25,22 @@ import 'test_camerax_library.g.dart' as _i4; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +class _FakeSize_0 extends _i1.SmartFake implements _i2.Size { + _FakeSize_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [AspectRatioStrategy]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockAspectRatioStrategy extends _i1.Mock - implements _i2.AspectRatioStrategy { + implements _i3.AspectRatioStrategy { MockAspectRatioStrategy() { _i1.throwOnMissingStub(this); } @@ -45,12 +58,31 @@ class MockAspectRatioStrategy extends _i1.Mock ) as int); } +/// A class which mocks [ResolutionFilter]. +/// +/// See the documentation for Mockito's code generation for more information. +// ignore: must_be_immutable +class MockResolutionFilter extends _i1.Mock implements _i4.ResolutionFilter { + MockResolutionFilter() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.Size get preferredResolution => (super.noSuchMethod( + Invocation.getter(#preferredResolution), + returnValue: _FakeSize_0( + this, + Invocation.getter(#preferredResolution), + ), + ) as _i2.Size); +} + /// A class which mocks [ResolutionStrategy]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockResolutionStrategy extends _i1.Mock - implements _i3.ResolutionStrategy { + implements _i5.ResolutionStrategy { MockResolutionStrategy() { _i1.throwOnMissingStub(this); } @@ -60,7 +92,7 @@ class MockResolutionStrategy extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTestResolutionSelectorHostApi extends _i1.Mock - implements _i4.TestResolutionSelectorHostApi { + implements _i6.TestResolutionSelectorHostApi { MockTestResolutionSelectorHostApi() { _i1.throwOnMissingStub(this); } @@ -69,6 +101,7 @@ class MockTestResolutionSelectorHostApi extends _i1.Mock void create( int? identifier, int? resolutionStrategyIdentifier, + int? resolutionSelectorIdentifier, int? aspectRatioStrategyIdentifier, ) => super.noSuchMethod( @@ -77,6 +110,7 @@ class MockTestResolutionSelectorHostApi extends _i1.Mock [ identifier, resolutionStrategyIdentifier, + resolutionSelectorIdentifier, aspectRatioStrategyIdentifier, ], ), @@ -88,7 +122,7 @@ class MockTestResolutionSelectorHostApi extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTestInstanceManagerHostApi extends _i1.Mock - implements _i4.TestInstanceManagerHostApi { + implements _i6.TestInstanceManagerHostApi { MockTestInstanceManagerHostApi() { _i1.throwOnMissingStub(this); } diff --git a/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart index b69825928dd9..8080e4276fc8 100644 --- a/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart +++ b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart @@ -1321,7 +1321,7 @@ abstract class TestResolutionSelectorHostApi { static const MessageCodec codec = StandardMessageCodec(); void create(int identifier, int? resolutionStrategyIdentifier, - int? aspectRatioStrategyIdentifier); + int? resolutionSelectorIdentifier, int? aspectRatioStrategyIdentifier); static void setup(TestResolutionSelectorHostApi? api, {BinaryMessenger? binaryMessenger}) { @@ -1343,8 +1343,12 @@ abstract class TestResolutionSelectorHostApi { assert(arg_identifier != null, 'Argument for dev.flutter.pigeon.ResolutionSelectorHostApi.create was null, expected non-null int.'); final int? arg_resolutionStrategyIdentifier = (args[1] as int?); - final int? arg_aspectRatioStrategyIdentifier = (args[2] as int?); - api.create(arg_identifier!, arg_resolutionStrategyIdentifier, + final int? arg_resolutionSelectorIdentifier = (args[2] as int?); + final int? arg_aspectRatioStrategyIdentifier = (args[3] as int?); + api.create( + arg_identifier!, + arg_resolutionStrategyIdentifier, + arg_resolutionSelectorIdentifier, arg_aspectRatioStrategyIdentifier); return []; }); @@ -2359,3 +2363,68 @@ abstract class TestCamera2CameraControlHostApi { } } } + +class _TestResolutionFilterHostApiCodec extends StandardMessageCodec { + const _TestResolutionFilterHostApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is ResolutionInfo) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return ResolutionInfo.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class TestResolutionFilterHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec codec = + _TestResolutionFilterHostApiCodec(); + + void createWithOnePreferredSize( + int identifier, ResolutionInfo preferredResolution); + + static void setup(TestResolutionFilterHostApi? api, + {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.ResolutionFilterHostApi.createWithOnePreferredSize', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.ResolutionFilterHostApi.createWithOnePreferredSize was null.'); + final List args = (message as List?)!; + final int? arg_identifier = (args[0] as int?); + assert(arg_identifier != null, + 'Argument for dev.flutter.pigeon.ResolutionFilterHostApi.createWithOnePreferredSize was null, expected non-null int.'); + final ResolutionInfo? arg_preferredResolution = + (args[1] as ResolutionInfo?); + assert(arg_preferredResolution != null, + 'Argument for dev.flutter.pigeon.ResolutionFilterHostApi.createWithOnePreferredSize was null, expected non-null ResolutionInfo.'); + api.createWithOnePreferredSize( + arg_identifier!, arg_preferredResolution!); + return []; + }); + } + } + } +}