diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md
index ab60e8aba87a..1cddca1cbbc3 100644
--- a/packages/camera/camera_android_camerax/CHANGELOG.md
+++ b/packages/camera/camera_android_camerax/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.5.0+12
+
+* Wraps classes needed to implement resolution configuration for image capture, image analysis, and preview.
+* Removes usages of deprecated APIs for resolution configuration.
+* Bumps CameraX version to 1.3.0-beta01.
+
## 0.5.0+11
* Fixes issue with image data not being emitted after relistening to stream returned by `onStreamedFrameAvailable`.
diff --git a/packages/camera/camera_android_camerax/android/build.gradle b/packages/camera/camera_android_camerax/android/build.gradle
index f10f13336081..5530a3bb1043 100644
--- a/packages/camera/camera_android_camerax/android/build.gradle
+++ b/packages/camera/camera_android_camerax/android/build.gradle
@@ -61,7 +61,7 @@ android {
dependencies {
// CameraX core library using the camera2 implementation must use same version number.
- def camerax_version = "1.3.0-alpha05"
+ def camerax_version = "1.3.0-beta01"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/AspectRatioStrategyHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/AspectRatioStrategyHostApiImpl.java
new file mode 100644
index 000000000000..91e0def66eaf
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/AspectRatioStrategyHostApiImpl.java
@@ -0,0 +1,65 @@
+// 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 androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.resolutionselector.AspectRatioStrategy;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.AspectRatioStrategyHostApi;
+
+/**
+ * Host API implementation for {@link AspectRatioStrategy}.
+ *
+ *
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 AspectRatioStrategyHostApiImpl implements AspectRatioStrategyHostApi {
+ private final InstanceManager instanceManager;
+ private final AspectRatioStrategyProxy proxy;
+
+ /** Proxy for constructors and static method of {@link AspectRatioStrategy}. */
+ @VisibleForTesting
+ public static class AspectRatioStrategyProxy {
+ /** Creates an instance of {@link AspectRatioStrategy}. */
+ @NonNull
+ public AspectRatioStrategy create(
+ @NonNull Long preferredAspectRatio, @NonNull Long fallbackRule) {
+ return new AspectRatioStrategy(preferredAspectRatio.intValue(), fallbackRule.intValue());
+ }
+ }
+
+ /**
+ * Constructs an {@link AspectRatioStrategyHostApiImpl}.
+ *
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public AspectRatioStrategyHostApiImpl(@NonNull InstanceManager instanceManager) {
+ this(instanceManager, new AspectRatioStrategyProxy());
+ }
+
+ /**
+ * Constructs an {@link AspectRatioStrategyHostApiImpl}.
+ *
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ * @param proxy proxy for constructors and static method of {@link AspectRatioStrategy}
+ */
+ @VisibleForTesting
+ AspectRatioStrategyHostApiImpl(
+ @NonNull InstanceManager instanceManager, @NonNull AspectRatioStrategyProxy proxy) {
+ this.instanceManager = instanceManager;
+ this.proxy = proxy;
+ }
+
+ /**
+ * Creates an {@link AspectRatioStrategy} instance with the preferred aspect ratio and fallback
+ * rule specified.
+ */
+ @Override
+ public void create(
+ @NonNull Long identifier, @NonNull Long preferredAspectRatio, @NonNull Long fallbackRule) {
+ instanceManager.addDartCreatedInstance(
+ proxy.create(preferredAspectRatio, fallbackRule), identifier);
+ }
+}
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 dd8ab514652c..dbae2a468052 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
@@ -97,6 +97,12 @@ public void setUp(
binaryMessenger, pendingRecordingHostApiImpl);
videoCaptureHostApiImpl = new VideoCaptureHostApiImpl(binaryMessenger, instanceManager);
GeneratedCameraXLibrary.VideoCaptureHostApi.setup(binaryMessenger, videoCaptureHostApiImpl);
+ GeneratedCameraXLibrary.ResolutionSelectorHostApi.setup(
+ binaryMessenger, new ResolutionSelectorHostApiImpl(instanceManager));
+ GeneratedCameraXLibrary.ResolutionStrategyHostApi.setup(
+ binaryMessenger, new ResolutionStrategyHostApiImpl(instanceManager));
+ GeneratedCameraXLibrary.AspectRatioStrategyHostApi.setup(
+ binaryMessenger, new AspectRatioStrategyHostApiImpl(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 c6f627993772..680ecb805250 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
@@ -76,6 +76,23 @@ private CameraStateType(final int index) {
}
}
+ /**
+ * The types (T) properly wrapped to be used as a LiveData.
+ *
+ * If you need to add another type to support a type S to use a LiveData in this plugin,
+ * ensure the following is done on the Dart side:
+ *
+ *
* In `../lib/src/live_data.dart`, add new cases for S in
+ * `_LiveDataHostApiImpl#getValueFromInstances` to get the current value of type S from a
+ * LiveData instance and in `LiveDataFlutterApiImpl#create` to create the expected type of
+ * LiveData when requested.
+ *
+ *
On the native side, ensure the following is done:
+ *
+ *
* Update `LiveDataHostApiImpl#getValue` is updated to properly return identifiers for
+ * instances of type S. * Update `ObserverFlutterApiWrapper#onChanged` to properly handle
+ * receiving calls with instances of type S if a LiveData instance is observed.
+ */
public enum LiveDataSupportedType {
CAMERA_STATE(0),
ZOOM_STATE(1);
@@ -1297,8 +1314,6 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
switch (type) {
case (byte) 128:
return ResolutionInfo.fromList((ArrayList) readValue(buffer));
- case (byte) 129:
- return ResolutionInfo.fromList((ArrayList) readValue(buffer));
default:
return super.readValueOfType(type, buffer);
}
@@ -1309,9 +1324,6 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
if (value instanceof ResolutionInfo) {
stream.write(128);
writeValue(stream, ((ResolutionInfo) value).toList());
- } else if (value instanceof ResolutionInfo) {
- stream.write(129);
- writeValue(stream, ((ResolutionInfo) value).toList());
} else {
super.writeValue(stream, value);
}
@@ -1322,9 +1334,7 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
public interface PreviewHostApi {
void create(
- @NonNull Long identifier,
- @Nullable Long rotation,
- @Nullable ResolutionInfo targetResolution);
+ @NonNull Long identifier, @Nullable Long rotation, @Nullable Long resolutionSelectorId);
@NonNull
Long setSurfaceProvider(@NonNull Long identifier);
@@ -1351,12 +1361,14 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PreviewHos
ArrayList args = (ArrayList) message;
Number identifierArg = (Number) args.get(0);
Number rotationArg = (Number) args.get(1);
- ResolutionInfo targetResolutionArg = (ResolutionInfo) args.get(2);
+ Number resolutionSelectorIdArg = (Number) args.get(2);
try {
api.create(
(identifierArg == null) ? null : identifierArg.longValue(),
(rotationArg == null) ? null : rotationArg.longValue(),
- targetResolutionArg);
+ (resolutionSelectorIdArg == null)
+ ? null
+ : resolutionSelectorIdArg.longValue());
wrapped.add(0, null);
} catch (Throwable exception) {
ArrayList wrappedError = wrapError(exception);
@@ -1911,40 +1923,11 @@ public void create(@NonNull Long identifierArg, @NonNull Reply callback) {
channelReply -> callback.reply(null));
}
}
-
- private static class ImageCaptureHostApiCodec extends StandardMessageCodec {
- public static final ImageCaptureHostApiCodec INSTANCE = new ImageCaptureHostApiCodec();
-
- private ImageCaptureHostApiCodec() {}
-
- @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 ImageCaptureHostApi {
void create(
- @NonNull Long identifier,
- @Nullable Long flashMode,
- @Nullable ResolutionInfo targetResolution);
+ @NonNull Long identifier, @Nullable Long flashMode, @Nullable Long resolutionSelectorId);
void setFlashMode(@NonNull Long identifier, @NonNull Long flashMode);
@@ -1952,7 +1935,7 @@ void create(
/** The codec used by ImageCaptureHostApi. */
static @NonNull MessageCodec getCodec() {
- return ImageCaptureHostApiCodec.INSTANCE;
+ return new StandardMessageCodec();
}
/**
* Sets up an instance of `ImageCaptureHostApi` to handle messages through the
@@ -1970,12 +1953,14 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable ImageCaptu
ArrayList args = (ArrayList) message;
Number identifierArg = (Number) args.get(0);
Number flashModeArg = (Number) args.get(1);
- ResolutionInfo targetResolutionArg = (ResolutionInfo) args.get(2);
+ Number resolutionSelectorIdArg = (Number) args.get(2);
try {
api.create(
(identifierArg == null) ? null : identifierArg.longValue(),
(flashModeArg == null) ? null : flashModeArg.longValue(),
- targetResolutionArg);
+ (resolutionSelectorIdArg == null)
+ ? null
+ : resolutionSelectorIdArg.longValue());
wrapped.add(0, null);
} catch (Throwable exception) {
ArrayList wrappedError = wrapError(exception);
@@ -2046,6 +2031,182 @@ public void error(Throwable error) {
}
}
+ private static class ResolutionStrategyHostApiCodec extends StandardMessageCodec {
+ public static final ResolutionStrategyHostApiCodec INSTANCE =
+ new ResolutionStrategyHostApiCodec();
+
+ private ResolutionStrategyHostApiCodec() {}
+
+ @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 ResolutionStrategyHostApi {
+
+ void create(
+ @NonNull Long identifier, @Nullable ResolutionInfo boundSize, @Nullable Long fallbackRule);
+
+ /** The codec used by ResolutionStrategyHostApi. */
+ static @NonNull MessageCodec getCodec() {
+ return ResolutionStrategyHostApiCodec.INSTANCE;
+ }
+ /**
+ * Sets up an instance of `ResolutionStrategyHostApi` to handle messages through the
+ * `binaryMessenger`.
+ */
+ static void setup(
+ @NonNull BinaryMessenger binaryMessenger, @Nullable ResolutionStrategyHostApi api) {
+ {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.ResolutionStrategyHostApi.create", getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ ArrayList wrapped = new ArrayList();
+ ArrayList args = (ArrayList) message;
+ Number identifierArg = (Number) args.get(0);
+ ResolutionInfo boundSizeArg = (ResolutionInfo) args.get(1);
+ Number fallbackRuleArg = (Number) args.get(2);
+ try {
+ api.create(
+ (identifierArg == null) ? null : identifierArg.longValue(),
+ boundSizeArg,
+ (fallbackRuleArg == null) ? null : fallbackRuleArg.longValue());
+ wrapped.add(0, null);
+ } catch (Throwable exception) {
+ ArrayList wrappedError = wrapError(exception);
+ wrapped = wrappedError;
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
+ }
+ }
+ /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+ public interface ResolutionSelectorHostApi {
+
+ void create(
+ @NonNull Long identifier,
+ @Nullable Long resolutionStrategyIdentifier,
+ @Nullable Long aspectRatioStrategyIdentifier);
+
+ /** The codec used by ResolutionSelectorHostApi. */
+ static @NonNull MessageCodec getCodec() {
+ return new StandardMessageCodec();
+ }
+ /**
+ * Sets up an instance of `ResolutionSelectorHostApi` to handle messages through the
+ * `binaryMessenger`.
+ */
+ static void setup(
+ @NonNull BinaryMessenger binaryMessenger, @Nullable ResolutionSelectorHostApi api) {
+ {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.ResolutionSelectorHostApi.create", getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ ArrayList wrapped = new ArrayList();
+ ArrayList args = (ArrayList) message;
+ Number identifierArg = (Number) args.get(0);
+ Number resolutionStrategyIdentifierArg = (Number) args.get(1);
+ Number aspectRatioStrategyIdentifierArg = (Number) args.get(2);
+ try {
+ api.create(
+ (identifierArg == null) ? null : identifierArg.longValue(),
+ (resolutionStrategyIdentifierArg == null)
+ ? null
+ : resolutionStrategyIdentifierArg.longValue(),
+ (aspectRatioStrategyIdentifierArg == null)
+ ? null
+ : aspectRatioStrategyIdentifierArg.longValue());
+ wrapped.add(0, null);
+ } catch (Throwable exception) {
+ ArrayList wrappedError = wrapError(exception);
+ wrapped = wrappedError;
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
+ }
+ }
+ /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+ public interface AspectRatioStrategyHostApi {
+
+ void create(
+ @NonNull Long identifier, @NonNull Long preferredAspectRatio, @NonNull Long fallbackRule);
+
+ /** The codec used by AspectRatioStrategyHostApi. */
+ static @NonNull MessageCodec getCodec() {
+ return new StandardMessageCodec();
+ }
+ /**
+ * Sets up an instance of `AspectRatioStrategyHostApi` to handle messages through the
+ * `binaryMessenger`.
+ */
+ static void setup(
+ @NonNull BinaryMessenger binaryMessenger, @Nullable AspectRatioStrategyHostApi api) {
+ {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger,
+ "dev.flutter.pigeon.AspectRatioStrategyHostApi.create",
+ getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ ArrayList wrapped = new ArrayList();
+ ArrayList args = (ArrayList) message;
+ Number identifierArg = (Number) args.get(0);
+ Number preferredAspectRatioArg = (Number) args.get(1);
+ Number fallbackRuleArg = (Number) args.get(2);
+ try {
+ api.create(
+ (identifierArg == null) ? null : identifierArg.longValue(),
+ (preferredAspectRatioArg == null)
+ ? null
+ : preferredAspectRatioArg.longValue(),
+ (fallbackRuleArg == null) ? null : fallbackRuleArg.longValue());
+ wrapped.add(0, null);
+ } catch (Throwable exception) {
+ ArrayList wrappedError = wrapError(exception);
+ wrapped = wrappedError;
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
+ }
+ }
+
private static class CameraStateFlutterApiCodec extends StandardMessageCodec {
public static final CameraStateFlutterApiCodec INSTANCE = new CameraStateFlutterApiCodec();
@@ -2194,37 +2355,10 @@ public void create(
channelReply -> callback.reply(null));
}
}
-
- private static class ImageAnalysisHostApiCodec extends StandardMessageCodec {
- public static final ImageAnalysisHostApiCodec INSTANCE = new ImageAnalysisHostApiCodec();
-
- private ImageAnalysisHostApiCodec() {}
-
- @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 ImageAnalysisHostApi {
- void create(@NonNull Long identifier, @Nullable ResolutionInfo targetResolutionIdentifier);
+ void create(@NonNull Long identifier, @Nullable Long resolutionSelectorId);
void setAnalyzer(@NonNull Long identifier, @NonNull Long analyzerIdentifier);
@@ -2232,7 +2366,7 @@ public interface ImageAnalysisHostApi {
/** The codec used by ImageAnalysisHostApi. */
static @NonNull MessageCodec getCodec() {
- return ImageAnalysisHostApiCodec.INSTANCE;
+ return new StandardMessageCodec();
}
/**
* Sets up an instance of `ImageAnalysisHostApi` to handle messages through the
@@ -2250,11 +2384,13 @@ static void setup(
ArrayList wrapped = new ArrayList();
ArrayList args = (ArrayList) message;
Number identifierArg = (Number) args.get(0);
- ResolutionInfo targetResolutionIdentifierArg = (ResolutionInfo) args.get(1);
+ Number resolutionSelectorIdArg = (Number) args.get(1);
try {
api.create(
(identifierArg == null) ? null : identifierArg.longValue(),
- targetResolutionIdentifierArg);
+ (resolutionSelectorIdArg == null)
+ ? null
+ : resolutionSelectorIdArg.longValue());
wrapped.add(0, null);
} catch (Throwable exception) {
ArrayList wrappedError = wrapError(exception);
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageAnalysisHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageAnalysisHostApiImpl.java
index 5e786176d50c..58491477ae15 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageAnalysisHostApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageAnalysisHostApiImpl.java
@@ -9,10 +9,10 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
import androidx.core.content.ContextCompat;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ImageAnalysisHostApi;
-import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionInfo;
import java.util.Objects;
public class ImageAnalysisHostApiImpl implements ImageAnalysisHostApi {
@@ -38,11 +38,13 @@ public void setContext(@NonNull Context context) {
/** Creates an {@link ImageAnalysis} instance with the target resolution if specified. */
@Override
- public void create(@NonNull Long identifier, @Nullable ResolutionInfo targetResolution) {
+ public void create(@NonNull Long identifier, @Nullable Long resolutionSelectorId) {
ImageAnalysis.Builder imageAnalysisBuilder = cameraXProxy.createImageAnalysisBuilder();
- if (targetResolution != null) {
- imageAnalysisBuilder.setTargetResolution(CameraXProxy.sizeFromResolution(targetResolution));
+ if (resolutionSelectorId != null) {
+ ResolutionSelector resolutionSelector =
+ Objects.requireNonNull(instanceManager.getInstance(resolutionSelectorId));
+ imageAnalysisBuilder.setResolutionSelector(resolutionSelector);
}
ImageAnalysis imageAnalysis = imageAnalysisBuilder.build();
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureHostApiImpl.java
index f2e71aa3eeee..88ec2debb7a8 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureHostApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ImageCaptureHostApiImpl.java
@@ -10,6 +10,7 @@
import androidx.annotation.VisibleForTesting;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ImageCaptureHostApi;
import java.io.File;
@@ -52,17 +53,19 @@ public void setContext(@NonNull Context context) {
*/
@Override
public void create(
- @NonNull Long identifier,
- @Nullable Long flashMode,
- @Nullable GeneratedCameraXLibrary.ResolutionInfo targetResolution) {
+ @NonNull Long identifier, @Nullable Long flashMode, @Nullable Long resolutionSelectorId) {
ImageCapture.Builder imageCaptureBuilder = cameraXProxy.createImageCaptureBuilder();
+
if (flashMode != null) {
// This sets the requested flash mode, but may fail silently.
imageCaptureBuilder.setFlashMode(flashMode.intValue());
}
- if (targetResolution != null) {
- imageCaptureBuilder.setTargetResolution(CameraXProxy.sizeFromResolution(targetResolution));
+ if (resolutionSelectorId != null) {
+ ResolutionSelector resolutionSelector =
+ Objects.requireNonNull(instanceManager.getInstance(resolutionSelectorId));
+ imageCaptureBuilder.setResolutionSelector(resolutionSelector);
}
+
ImageCapture imageCapture = imageCaptureBuilder.build();
instanceManager.addDartCreatedInstance(imageCapture, identifier);
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java
index 6f93fd0f87cb..07b581ebf96a 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/PreviewHostApiImpl.java
@@ -12,6 +12,7 @@
import androidx.annotation.VisibleForTesting;
import androidx.camera.core.Preview;
import androidx.camera.core.SurfaceRequest;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.PreviewHostApi;
import io.flutter.view.TextureRegistry;
@@ -38,16 +39,18 @@ public PreviewHostApiImpl(
/** Creates a {@link Preview} with the target rotation and resolution if specified. */
@Override
public void create(
- @NonNull Long identifier,
- @Nullable Long rotation,
- @Nullable GeneratedCameraXLibrary.ResolutionInfo targetResolution) {
+ @NonNull Long identifier, @Nullable Long rotation, @Nullable Long resolutionSelectorId) {
Preview.Builder previewBuilder = cameraXProxy.createPreviewBuilder();
+
if (rotation != null) {
previewBuilder.setTargetRotation(rotation.intValue());
}
- if (targetResolution != null) {
- previewBuilder.setTargetResolution(CameraXProxy.sizeFromResolution(targetResolution));
+ if (resolutionSelectorId != null) {
+ ResolutionSelector resolutionSelector =
+ Objects.requireNonNull(instanceManager.getInstance(resolutionSelectorId));
+ previewBuilder.setResolutionSelector(resolutionSelector);
}
+
Preview preview = previewBuilder.build();
instanceManager.addDartCreatedInstance(preview, 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
new file mode 100644
index 000000000000..be05e1bb8bef
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionSelectorHostApiImpl.java
@@ -0,0 +1,87 @@
+// 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 androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.resolutionselector.AspectRatioStrategy;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
+import androidx.camera.core.resolutionselector.ResolutionStrategy;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionSelectorHostApi;
+import java.util.Objects;
+
+/**
+ * Host API implementation for {@link ResolutionSelector}.
+ *
+ * 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 ResolutionSelectorHostApiImpl implements ResolutionSelectorHostApi {
+ private final InstanceManager instanceManager;
+ private final ResolutionSelectorProxy proxy;
+
+ /** Proxy for constructors and static method of {@link ResolutionSelector}. */
+ @VisibleForTesting
+ public static class ResolutionSelectorProxy {
+ /** Creates an instance of {@link ResolutionSelector}. */
+ @NonNull
+ public ResolutionSelector create(
+ @Nullable ResolutionStrategy resolutionStrategy,
+ @Nullable AspectRatioStrategy aspectRatioStrategy) {
+ final ResolutionSelector.Builder builder = new ResolutionSelector.Builder();
+ if (resolutionStrategy != null) {
+ builder.setResolutionStrategy(resolutionStrategy);
+ }
+ if (aspectRatioStrategy != null) {
+ builder.setAspectRatioStrategy(aspectRatioStrategy);
+ }
+ return builder.build();
+ }
+ }
+
+ /**
+ * Constructs a {@link ResolutionSelectorHostApiImpl}.
+ *
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public ResolutionSelectorHostApiImpl(@NonNull InstanceManager instanceManager) {
+ this(instanceManager, new ResolutionSelectorProxy());
+ }
+
+ /**
+ * Constructs a {@link ResolutionSelectorHostApiImpl}.
+ *
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ * @param proxy proxy for constructors and static method of {@link ResolutionSelector}
+ */
+ @VisibleForTesting
+ ResolutionSelectorHostApiImpl(
+ @NonNull InstanceManager instanceManager, @NonNull ResolutionSelectorProxy proxy) {
+ this.instanceManager = instanceManager;
+ this.proxy = proxy;
+ }
+
+ /**
+ * Creates a {@link ResolutionSelector} instance with the {@link ResolutionStrategy} and {@link
+ * AspectRatio} that have the identifiers specified if provided.
+ */
+ @Override
+ public void create(
+ @NonNull Long identifier,
+ @Nullable Long resolutionStrategyIdentifier,
+ @Nullable Long aspectRatioStrategyIdentifier) {
+ instanceManager.addDartCreatedInstance(
+ proxy.create(
+ resolutionStrategyIdentifier == null
+ ? null
+ : Objects.requireNonNull(instanceManager.getInstance(resolutionStrategyIdentifier)),
+ aspectRatioStrategyIdentifier == null
+ ? null
+ : Objects.requireNonNull(
+ instanceManager.getInstance(aspectRatioStrategyIdentifier))),
+ identifier);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionStrategyHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionStrategyHostApiImpl.java
new file mode 100644
index 000000000000..c110c40446ef
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ResolutionStrategyHostApiImpl.java
@@ -0,0 +1,81 @@
+// 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.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.resolutionselector.ResolutionStrategy;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionStrategyHostApi;
+
+/**
+ * Host API implementation for {@link ResolutionStrategy}.
+ *
+ *
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 ResolutionStrategyHostApiImpl implements ResolutionStrategyHostApi {
+ private final InstanceManager instanceManager;
+ private final ResolutionStrategyProxy proxy;
+
+ /** Proxy for constructors and static method of {@link ResolutionStrategy}. */
+ @VisibleForTesting
+ public static class ResolutionStrategyProxy {
+
+ /** Creates an instance of {@link ResolutionStrategy}. */
+ @NonNull
+ public ResolutionStrategy create(@NonNull Size boundSize, @NonNull Long fallbackRule) {
+ return new ResolutionStrategy(boundSize, fallbackRule.intValue());
+ }
+ }
+
+ /**
+ * Constructs a {@link ResolutionStrategyHostApiImpl}.
+ *
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public ResolutionStrategyHostApiImpl(@NonNull InstanceManager instanceManager) {
+ this(instanceManager, new ResolutionStrategyProxy());
+ }
+
+ /**
+ * Constructs a {@link ResolutionStrategyHostApiImpl}.
+ *
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ * @param proxy proxy for constructors and static method of {@link ResolutionStrategy}
+ */
+ @VisibleForTesting
+ ResolutionStrategyHostApiImpl(
+ @NonNull InstanceManager instanceManager, @NonNull ResolutionStrategyProxy proxy) {
+ this.instanceManager = instanceManager;
+ this.proxy = proxy;
+ }
+
+ /**
+ * Creates a {@link ResolutionStrategy} instance with the {@link
+ * GeneratedCameraXLibrary.ResolutionInfo} bound size and {@code fallbackRule} if specified.
+ */
+ @Override
+ public void create(
+ @NonNull Long identifier,
+ @Nullable GeneratedCameraXLibrary.ResolutionInfo boundSize,
+ @Nullable Long fallbackRule) {
+ ResolutionStrategy resolutionStrategy;
+ if (boundSize == null && fallbackRule == null) {
+ // Strategy that chooses the highest available resolution does not have a bound size or fallback rule.
+ resolutionStrategy = ResolutionStrategy.HIGHEST_AVAILABLE_STRATEGY;
+ } else if (boundSize == null) {
+ throw new IllegalArgumentException(
+ "A bound size must be specified if a non-null fallback rule is specified to create a valid ResolutionStrategy.");
+ } else {
+ resolutionStrategy =
+ proxy.create(
+ new Size(boundSize.getWidth().intValue(), boundSize.getHeight().intValue()),
+ fallbackRule);
+ }
+ instanceManager.addDartCreatedInstance(resolutionStrategy, identifier);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/AspectRatioStrategyTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/AspectRatioStrategyTest.java
new file mode 100644
index 000000000000..02e757dc39fa
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/AspectRatioStrategyTest.java
@@ -0,0 +1,51 @@
+// 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 static org.mockito.Mockito.when;
+
+import androidx.camera.core.resolutionselector.AspectRatioStrategy;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+public class AspectRatioStrategyTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+ @Mock public AspectRatioStrategy mockAspectRatioStrategy;
+ @Mock public AspectRatioStrategyHostApiImpl.AspectRatioStrategyProxy mockProxy;
+
+ InstanceManager instanceManager;
+
+ @Before
+ public void setUp() {
+ instanceManager = InstanceManager.create(identifier -> {});
+ }
+
+ @After
+ public void tearDown() {
+ instanceManager.stopFinalizationListener();
+ }
+
+ @Test
+ public void hostApiCreate_createsExpectedAspectRatioStrategyInstance() {
+ final Long preferredAspectRatio = 0L;
+ final Long fallbackRule = 1L;
+
+ when(mockProxy.create(preferredAspectRatio, fallbackRule)).thenReturn(mockAspectRatioStrategy);
+
+ final AspectRatioStrategyHostApiImpl hostApi =
+ new AspectRatioStrategyHostApiImpl(instanceManager, mockProxy);
+
+ final long instanceIdentifier = 0;
+ hostApi.create(instanceIdentifier, preferredAspectRatio, fallbackRule);
+
+ assertEquals(instanceManager.getInstance(instanceIdentifier), mockAspectRatioStrategy);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageAnalysisTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageAnalysisTest.java
index 38f77761da99..b9a6d299ae30 100644
--- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageAnalysisTest.java
+++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageAnalysisTest.java
@@ -12,18 +12,16 @@
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.util.Size;
import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
import androidx.test.core.app.ApplicationProvider;
import io.flutter.plugin.common.BinaryMessenger;
-import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionInfo;
import java.util.concurrent.Executor;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -55,27 +53,19 @@ public void hostApiCreate_createsExpectedImageAnalysisInstanceWithExpectedIdenti
new ImageAnalysisHostApiImpl(mockBinaryMessenger, instanceManager);
final CameraXProxy mockCameraXProxy = mock(CameraXProxy.class);
final ImageAnalysis.Builder mockImageAnalysisBuilder = mock(ImageAnalysis.Builder.class);
- final int targetResolutionWidth = 10;
- final int targetResolutionHeight = 50;
- final ResolutionInfo resolutionInfo =
- new ResolutionInfo.Builder()
- .setWidth(Long.valueOf(targetResolutionWidth))
- .setHeight(Long.valueOf(targetResolutionHeight))
- .build();
+ final ResolutionSelector mockResolutionSelector = mock(ResolutionSelector.class);
final long instanceIdentifier = 0;
+ final long mockResolutionSelectorId = 25;
hostApi.cameraXProxy = mockCameraXProxy;
-
- final ArgumentCaptor sizeCaptor = ArgumentCaptor.forClass(Size.class);
+ instanceManager.addDartCreatedInstance(mockResolutionSelector, mockResolutionSelectorId);
when(mockCameraXProxy.createImageAnalysisBuilder()).thenReturn(mockImageAnalysisBuilder);
when(mockImageAnalysisBuilder.build()).thenReturn(mockImageAnalysis);
- hostApi.create(instanceIdentifier, resolutionInfo);
+ hostApi.create(instanceIdentifier, mockResolutionSelectorId);
- verify(mockImageAnalysisBuilder).setTargetResolution(sizeCaptor.capture());
- assertEquals(sizeCaptor.getValue().getWidth(), targetResolutionWidth);
- assertEquals(sizeCaptor.getValue().getHeight(), targetResolutionHeight);
+ verify(mockImageAnalysisBuilder).setResolutionSelector(mockResolutionSelector);
assertEquals(instanceManager.getInstance(instanceIdentifier), mockImageAnalysis);
}
diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java
index 881b6bea5a75..df6c8ee74b7f 100644
--- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java
+++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ImageCaptureTest.java
@@ -4,7 +4,6 @@
package io.flutter.plugins.camerax;
-import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -15,9 +14,9 @@
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.util.Size;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
import io.flutter.plugin.common.BinaryMessenger;
import java.io.File;
import java.io.IOException;
@@ -27,7 +26,6 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.MockitoJUnit;
@@ -66,26 +64,18 @@ public void create_createsImageCaptureWithCorrectConfiguration() {
final ImageCapture.Builder mockImageCaptureBuilder = mock(ImageCapture.Builder.class);
final Long imageCaptureIdentifier = 74L;
final Long flashMode = Long.valueOf(ImageCapture.FLASH_MODE_ON);
- final int targetResolutionWidth = 10;
- final int targetResolutionHeight = 50;
- final GeneratedCameraXLibrary.ResolutionInfo resolutionInfo =
- new GeneratedCameraXLibrary.ResolutionInfo.Builder()
- .setWidth(Long.valueOf(targetResolutionWidth))
- .setHeight(Long.valueOf(targetResolutionHeight))
- .build();
+ final ResolutionSelector mockResolutionSelector = mock(ResolutionSelector.class);
+ final long mockResolutionSelectorId = 77;
imageCaptureHostApiImpl.cameraXProxy = mockCameraXProxy;
+ testInstanceManager.addDartCreatedInstance(mockResolutionSelector, mockResolutionSelectorId);
when(mockCameraXProxy.createImageCaptureBuilder()).thenReturn(mockImageCaptureBuilder);
when(mockImageCaptureBuilder.build()).thenReturn(mockImageCapture);
- final ArgumentCaptor sizeCaptor = ArgumentCaptor.forClass(Size.class);
-
- imageCaptureHostApiImpl.create(imageCaptureIdentifier, flashMode, resolutionInfo);
+ imageCaptureHostApiImpl.create(imageCaptureIdentifier, flashMode, mockResolutionSelectorId);
verify(mockImageCaptureBuilder).setFlashMode(flashMode.intValue());
- verify(mockImageCaptureBuilder).setTargetResolution(sizeCaptor.capture());
- assertEquals(sizeCaptor.getValue().getWidth(), targetResolutionWidth);
- assertEquals(sizeCaptor.getValue().getHeight(), targetResolutionHeight);
+ verify(mockImageCaptureBuilder).setResolutionSelector(mockResolutionSelector);
verify(mockImageCaptureBuilder).build();
verify(testInstanceManager).addDartCreatedInstance(mockImageCapture, imageCaptureIdentifier);
}
diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java
index 39b73abd7381..37a7c7704135 100644
--- a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java
+++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/PreviewTest.java
@@ -18,6 +18,7 @@
import android.view.Surface;
import androidx.camera.core.Preview;
import androidx.camera.core.SurfaceRequest;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
import androidx.core.util.Consumer;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionInfo;
@@ -63,27 +64,20 @@ public void create_createsPreviewWithCorrectConfiguration() {
new PreviewHostApiImpl(mockBinaryMessenger, testInstanceManager, mockTextureRegistry);
final Preview.Builder mockPreviewBuilder = mock(Preview.Builder.class);
final int targetRotation = 90;
- final int targetResolutionWidth = 10;
- final int targetResolutionHeight = 50;
final Long previewIdentifier = 3L;
- final GeneratedCameraXLibrary.ResolutionInfo resolutionInfo =
- new GeneratedCameraXLibrary.ResolutionInfo.Builder()
- .setWidth(Long.valueOf(targetResolutionWidth))
- .setHeight(Long.valueOf(targetResolutionHeight))
- .build();
+ final ResolutionSelector mockResolutionSelector = mock(ResolutionSelector.class);
+ final long mockResolutionSelectorId = 90;
previewHostApi.cameraXProxy = mockCameraXProxy;
+ testInstanceManager.addDartCreatedInstance(mockResolutionSelector, mockResolutionSelectorId);
when(mockCameraXProxy.createPreviewBuilder()).thenReturn(mockPreviewBuilder);
when(mockPreviewBuilder.build()).thenReturn(mockPreview);
- final ArgumentCaptor sizeCaptor = ArgumentCaptor.forClass(Size.class);
-
- previewHostApi.create(previewIdentifier, Long.valueOf(targetRotation), resolutionInfo);
+ previewHostApi.create(
+ previewIdentifier, Long.valueOf(targetRotation), mockResolutionSelectorId);
verify(mockPreviewBuilder).setTargetRotation(targetRotation);
- verify(mockPreviewBuilder).setTargetResolution(sizeCaptor.capture());
- assertEquals(sizeCaptor.getValue().getWidth(), targetResolutionWidth);
- assertEquals(sizeCaptor.getValue().getHeight(), targetResolutionHeight);
+ verify(mockPreviewBuilder).setResolutionSelector(mockResolutionSelector);
verify(mockPreviewBuilder).build();
verify(testInstanceManager).addDartCreatedInstance(mockPreview, previewIdentifier);
}
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
new file mode 100644
index 000000000000..f323e4706c9b
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionSelectorTest.java
@@ -0,0 +1,59 @@
+// 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import androidx.camera.core.resolutionselector.AspectRatioStrategy;
+import androidx.camera.core.resolutionselector.ResolutionSelector;
+import androidx.camera.core.resolutionselector.ResolutionStrategy;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+public class ResolutionSelectorTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+ @Mock public ResolutionSelector mockResolutionSelector;
+ @Mock public ResolutionSelectorHostApiImpl.ResolutionSelectorProxy mockProxy;
+
+ InstanceManager instanceManager;
+
+ @Before
+ public void setUp() {
+ instanceManager = InstanceManager.create(identifier -> {});
+ }
+
+ @After
+ public void tearDown() {
+ instanceManager.stopFinalizationListener();
+ }
+
+ @Test
+ public void hostApiCreate_createsExpectedResolutionSelectorInstance() {
+ final ResolutionStrategy mockResolutionStrategy = mock(ResolutionStrategy.class);
+ final long resolutionStrategyIdentifier = 14;
+ instanceManager.addDartCreatedInstance(mockResolutionStrategy, resolutionStrategyIdentifier);
+
+ final AspectRatioStrategy mockAspectRatioStrategy = mock(AspectRatioStrategy.class);
+ final long aspectRatioStrategyIdentifier = 15;
+ instanceManager.addDartCreatedInstance(mockAspectRatioStrategy, aspectRatioStrategyIdentifier);
+
+ when(mockProxy.create(mockResolutionStrategy, mockAspectRatioStrategy))
+ .thenReturn(mockResolutionSelector);
+ final ResolutionSelectorHostApiImpl hostApi =
+ new ResolutionSelectorHostApiImpl(instanceManager, mockProxy);
+
+ final long instanceIdentifier = 0;
+ hostApi.create(instanceIdentifier, resolutionStrategyIdentifier, aspectRatioStrategyIdentifier);
+
+ assertEquals(instanceManager.getInstance(instanceIdentifier), mockResolutionSelector);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionStrategyTest.java b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionStrategyTest.java
new file mode 100644
index 000000000000..7bbc6152da0c
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/test/java/io/flutter/plugins/camerax/ResolutionStrategyTest.java
@@ -0,0 +1,71 @@
+// 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 static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.util.Size;
+import androidx.camera.core.resolutionselector.ResolutionStrategy;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+public class ResolutionStrategyTest {
+ @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+ @Mock public ResolutionStrategy mockResolutionStrategy;
+ @Mock public ResolutionStrategyHostApiImpl.ResolutionStrategyProxy mockProxy;
+
+ InstanceManager instanceManager;
+
+ @Before
+ public void setUp() {
+ instanceManager = InstanceManager.create(identifier -> {});
+ }
+
+ @After
+ public void tearDown() {
+ instanceManager.stopFinalizationListener();
+ }
+
+ @Test
+ public void hostApiCreate_createsExpectedResolutionStrategyInstanceWhenArgumentsValid() {
+ final GeneratedCameraXLibrary.ResolutionInfo boundSize =
+ new GeneratedCameraXLibrary.ResolutionInfo.Builder().setWidth(50L).setHeight(30L).build();
+
+ final Long fallbackRule = 0L;
+
+ when(mockProxy.create(any(Size.class), eq(fallbackRule))).thenReturn(mockResolutionStrategy);
+
+ final ResolutionStrategyHostApiImpl hostApi =
+ new ResolutionStrategyHostApiImpl(instanceManager, mockProxy);
+
+ final long instanceIdentifier = 0;
+ hostApi.create(instanceIdentifier, boundSize, fallbackRule);
+
+ assertEquals(instanceManager.getInstance(instanceIdentifier), mockResolutionStrategy);
+ }
+
+ @Test
+ public void hostApiCreate_throwsAssertionErrorWhenArgumentsInvalid() {
+ final Long fallbackRule = 8L;
+ final long instanceIdentifier = 0;
+
+ final ResolutionStrategyHostApiImpl hostApi =
+ new ResolutionStrategyHostApiImpl(instanceManager, mockProxy);
+
+ // We expect an exception to be thrown if fallback rule is specified but bound size is not.
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> hostApi.create(instanceIdentifier, null, fallbackRule));
+ }
+}
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 9a58e6f4df86..7c5bf6b37e6e 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
@@ -116,10 +116,6 @@ class AndroidCameraCameraX extends CameraPlatform {
@visibleForTesting
CameraSelector? cameraSelector;
- /// The resolution preset used to create a camera that should be used for
- /// capturing still images and recording video.
- ResolutionPreset? _resolutionPreset;
-
/// The controller we need to broadcast the different camera events.
///
/// It is a `broadcast` because multiple controllers will connect to
@@ -233,19 +229,17 @@ class AndroidCameraCameraX extends CameraPlatform {
processCameraProvider ??= await ProcessCameraProvider.getInstance();
processCameraProvider!.unbindAll();
+ // TODO(camsim99): Implement resolution configuration for UseCases
+ // configured here. https://github.com/flutter/flutter/issues/120462
+
// Configure Preview instance.
- _resolutionPreset = resolutionPreset;
final int targetRotation =
_getTargetRotation(cameraDescription.sensorOrientation);
- final ResolutionInfo? previewTargetResolution =
- _getTargetResolutionForPreview(resolutionPreset);
- preview = createPreview(targetRotation, previewTargetResolution);
+ preview = createPreview(targetRotation);
final int flutterSurfaceTextureId = await preview!.setSurfaceProvider();
// Configure ImageCapture instance.
- final ResolutionInfo? imageCaptureTargetResolution =
- _getTargetResolutionForImageCapture(_resolutionPreset);
- imageCapture = createImageCapture(null, imageCaptureTargetResolution);
+ imageCapture = createImageCapture(null);
// Configure VideoCapture and Recorder instances.
// TODO(gmackall): Enable video capture resolution configuration in createRecorder().
@@ -642,7 +636,7 @@ class AndroidCameraCameraX extends CameraPlatform {
// TODO(camsim99): Support resolution configuration.
// Defaults to YUV_420_888 image format.
- imageAnalysis ??= createImageAnalysis(null);
+ imageAnalysis ??= createImageAnalysis();
unawaited(imageAnalysis!.setAnalyzer(analyzer));
if (await processCameraProvider!.isBound(imageAnalysis!)) {
@@ -780,23 +774,6 @@ class AndroidCameraCameraX extends CameraPlatform {
}
}
- /// Returns [ResolutionInfo] that maps to the specified resolution preset for
- /// a camera preview.
- ResolutionInfo? _getTargetResolutionForPreview(ResolutionPreset? resolution) {
- // TODO(camsim99): Implement resolution configuration.
- // https://github.com/flutter/flutter/issues/120462
- return null;
- }
-
- /// Returns [ResolutionInfo] that maps to the specified resolution preset for
- /// image capture.
- ResolutionInfo? _getTargetResolutionForImageCapture(
- ResolutionPreset? resolution) {
- // TODO(camsim99): Implement resolution configuration.
- // https://github.com/flutter/flutter/issues/120462
- return null;
- }
-
// Methods for calls that need to be tested:
/// Requests camera permissions.
@@ -829,18 +806,15 @@ class AndroidCameraCameraX extends CameraPlatform {
/// Returns a [Preview] configured with the specified target rotation and
/// resolution.
@visibleForTesting
- Preview createPreview(int targetRotation, ResolutionInfo? targetResolution) {
- return Preview(
- targetRotation: targetRotation, targetResolution: targetResolution);
+ Preview createPreview(int targetRotation) {
+ return Preview(targetRotation: targetRotation);
}
/// Returns an [ImageCapture] configured with specified flash mode and
/// target resolution.
@visibleForTesting
- ImageCapture createImageCapture(
- int? flashMode, ResolutionInfo? targetResolution) {
- return ImageCapture(
- targetFlashMode: flashMode, targetResolution: targetResolution);
+ ImageCapture createImageCapture(int? flashMode) {
+ return ImageCapture(targetFlashMode: flashMode);
}
/// Returns a [Recorder] for use in video capture.
@@ -857,7 +831,7 @@ class AndroidCameraCameraX extends CameraPlatform {
/// Returns an [ImageAnalysis] configured with specified target resolution.
@visibleForTesting
- ImageAnalysis createImageAnalysis(ResolutionInfo? targetResolution) {
- return ImageAnalysis(targetResolution: targetResolution);
+ ImageAnalysis createImageAnalysis() {
+ return ImageAnalysis();
}
}
diff --git a/packages/camera/camera_android_camerax/lib/src/aspect_ratio_strategy.dart b/packages/camera/camera_android_camerax/lib/src/aspect_ratio_strategy.dart
new file mode 100644
index 000000000000..621f4ddb2edc
--- /dev/null
+++ b/packages/camera/camera_android_camerax/lib/src/aspect_ratio_strategy.dart
@@ -0,0 +1,138 @@
+// 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';
+
+/// The aspect ratio of a UseCase.
+///
+/// Aspect ratio is the ratio of width to height.
+///
+/// See https://developer.android.com/reference/androidx/camera/core/AspectRatio.
+class AspectRatio {
+ AspectRatio._();
+
+ /// 4:3 standard aspect ratio.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/AspectRatio#RATIO_4_3().
+ static const int ratio4To3 = 0;
+
+ /// 16:9 standard aspect ratio.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/AspectRatio#RATIO_16_9().
+ static const int ratio16To9 = 1;
+
+ /// The aspect ratio representing no preference for aspect ratio.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/AspectRatio#RATIO_DEFAULT().
+ static const int ratioDefault = -1;
+}
+
+/// The aspect ratio strategy defines the sequence of aspect ratios that are
+/// used to select the best size for a particular image.
+///
+/// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/AspectRatioStrategy.
+@immutable
+class AspectRatioStrategy extends JavaObject {
+ /// Construct a [AspectRatioStrategy].
+ AspectRatioStrategy({
+ required this.preferredAspectRatio,
+ required this.fallbackRule,
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _AspectRatioStrategyHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ super.detached() {
+ _api.createFromInstances(this, preferredAspectRatio, fallbackRule);
+ }
+
+ /// Instantiates a [AspectRatioStrategy] without creating and attaching to an
+ /// instance of the associated native class.
+ ///
+ /// This should only be used outside of tests by subclasses created by this
+ /// library or to create a copy for an [InstanceManager].
+ AspectRatioStrategy.detached({
+ required this.preferredAspectRatio,
+ required this.fallbackRule,
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _AspectRatioStrategyHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ super.detached();
+
+ /// CameraX doesn't fall back to select sizes of any other aspect ratio when
+ /// this fallback rule is used.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/AspectRatioStrategy#FALLBACK_RULE_NONE().
+ static const int fallbackRuleNone = 0;
+
+ /// CameraX automatically chooses the next best aspect ratio which contains
+ /// the closest field of view (FOV) of the camera sensor, from the remaining
+ /// options.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/AspectRatioStrategy#FALLBACK_RULE_AUTO().
+ static const int fallbackRuleAuto = 1;
+
+ final _AspectRatioStrategyHostApiImpl _api;
+
+ /// The preferred aspect ratio captured by the camera.
+ final int preferredAspectRatio;
+
+ /// The specified fallback rule for choosing the aspect ratio when the
+ /// preferred aspect ratio is not available.
+ final int fallbackRule;
+}
+
+/// Host API implementation of [AspectRatioStrategy].
+class _AspectRatioStrategyHostApiImpl extends AspectRatioStrategyHostApi {
+ /// Constructs an [_AspectRatioStrategyHostApiImpl].
+ ///
+ /// 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].
+ _AspectRatioStrategyHostApiImpl({
+ 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 [AspectRatioStrategy] on the native side with the preferred
+ /// aspect ratio and fallback rule specified.
+ Future createFromInstances(
+ AspectRatioStrategy instance,
+ int preferredAspectRatio,
+ int fallbackRule,
+ ) {
+ return create(
+ instanceManager.addDartCreatedInstance(
+ instance,
+ onCopy: (AspectRatioStrategy original) => AspectRatioStrategy.detached(
+ preferredAspectRatio: original.preferredAspectRatio,
+ fallbackRule: original.fallbackRule,
+ binaryMessenger: binaryMessenger,
+ instanceManager: instanceManager,
+ ),
+ ),
+ preferredAspectRatio,
+ fallbackRule,
+ );
+ }
+}
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 2a1b2813f1aa..2d1dccf971c2 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
@@ -22,6 +22,22 @@ enum CameraStateType {
pendingOpen,
}
+/// The types (T) properly wrapped to be used as a LiveData.
+///
+/// If you need to add another type to support a type S to use a LiveData in
+/// this plugin, ensure the following is done on the Dart side:
+///
+/// * In `../lib/src/live_data.dart`, add new cases for S in
+/// `_LiveDataHostApiImpl#getValueFromInstances` to get the current value of
+/// type S from a LiveData instance and in `LiveDataFlutterApiImpl#create`
+/// to create the expected type of LiveData when requested.
+///
+/// On the native side, ensure the following is done:
+///
+/// * Update `LiveDataHostApiImpl#getValue` is updated to properly return
+/// identifiers for instances of type S.
+/// * Update `ObserverFlutterApiWrapper#onChanged` to properly handle receiving
+/// calls with instances of type S if a LiveData instance is observed.
enum LiveDataSupportedType {
cameraState,
zoomState,
@@ -937,9 +953,6 @@ class _PreviewHostApiCodec extends StandardMessageCodec {
if (value is ResolutionInfo) {
buffer.putUint8(128);
writeValue(buffer, value.encode());
- } else if (value is ResolutionInfo) {
- buffer.putUint8(129);
- writeValue(buffer, value.encode());
} else {
super.writeValue(buffer, value);
}
@@ -950,8 +963,6 @@ class _PreviewHostApiCodec extends StandardMessageCodec {
switch (type) {
case 128:
return ResolutionInfo.decode(readValue(buffer)!);
- case 129:
- return ResolutionInfo.decode(readValue(buffer)!);
default:
return super.readValueOfType(type, buffer);
}
@@ -969,12 +980,12 @@ class PreviewHostApi {
static const MessageCodec codec = _PreviewHostApiCodec();
Future create(int arg_identifier, int? arg_rotation,
- ResolutionInfo? arg_targetResolution) async {
+ int? arg_resolutionSelectorId) async {
final BasicMessageChannel channel = BasicMessageChannel(
'dev.flutter.pigeon.PreviewHostApi.create', codec,
binaryMessenger: _binaryMessenger);
- final List? replyList = await channel
- .send([arg_identifier, arg_rotation, arg_targetResolution])
+ final List? replyList = await channel.send(
+ [arg_identifier, arg_rotation, arg_resolutionSelectorId])
as List?;
if (replyList == null) {
throw PlatformException(
@@ -1505,8 +1516,92 @@ abstract class RecordingFlutterApi {
}
}
-class _ImageCaptureHostApiCodec extends StandardMessageCodec {
- const _ImageCaptureHostApiCodec();
+class ImageCaptureHostApi {
+ /// Constructor for [ImageCaptureHostApi]. 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.
+ ImageCaptureHostApi({BinaryMessenger? binaryMessenger})
+ : _binaryMessenger = binaryMessenger;
+ final BinaryMessenger? _binaryMessenger;
+
+ static const MessageCodec codec = StandardMessageCodec();
+
+ Future create(int arg_identifier, int? arg_flashMode,
+ int? arg_resolutionSelectorId) async {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.ImageCaptureHostApi.create', codec,
+ binaryMessenger: _binaryMessenger);
+ final List? replyList = await channel.send(
+ [arg_identifier, arg_flashMode, arg_resolutionSelectorId])
+ 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;
+ }
+ }
+
+ Future setFlashMode(int arg_identifier, int arg_flashMode) async {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.ImageCaptureHostApi.setFlashMode', codec,
+ binaryMessenger: _binaryMessenger);
+ final List? replyList = await channel
+ .send([arg_identifier, arg_flashMode]) 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;
+ }
+ }
+
+ Future takePicture(int arg_identifier) async {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.ImageCaptureHostApi.takePicture', codec,
+ binaryMessenger: _binaryMessenger);
+ final List? replyList =
+ await channel.send([arg_identifier]) 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 if (replyList[0] == null) {
+ throw PlatformException(
+ code: 'null-error',
+ message: 'Host platform returned null value for non-null return value.',
+ );
+ } else {
+ return (replyList[0] as String?)!;
+ }
+ }
+}
+
+class _ResolutionStrategyHostApiCodec extends StandardMessageCodec {
+ const _ResolutionStrategyHostApiCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is ResolutionInfo) {
@@ -1528,23 +1623,23 @@ class _ImageCaptureHostApiCodec extends StandardMessageCodec {
}
}
-class ImageCaptureHostApi {
- /// Constructor for [ImageCaptureHostApi]. The [binaryMessenger] named argument is
+class ResolutionStrategyHostApi {
+ /// Constructor for [ResolutionStrategyHostApi]. 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.
- ImageCaptureHostApi({BinaryMessenger? binaryMessenger})
+ ResolutionStrategyHostApi({BinaryMessenger? binaryMessenger})
: _binaryMessenger = binaryMessenger;
final BinaryMessenger? _binaryMessenger;
- static const MessageCodec codec = _ImageCaptureHostApiCodec();
+ static const MessageCodec codec = _ResolutionStrategyHostApiCodec();
- Future create(int arg_identifier, int? arg_flashMode,
- ResolutionInfo? arg_targetResolution) async {
+ Future create(int arg_identifier, ResolutionInfo? arg_boundSize,
+ int? arg_fallbackRule) async {
final BasicMessageChannel channel = BasicMessageChannel(
- 'dev.flutter.pigeon.ImageCaptureHostApi.create', codec,
+ 'dev.flutter.pigeon.ResolutionStrategyHostApi.create', codec,
binaryMessenger: _binaryMessenger);
- final List? replyList = await channel.send(
- [arg_identifier, arg_flashMode, arg_targetResolution])
+ final List? replyList = await channel
+ .send([arg_identifier, arg_boundSize, arg_fallbackRule])
as List?;
if (replyList == null) {
throw PlatformException(
@@ -1561,13 +1656,28 @@ class ImageCaptureHostApi {
return;
}
}
+}
- Future setFlashMode(int arg_identifier, int arg_flashMode) async {
+class ResolutionSelectorHostApi {
+ /// Constructor for [ResolutionSelectorHostApi]. 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.
+ ResolutionSelectorHostApi({BinaryMessenger? binaryMessenger})
+ : _binaryMessenger = binaryMessenger;
+ final BinaryMessenger? _binaryMessenger;
+
+ static const MessageCodec codec = StandardMessageCodec();
+
+ Future create(int arg_identifier, int? arg_resolutionStrategyIdentifier,
+ int? arg_aspectRatioStrategyIdentifier) async {
final BasicMessageChannel channel = BasicMessageChannel(
- 'dev.flutter.pigeon.ImageCaptureHostApi.setFlashMode', codec,
+ 'dev.flutter.pigeon.ResolutionSelectorHostApi.create', codec,
binaryMessenger: _binaryMessenger);
- final List? replyList = await channel
- .send([arg_identifier, arg_flashMode]) as List?;
+ final List? replyList = await channel.send([
+ arg_identifier,
+ arg_resolutionStrategyIdentifier,
+ arg_aspectRatioStrategyIdentifier
+ ]) as List?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
@@ -1583,13 +1693,28 @@ class ImageCaptureHostApi {
return;
}
}
+}
- Future takePicture(int arg_identifier) async {
+class AspectRatioStrategyHostApi {
+ /// Constructor for [AspectRatioStrategyHostApi]. 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.
+ AspectRatioStrategyHostApi({BinaryMessenger? binaryMessenger})
+ : _binaryMessenger = binaryMessenger;
+ final BinaryMessenger? _binaryMessenger;
+
+ static const MessageCodec codec = StandardMessageCodec();
+
+ Future create(int arg_identifier, int arg_preferredAspectRatio,
+ int arg_fallbackRule) async {
final BasicMessageChannel channel = BasicMessageChannel(
- 'dev.flutter.pigeon.ImageCaptureHostApi.takePicture', codec,
+ 'dev.flutter.pigeon.AspectRatioStrategyHostApi.create', codec,
binaryMessenger: _binaryMessenger);
- final List? replyList =
- await channel.send([arg_identifier]) as List?;
+ final List? replyList = await channel.send([
+ arg_identifier,
+ arg_preferredAspectRatio,
+ arg_fallbackRule
+ ]) as List?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
@@ -1601,13 +1726,8 @@ class ImageCaptureHostApi {
message: replyList[1] as String?,
details: replyList[2],
);
- } else if (replyList[0] == null) {
- throw PlatformException(
- code: 'null-error',
- message: 'Host platform returned null value for non-null return value.',
- );
} else {
- return (replyList[0] as String?)!;
+ return;
}
}
}
@@ -1767,29 +1887,6 @@ abstract class ZoomStateFlutterApi {
}
}
-class _ImageAnalysisHostApiCodec extends StandardMessageCodec {
- const _ImageAnalysisHostApiCodec();
- @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 ImageAnalysisHostApi {
/// Constructor for [ImageAnalysisHostApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
@@ -1798,16 +1895,15 @@ class ImageAnalysisHostApi {
: _binaryMessenger = binaryMessenger;
final BinaryMessenger? _binaryMessenger;
- static const MessageCodec codec = _ImageAnalysisHostApiCodec();
+ static const MessageCodec codec = StandardMessageCodec();
- Future create(int arg_identifier,
- ResolutionInfo? arg_targetResolutionIdentifier) async {
+ Future create(int arg_identifier, int? arg_resolutionSelectorId) async {
final BasicMessageChannel channel = BasicMessageChannel(
'dev.flutter.pigeon.ImageAnalysisHostApi.create', codec,
binaryMessenger: _binaryMessenger);
- final List? replyList = await channel
- .send([arg_identifier, arg_targetResolutionIdentifier])
- as List?;
+ final List? replyList =
+ await channel.send([arg_identifier, arg_resolutionSelectorId])
+ as List?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
diff --git a/packages/camera/camera_android_camerax/lib/src/image_analysis.dart b/packages/camera/camera_android_camerax/lib/src/image_analysis.dart
index 4d2a335a3c34..e28457c6d192 100644
--- a/packages/camera/camera_android_camerax/lib/src/image_analysis.dart
+++ b/packages/camera/camera_android_camerax/lib/src/image_analysis.dart
@@ -12,6 +12,7 @@ import 'android_camera_camerax_flutter_api_impls.dart';
import 'camerax_library.g.dart';
import 'instance_manager.dart';
import 'java_object.dart';
+import 'resolution_selector.dart';
import 'use_case.dart';
/// Use case for providing CPU accessible images for performing image analysis.
@@ -23,13 +24,13 @@ class ImageAnalysis extends UseCase {
ImageAnalysis(
{BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
- this.targetResolution})
+ this.resolutionSelector})
: super.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager) {
_api = _ImageAnalysisHostApiImpl(
binaryMessenger: binaryMessenger, instanceManager: instanceManager);
- _api.createfromInstances(this, targetResolution);
+ _api.createfromInstances(this, resolutionSelector);
AndroidCameraXCameraFlutterApis.instance.ensureSetUp();
}
@@ -37,7 +38,7 @@ class ImageAnalysis extends UseCase {
ImageAnalysis.detached(
{BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
- this.targetResolution})
+ this.resolutionSelector})
: super.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager) {
@@ -49,7 +50,10 @@ class ImageAnalysis extends UseCase {
late final _ImageAnalysisHostApiImpl _api;
/// Target resolution of the camera preview stream.
- final ResolutionInfo? targetResolution;
+ ///
+ /// If not set, this [UseCase] will default to the behavior described in:
+ /// https://developer.android.com/reference/androidx/camera/core/ImageAnalysis.Builder#setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector).
+ final ResolutionSelector? resolutionSelector;
/// Sets an [Analyzer] to receive and analyze images.
Future setAnalyzer(Analyzer analyzer) =>
@@ -83,18 +87,20 @@ class _ImageAnalysisHostApiImpl extends ImageAnalysisHostApi {
/// on the native side.
Future createfromInstances(
ImageAnalysis instance,
- ResolutionInfo? targetResolution,
+ ResolutionSelector? resolutionSelector,
) {
return create(
instanceManager.addDartCreatedInstance(
instance,
onCopy: (ImageAnalysis original) => ImageAnalysis.detached(
- targetResolution: original.targetResolution,
+ resolutionSelector: original.resolutionSelector,
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
),
),
- targetResolution,
+ resolutionSelector == null
+ ? null
+ : instanceManager.getIdentifier(resolutionSelector),
);
}
diff --git a/packages/camera/camera_android_camerax/lib/src/image_capture.dart b/packages/camera/camera_android_camerax/lib/src/image_capture.dart
index f7f45d15ffbb..76fd9c4ae5c0 100644
--- a/packages/camera/camera_android_camerax/lib/src/image_capture.dart
+++ b/packages/camera/camera_android_camerax/lib/src/image_capture.dart
@@ -8,6 +8,7 @@ import 'package:meta/meta.dart' show immutable;
import 'camerax_library.g.dart';
import 'instance_manager.dart';
import 'java_object.dart';
+import 'resolution_selector.dart';
import 'use_case.dart';
/// Use case for picture taking.
@@ -20,14 +21,14 @@ class ImageCapture extends UseCase {
BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
this.targetFlashMode,
- this.targetResolution,
+ this.resolutionSelector,
}) : super.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
) {
_api = ImageCaptureHostApiImpl(
binaryMessenger: binaryMessenger, instanceManager: instanceManager);
- _api.createFromInstance(this, targetFlashMode, targetResolution);
+ _api.createFromInstance(this, targetFlashMode, resolutionSelector);
}
/// Constructs a [ImageCapture] that is not automatically attached to a native object.
@@ -35,7 +36,7 @@ class ImageCapture extends UseCase {
BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
this.targetFlashMode,
- this.targetResolution,
+ this.resolutionSelector,
}) : super.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
@@ -50,7 +51,10 @@ class ImageCapture extends UseCase {
final int? targetFlashMode;
/// Target resolution of the image output from taking a picture.
- final ResolutionInfo? targetResolution;
+ ///
+ /// If not set, this [UseCase] will default to the behavior described in:
+ /// https://developer.android.com/reference/androidx/camera/core/ImageCapture.Builder#setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector).
+ final ResolutionSelector? resolutionSelector;
/// Constant for automatic flash mode.
///
@@ -121,16 +125,21 @@ class ImageCaptureHostApiImpl extends ImageCaptureHostApi {
/// Creates an [ImageCapture] instance with the flash mode and target resolution
/// if specified.
void createFromInstance(ImageCapture instance, int? targetFlashMode,
- ResolutionInfo? targetResolution) {
+ ResolutionSelector? resolutionSelector) {
final int identifier = instanceManager.addDartCreatedInstance(instance,
onCopy: (ImageCapture original) {
return ImageCapture.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
targetFlashMode: original.targetFlashMode,
- targetResolution: original.targetResolution);
+ resolutionSelector: original.resolutionSelector);
});
- create(identifier, targetFlashMode, targetResolution);
+ create(
+ identifier,
+ targetFlashMode,
+ resolutionSelector == null
+ ? null
+ : instanceManager.getIdentifier(resolutionSelector));
}
/// Sets the flash mode for the specified [ImageCapture] instance to take
diff --git a/packages/camera/camera_android_camerax/lib/src/preview.dart b/packages/camera/camera_android_camerax/lib/src/preview.dart
index a5307463a58c..f0568078bedb 100644
--- a/packages/camera/camera_android_camerax/lib/src/preview.dart
+++ b/packages/camera/camera_android_camerax/lib/src/preview.dart
@@ -8,6 +8,7 @@ import 'package:meta/meta.dart' show immutable;
import 'camerax_library.g.dart';
import 'instance_manager.dart';
import 'java_object.dart';
+import 'resolution_selector.dart';
import 'use_case.dart';
/// Use case that provides a camera preview stream for display.
@@ -20,13 +21,13 @@ class Preview extends UseCase {
{BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
this.targetRotation,
- this.targetResolution})
+ this.resolutionSelector})
: super.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager) {
_api = PreviewHostApiImpl(
binaryMessenger: binaryMessenger, instanceManager: instanceManager);
- _api.createFromInstance(this, targetRotation, targetResolution);
+ _api.createFromInstance(this, targetRotation, resolutionSelector);
}
/// Constructs a [Preview] that is not automatically attached to a native object.
@@ -34,7 +35,7 @@ class Preview extends UseCase {
{BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
this.targetRotation,
- this.targetResolution})
+ this.resolutionSelector})
: super.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager) {
@@ -48,7 +49,10 @@ class Preview extends UseCase {
final int? targetRotation;
/// Target resolution of the camera preview stream.
- final ResolutionInfo? targetResolution;
+ ///
+ /// If not set, this [UseCase] will default to the behavior described in:
+ /// https://developer.android.com/reference/androidx/camera/core/Preview.Builder#setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector).
+ final ResolutionSelector? resolutionSelector;
/// Sets the surface provider for the preview stream.
///
@@ -92,17 +96,22 @@ class PreviewHostApiImpl extends PreviewHostApi {
/// Creates a [Preview] with the target rotation and target resolution if
/// specified.
- void createFromInstance(
- Preview instance, int? targetRotation, ResolutionInfo? targetResolution) {
+ void createFromInstance(Preview instance, int? targetRotation,
+ ResolutionSelector? resolutionSelector) {
final int identifier = instanceManager.addDartCreatedInstance(instance,
onCopy: (Preview original) {
return Preview.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
targetRotation: original.targetRotation,
- targetResolution: original.targetResolution);
+ resolutionSelector: original.resolutionSelector);
});
- create(identifier, targetRotation, targetResolution);
+ create(
+ identifier,
+ targetRotation,
+ resolutionSelector == null
+ ? null
+ : instanceManager.getIdentifier(resolutionSelector));
}
/// Sets the surface provider of the specified [Preview] instance and returns
diff --git a/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart b/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart
new file mode 100644
index 000000000000..74191724e5ce
--- /dev/null
+++ b/packages/camera/camera_android_camerax/lib/src/resolution_selector.dart
@@ -0,0 +1,108 @@
+// 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 'aspect_ratio_strategy.dart';
+import 'camerax_library.g.dart';
+import 'instance_manager.dart';
+import 'java_object.dart';
+import 'resolution_strategy.dart';
+
+/// A set of requirements and priorities used to select a resolution for a
+/// UseCase.
+///
+/// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionSelector.
+@immutable
+class ResolutionSelector extends JavaObject {
+ /// Construct a [ResolutionSelector].
+ ResolutionSelector({
+ this.resolutionStrategy,
+ this.aspectRatioStrategy,
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _ResolutionSelectorHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ super.detached() {
+ _api.createFromInstances(this, resolutionStrategy, aspectRatioStrategy);
+ }
+
+ /// Instantiates a [ResolutionSelector] without creating and attaching to an
+ /// instance of the associated native class.
+ ///
+ /// This should only be used outside of tests by subclasses created by this
+ /// library or to create a copy for an [InstanceManager].
+ ResolutionSelector.detached({
+ this.resolutionStrategy,
+ this.aspectRatioStrategy,
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _ResolutionSelectorHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ super.detached();
+
+ final _ResolutionSelectorHostApiImpl _api;
+
+ /// Determines how the UseCase will choose the resolution of the captured
+ /// image.
+ final ResolutionStrategy? resolutionStrategy;
+
+ /// Determines how the UseCase will choose the aspect ratio of the captured
+ /// image.
+ final AspectRatioStrategy? aspectRatioStrategy;
+}
+
+/// Host API implementation of [ResolutionSelector].
+class _ResolutionSelectorHostApiImpl extends ResolutionSelectorHostApi {
+ /// Constructs an [_ResolutionSelectorHostApiImpl].
+ ///
+ /// 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].
+ _ResolutionSelectorHostApiImpl({
+ 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 [ResolutionSelector] on the native side with the
+ /// [ResolutionStrategy] and [AspectRatioStrategy] if specified.
+ Future createFromInstances(
+ ResolutionSelector instance,
+ ResolutionStrategy? resolutionStrategy,
+ AspectRatioStrategy? aspectRatioStrategy,
+ ) {
+ return create(
+ instanceManager.addDartCreatedInstance(
+ instance,
+ onCopy: (ResolutionSelector original) => ResolutionSelector.detached(
+ resolutionStrategy: original.resolutionStrategy,
+ aspectRatioStrategy: original.aspectRatioStrategy,
+ binaryMessenger: binaryMessenger,
+ instanceManager: instanceManager,
+ ),
+ ),
+ resolutionStrategy == null
+ ? null
+ : instanceManager.getIdentifier(resolutionStrategy)!,
+ aspectRatioStrategy == null
+ ? null
+ : instanceManager.getIdentifier(aspectRatioStrategy)!,
+ );
+ }
+}
diff --git a/packages/camera/camera_android_camerax/lib/src/resolution_strategy.dart b/packages/camera/camera_android_camerax/lib/src/resolution_strategy.dart
new file mode 100644
index 000000000000..80669f3f8d58
--- /dev/null
+++ b/packages/camera/camera_android_camerax/lib/src/resolution_strategy.dart
@@ -0,0 +1,189 @@
+// 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';
+
+/// The resolution strategy defines the resolution selection sequence to select
+/// the best size.
+///
+/// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy.
+@immutable
+class ResolutionStrategy extends JavaObject {
+ /// Constructs a [ResolutionStrategy].
+ ResolutionStrategy({
+ required Size this.boundSize,
+ this.fallbackRule,
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _ResolutionStrategyHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ super.detached() {
+ _api.createFromInstances(this, boundSize, fallbackRule);
+ }
+
+ /// Constructs a [ResolutionStrategy] that represents the strategy that
+ /// chooses the highest available resolution.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy#HIGHEST_AVAILABLE_STRATEGY().
+ ResolutionStrategy.highestAvailableStrategy({
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _ResolutionStrategyHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ boundSize = null,
+ fallbackRule = null,
+ super.detached() {
+ _api.createFromInstances(this, boundSize, fallbackRule);
+ }
+
+ /// Instantiates a [ResolutionStrategy] without creating and attaching to an
+ /// instance of the associated native class.
+ ///
+ /// This should only be used outside of tests by subclasses created by this
+ /// library or to create a copy for an [InstanceManager].
+ ResolutionStrategy.detached({
+ required this.boundSize,
+ this.fallbackRule,
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _ResolutionStrategyHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ super.detached();
+
+ /// Instantiates a [ResolutionStrategy] that represents the strategy that
+ /// chooses the highest available resolution without creating and attaching to
+ /// an instance of the associated native class.
+ ///
+ /// This should only be used outside of tests by subclasses created by this
+ /// library or to create a copy for an [InstanceManager].
+ ResolutionStrategy.detachedHighestAvailableStrategy({
+ super.binaryMessenger,
+ super.instanceManager,
+ }) : _api = _ResolutionStrategyHostApiImpl(
+ instanceManager: instanceManager,
+ binaryMessenger: binaryMessenger,
+ ),
+ boundSize = null,
+ fallbackRule = null,
+ super.detached();
+
+ /// CameraX doesn't select an alternate size when the specified bound size is
+ /// unavailable.
+ ///
+ /// Applications will receive [PlatformException] when binding the [UseCase]s
+ /// with this fallback rule if the device doesn't support the specified bound
+ /// size.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy#FALLBACK_RULE_NONE().
+ static const int fallbackRuleNone = 0;
+
+ /// When the specified bound size is unavailable, CameraX falls back to select
+ /// the closest higher resolution size.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy#FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER().
+ static const int fallbackRuleClosestHigherThenLower = 1;
+
+ /// When the specified bound size is unavailable, CameraX falls back to the
+ /// closest higher resolution size.
+ ///
+ /// If CameraX still cannot find any available resolution, it will fallback to
+ /// select other lower resolutions.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy#FALLBACK_RULE_CLOSEST_HIGHER().
+ static const int fallbackRuleClosestHigher = 2;
+
+ /// When the specified bound size is unavailable, CameraX falls back to select
+ /// the closest lower resolution size.
+ ///
+ /// If CameraX still cannot find any available resolution, it will fallback to
+ /// select other higher resolutions.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy#FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER().
+ static const int fallbackRuleClosestLowerThenHigher = 3;
+
+ /// When the specified bound size is unavailable, CameraX falls back to the
+ /// closest lower resolution size.
+ ///
+ /// See https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy#FALLBACK_RULE_CLOSEST_LOWER().
+ static const int fallbackRuleClosestLower = 4;
+
+ final _ResolutionStrategyHostApiImpl _api;
+
+ /// The specified bound size for the desired resolution of the camera.
+ ///
+ /// If left null, [fallbackRule] must also be left null in order to create a
+ /// valid [ResolutionStrategy]. This will create the [ResolutionStrategy]
+ /// that chooses the highest available resolution, which can also be retrieved
+ /// by calling [getHighestAvailableStrategy].
+ final Size? boundSize;
+
+ /// The fallback rule for choosing an alternate size when the specified bound
+ /// size is unavailable.
+ ///
+ /// Must be left null if [boundSize] is specified as null. This will create
+ /// the [ResolutionStrategy] that chooses the highest available resolution,
+ /// which can also be retrieved by calling [getHighestAvailableStrategy].
+ final int? fallbackRule;
+}
+
+/// Host API implementation of [ResolutionStrategy].
+class _ResolutionStrategyHostApiImpl extends ResolutionStrategyHostApi {
+ /// Constructs an [_ResolutionStrategyHostApiImpl].
+ ///
+ /// 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].
+ _ResolutionStrategyHostApiImpl({
+ 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 [ResolutionStrategy] on the native side with the bound [Size]
+ /// and fallback rule, if specified.
+ Future createFromInstances(
+ ResolutionStrategy instance,
+ Size? boundSize,
+ int? fallbackRule,
+ ) {
+ return create(
+ instanceManager.addDartCreatedInstance(
+ instance,
+ onCopy: (ResolutionStrategy original) => ResolutionStrategy.detached(
+ boundSize: original.boundSize,
+ fallbackRule: original.fallbackRule,
+ binaryMessenger: binaryMessenger,
+ instanceManager: instanceManager,
+ ),
+ ),
+ boundSize == null
+ ? null
+ : ResolutionInfo(
+ width: boundSize.width.toInt(),
+ height: boundSize.height.toInt(),
+ ),
+ fallbackRule,
+ );
+ }
+}
diff --git a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart
index 601601dbf365..a22d7f6e3514 100644
--- a/packages/camera/camera_android_camerax/pigeons/camerax_library.dart
+++ b/packages/camera/camera_android_camerax/pigeons/camerax_library.dart
@@ -196,7 +196,7 @@ abstract class SystemServicesFlutterApi {
@HostApi(dartHostTestHandler: 'TestPreviewHostApi')
abstract class PreviewHostApi {
- void create(int identifier, int? rotation, ResolutionInfo? targetResolution);
+ void create(int identifier, int? rotation, int? resolutionSelectorId);
int setSurfaceProvider(int identifier);
@@ -261,7 +261,7 @@ abstract class RecordingFlutterApi {
@HostApi(dartHostTestHandler: 'TestImageCaptureHostApi')
abstract class ImageCaptureHostApi {
- void create(int identifier, int? flashMode, ResolutionInfo? targetResolution);
+ void create(int identifier, int? flashMode, int? resolutionSelectorId);
void setFlashMode(int identifier, int flashMode);
@@ -269,6 +269,25 @@ abstract class ImageCaptureHostApi {
String takePicture(int identifier);
}
+@HostApi(dartHostTestHandler: 'TestResolutionStrategyHostApi')
+abstract class ResolutionStrategyHostApi {
+ void create(int identifier, ResolutionInfo? boundSize, int? fallbackRule);
+}
+
+@HostApi(dartHostTestHandler: 'TestResolutionSelectorHostApi')
+abstract class ResolutionSelectorHostApi {
+ void create(
+ int identifier,
+ int? resolutionStrategyIdentifier,
+ int? aspectRatioStrategyIdentifier,
+ );
+}
+
+@HostApi(dartHostTestHandler: 'TestAspectRatioStrategyHostApi')
+abstract class AspectRatioStrategyHostApi {
+ void create(int identifier, int preferredAspectRatio, int fallbackRule);
+}
+
@FlutterApi()
abstract class CameraStateFlutterApi {
void create(int identifier, CameraStateTypeData type, int? errorIdentifier);
@@ -289,7 +308,7 @@ abstract class ZoomStateFlutterApi {
@HostApi(dartHostTestHandler: 'TestImageAnalysisHostApi')
abstract class ImageAnalysisHostApi {
- void create(int identifier, ResolutionInfo? targetResolutionIdentifier);
+ void create(int identifier, int? resolutionSelectorId);
void setAnalyzer(int identifier, int analyzerIdentifier);
diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml
index 0fea9fc68240..f8927d03112b 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.5.0+11
+version: 0.5.0+12
environment:
sdk: ">=2.19.0 <4.0.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 bdebdce095d6..a0e60b60be88 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
@@ -1127,13 +1127,12 @@ class FakeAndroidCameraCameraX extends AndroidCameraCameraX {
}
@override
- Preview createPreview(int targetRotation, ResolutionInfo? targetResolution) {
+ Preview createPreview(int targetRotation) {
return testPreview;
}
@override
- ImageCapture createImageCapture(
- int? flashMode, ResolutionInfo? targetResolution) {
+ ImageCapture createImageCapture(int? flashMode) {
return testImageCapture;
}
@@ -1148,7 +1147,7 @@ class FakeAndroidCameraCameraX extends AndroidCameraCameraX {
}
@override
- ImageAnalysis createImageAnalysis(ResolutionInfo? targetResolution) {
+ ImageAnalysis createImageAnalysis() {
return mockImageAnalysis;
}
}
diff --git a/packages/camera/camera_android_camerax/test/aspect_ratio_strategy_test.dart b/packages/camera/camera_android_camerax/test/aspect_ratio_strategy_test.dart
new file mode 100644
index 000000000000..28ec032a2a9e
--- /dev/null
+++ b/packages/camera/camera_android_camerax/test/aspect_ratio_strategy_test.dart
@@ -0,0 +1,84 @@
+// 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:camera_android_camerax/src/aspect_ratio_strategy.dart';
+import 'package:camera_android_camerax/src/instance_manager.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+
+import 'aspect_ratio_strategy_test.mocks.dart';
+import 'test_camerax_library.g.dart';
+
+@GenerateMocks([
+ TestAspectRatioStrategyHostApi,
+ TestInstanceManagerHostApi,
+])
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ group('AspectRatioStrategy', () {
+ tearDown(() {
+ TestAspectRatioStrategyHostApi.setup(null);
+ TestInstanceManagerHostApi.setup(null);
+ });
+
+ test(
+ 'detached create does not make call to create expected AspectRatioStrategy instance',
+ () async {
+ final MockTestAspectRatioStrategyHostApi mockApi =
+ MockTestAspectRatioStrategyHostApi();
+ TestAspectRatioStrategyHostApi.setup(mockApi);
+
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ const int preferredAspectRatio = 1;
+
+ const int fallbackRule = 1;
+
+ AspectRatioStrategy.detached(
+ preferredAspectRatio: preferredAspectRatio,
+ fallbackRule: fallbackRule,
+ instanceManager: instanceManager,
+ );
+
+ verifyNever(mockApi.create(
+ argThat(isA()),
+ preferredAspectRatio,
+ fallbackRule,
+ ));
+ });
+
+ test(
+ 'HostApi create makes call to create expected AspectRatioStrategy instance',
+ () {
+ final MockTestAspectRatioStrategyHostApi mockApi =
+ MockTestAspectRatioStrategyHostApi();
+ TestAspectRatioStrategyHostApi.setup(mockApi);
+ TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi());
+
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ const int preferredAspectRatio = 0;
+
+ const int fallbackRule = 0;
+
+ final AspectRatioStrategy instance = AspectRatioStrategy(
+ preferredAspectRatio: preferredAspectRatio,
+ fallbackRule: fallbackRule,
+ instanceManager: instanceManager,
+ );
+
+ verify(mockApi.create(
+ instanceManager.getIdentifier(instance),
+ preferredAspectRatio,
+ fallbackRule,
+ ));
+ });
+ });
+}
diff --git a/packages/camera/camera_android_camerax/test/aspect_ratio_strategy_test.mocks.dart b/packages/camera/camera_android_camerax/test/aspect_ratio_strategy_test.mocks.dart
new file mode 100644
index 000000000000..28dda66896e0
--- /dev/null
+++ b/packages/camera/camera_android_camerax/test/aspect_ratio_strategy_test.mocks.dart
@@ -0,0 +1,68 @@
+// Mocks generated by Mockito 5.4.1 from annotations
+// in camera_android_camerax/test/aspect_ratio_strategy_test.dart.
+// Do not manually edit this file.
+
+// @dart=2.19
+
+// ignore_for_file: no_leading_underscores_for_library_prefixes
+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: 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 [TestAspectRatioStrategyHostApi].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockTestAspectRatioStrategyHostApi extends _i1.Mock
+ implements _i2.TestAspectRatioStrategyHostApi {
+ MockTestAspectRatioStrategyHostApi() {
+ _i1.throwOnMissingStub(this);
+ }
+
+ @override
+ void create(
+ int? identifier,
+ int? preferredAspectRatio,
+ int? fallbackRule,
+ ) =>
+ super.noSuchMethod(
+ Invocation.method(
+ #create,
+ [
+ identifier,
+ preferredAspectRatio,
+ fallbackRule,
+ ],
+ ),
+ 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/image_analysis_test.dart b/packages/camera/camera_android_camerax/test/image_analysis_test.dart
index d9c657ea97af..80acd655982e 100644
--- a/packages/camera/camera_android_camerax/test/image_analysis_test.dart
+++ b/packages/camera/camera_android_camerax/test/image_analysis_test.dart
@@ -3,10 +3,10 @@
// found in the LICENSE file.
import 'package:camera_android_camerax/src/analyzer.dart';
-import 'package:camera_android_camerax/src/camerax_library.g.dart';
import 'package:camera_android_camerax/src/image_analysis.dart';
import 'package:camera_android_camerax/src/image_proxy.dart';
import 'package:camera_android_camerax/src/instance_manager.dart';
+import 'package:camera_android_camerax/src/resolution_selector.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
@@ -14,7 +14,11 @@ import 'package:mockito/mockito.dart';
import 'image_analysis_test.mocks.dart';
import 'test_camerax_library.g.dart';
-@GenerateMocks([TestImageAnalysisHostApi, TestInstanceManagerHostApi])
+@GenerateMocks([
+ TestImageAnalysisHostApi,
+ TestInstanceManagerHostApi,
+ ResolutionSelector,
+])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
@@ -22,13 +26,11 @@ void main() {
TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi());
group('ImageAnalysis', () {
- setUp(() {});
-
tearDown(() {
TestImageAnalysisHostApi.setup(null);
});
- test('HostApi create', () {
+ test('create calls create on the Java side', () {
final MockTestImageAnalysisHostApi mockApi =
MockTestImageAnalysisHostApi();
TestImageAnalysisHostApi.setup(mockApi);
@@ -37,25 +39,28 @@ void main() {
onWeakReferenceRemoved: (_) {},
);
- const int targetResolutionWidth = 65;
- const int targetResolutionHeight = 99;
- final ResolutionInfo targetResolution =
- ResolutionInfo(width: 65, height: 99);
+ final MockResolutionSelector mockResolutionSelector =
+ MockResolutionSelector();
+ const int mockResolutionSelectorId = 24;
+
+ instanceManager.addHostCreatedInstance(
+ mockResolutionSelector, mockResolutionSelectorId,
+ onCopy: (ResolutionSelector original) {
+ return MockResolutionSelector();
+ });
+
final ImageAnalysis instance = ImageAnalysis(
- targetResolution: targetResolution,
+ resolutionSelector: mockResolutionSelector,
instanceManager: instanceManager,
);
- final VerificationResult createVerification = verify(mockApi.create(
+ verify(mockApi.create(
argThat(equals(instanceManager.getIdentifier(instance))),
- captureAny));
- final ResolutionInfo capturedResolutionInfo =
- createVerification.captured.single as ResolutionInfo;
- expect(capturedResolutionInfo.width, equals(targetResolutionWidth));
- expect(capturedResolutionInfo.height, equals(targetResolutionHeight));
+ argThat(equals(mockResolutionSelectorId))));
});
- test('setAnalyzer', () async {
+ test('setAnalyzer makes call to set analyzer on ImageAnalysis instance',
+ () async {
final MockTestImageAnalysisHostApi mockApi =
MockTestImageAnalysisHostApi();
TestImageAnalysisHostApi.setup(mockApi);
@@ -65,7 +70,7 @@ void main() {
);
final ImageAnalysis instance = ImageAnalysis.detached(
- targetResolution: ResolutionInfo(width: 75, height: 98),
+ resolutionSelector: MockResolutionSelector(),
instanceManager: instanceManager,
);
const int instanceIdentifier = 0;
@@ -73,7 +78,7 @@ void main() {
instance,
instanceIdentifier,
onCopy: (ImageAnalysis original) => ImageAnalysis.detached(
- targetResolution: original.targetResolution,
+ resolutionSelector: original.resolutionSelector,
instanceManager: instanceManager,
),
);
@@ -102,7 +107,8 @@ void main() {
));
});
- test('clearAnalyzer', () async {
+ test('clearAnalyzer makes call to clear analyzer on ImageAnalysis instance',
+ () async {
final MockTestImageAnalysisHostApi mockApi =
MockTestImageAnalysisHostApi();
TestImageAnalysisHostApi.setup(mockApi);
@@ -112,7 +118,7 @@ void main() {
);
final ImageAnalysis instance = ImageAnalysis.detached(
- targetResolution: ResolutionInfo(width: 75, height: 98),
+ resolutionSelector: MockResolutionSelector(),
instanceManager: instanceManager,
);
const int instanceIdentifier = 0;
@@ -120,7 +126,7 @@ void main() {
instance,
instanceIdentifier,
onCopy: (ImageAnalysis original) => ImageAnalysis.detached(
- targetResolution: original.targetResolution,
+ resolutionSelector: original.resolutionSelector,
instanceManager: instanceManager,
),
);
diff --git a/packages/camera/camera_android_camerax/test/image_analysis_test.mocks.dart b/packages/camera/camera_android_camerax/test/image_analysis_test.mocks.dart
index cbece720c1c2..b0df5790b2c3 100644
--- a/packages/camera/camera_android_camerax/test/image_analysis_test.mocks.dart
+++ b/packages/camera/camera_android_camerax/test/image_analysis_test.mocks.dart
@@ -5,7 +5,7 @@
// @dart=2.19
// ignore_for_file: no_leading_underscores_for_library_prefixes
-import 'package:camera_android_camerax/src/camerax_library.g.dart' as _i3;
+import 'package:camera_android_camerax/src/resolution_selector.dart' as _i3;
import 'package:mockito/mockito.dart' as _i1;
import 'test_camerax_library.g.dart' as _i2;
@@ -33,14 +33,14 @@ class MockTestImageAnalysisHostApi extends _i1.Mock
@override
void create(
int? identifier,
- _i3.ResolutionInfo? targetResolutionIdentifier,
+ int? resolutionSelectorId,
) =>
super.noSuchMethod(
Invocation.method(
#create,
[
identifier,
- targetResolutionIdentifier,
+ resolutionSelectorId,
],
),
returnValueForMissingStub: null,
@@ -88,3 +88,14 @@ class MockTestInstanceManagerHostApi extends _i1.Mock
returnValueForMissingStub: null,
);
}
+
+/// A class which mocks [ResolutionSelector].
+///
+/// See the documentation for Mockito's code generation for more information.
+// ignore: must_be_immutable
+class MockResolutionSelector extends _i1.Mock
+ implements _i3.ResolutionSelector {
+ MockResolutionSelector() {
+ _i1.throwOnMissingStub(this);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/test/image_capture_test.dart b/packages/camera/camera_android_camerax/test/image_capture_test.dart
index 21c071965dc4..c50314ed3cb3 100644
--- a/packages/camera/camera_android_camerax/test/image_capture_test.dart
+++ b/packages/camera/camera_android_camerax/test/image_capture_test.dart
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'package:camera_android_camerax/src/camerax_library.g.dart';
import 'package:camera_android_camerax/src/image_capture.dart';
import 'package:camera_android_camerax/src/instance_manager.dart';
+import 'package:camera_android_camerax/src/resolution_selector.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
@@ -12,7 +12,11 @@ import 'package:mockito/mockito.dart';
import 'image_capture_test.mocks.dart';
import 'test_camerax_library.g.dart';
-@GenerateMocks([TestImageCaptureHostApi, TestInstanceManagerHostApi])
+@GenerateMocks([
+ TestImageCaptureHostApi,
+ TestInstanceManagerHostApi,
+ ResolutionSelector
+])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
@@ -32,11 +36,11 @@ void main() {
ImageCapture.detached(
instanceManager: instanceManager,
targetFlashMode: ImageCapture.flashModeOn,
- targetResolution: ResolutionInfo(width: 50, height: 10),
+ resolutionSelector: MockResolutionSelector(),
);
verifyNever(mockApi.create(argThat(isA()), argThat(isA()),
- argThat(isA())));
+ argThat(isA())));
});
test('create calls create on the Java side', () async {
@@ -47,21 +51,26 @@ void main() {
onWeakReferenceRemoved: (_) {},
);
const int targetFlashMode = ImageCapture.flashModeAuto;
- const int targetResolutionWidth = 10;
- const int targetResolutionHeight = 50;
+ final MockResolutionSelector mockResolutionSelector =
+ MockResolutionSelector();
+ const int mockResolutionSelectorId = 24;
+
+ instanceManager.addHostCreatedInstance(
+ mockResolutionSelector, mockResolutionSelectorId,
+ onCopy: (ResolutionSelector original) {
+ return MockResolutionSelector();
+ });
+
ImageCapture(
instanceManager: instanceManager,
targetFlashMode: targetFlashMode,
- targetResolution: ResolutionInfo(
- width: targetResolutionWidth, height: targetResolutionHeight),
+ resolutionSelector: mockResolutionSelector,
);
- final VerificationResult createVerification = verify(mockApi.create(
- argThat(isA()), argThat(equals(targetFlashMode)), captureAny));
- final ResolutionInfo capturedResolutionInfo =
- createVerification.captured.single as ResolutionInfo;
- expect(capturedResolutionInfo.width, equals(targetResolutionWidth));
- expect(capturedResolutionInfo.height, equals(targetResolutionHeight));
+ verify(mockApi.create(
+ argThat(isA()),
+ argThat(equals(targetFlashMode)),
+ argThat(equals(mockResolutionSelectorId))));
});
test('setFlashMode makes call to set flash mode for ImageCapture instance',
diff --git a/packages/camera/camera_android_camerax/test/image_capture_test.mocks.dart b/packages/camera/camera_android_camerax/test/image_capture_test.mocks.dart
index 1b9e1e777e29..44331c92cff9 100644
--- a/packages/camera/camera_android_camerax/test/image_capture_test.mocks.dart
+++ b/packages/camera/camera_android_camerax/test/image_capture_test.mocks.dart
@@ -5,9 +5,9 @@
// @dart=2.19
// ignore_for_file: no_leading_underscores_for_library_prefixes
-import 'dart:async' as _i4;
+import 'dart:async' as _i3;
-import 'package:camera_android_camerax/src/camerax_library.g.dart' as _i3;
+import 'package:camera_android_camerax/src/resolution_selector.dart' as _i4;
import 'package:mockito/mockito.dart' as _i1;
import 'test_camerax_library.g.dart' as _i2;
@@ -36,7 +36,7 @@ class MockTestImageCaptureHostApi extends _i1.Mock
void create(
int? identifier,
int? flashMode,
- _i3.ResolutionInfo? targetResolution,
+ int? resolutionSelectorId,
) =>
super.noSuchMethod(
Invocation.method(
@@ -44,7 +44,7 @@ class MockTestImageCaptureHostApi extends _i1.Mock
[
identifier,
flashMode,
- targetResolution,
+ resolutionSelectorId,
],
),
returnValueForMissingStub: null,
@@ -65,13 +65,13 @@ class MockTestImageCaptureHostApi extends _i1.Mock
returnValueForMissingStub: null,
);
@override
- _i4.Future takePicture(int? identifier) => (super.noSuchMethod(
+ _i3.Future takePicture(int? identifier) => (super.noSuchMethod(
Invocation.method(
#takePicture,
[identifier],
),
- returnValue: _i4.Future.value(''),
- ) as _i4.Future);
+ returnValue: _i3.Future.value(''),
+ ) as _i3.Future);
}
/// A class which mocks [TestInstanceManagerHostApi].
@@ -92,3 +92,14 @@ class MockTestInstanceManagerHostApi extends _i1.Mock
returnValueForMissingStub: null,
);
}
+
+/// A class which mocks [ResolutionSelector].
+///
+/// See the documentation for Mockito's code generation for more information.
+// ignore: must_be_immutable
+class MockResolutionSelector extends _i1.Mock
+ implements _i4.ResolutionSelector {
+ MockResolutionSelector() {
+ _i1.throwOnMissingStub(this);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/test/preview_test.dart b/packages/camera/camera_android_camerax/test/preview_test.dart
index 6eacd42b5caf..29f862cda4c7 100644
--- a/packages/camera/camera_android_camerax/test/preview_test.dart
+++ b/packages/camera/camera_android_camerax/test/preview_test.dart
@@ -5,6 +5,7 @@
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/preview.dart';
+import 'package:camera_android_camerax/src/resolution_selector.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
@@ -12,7 +13,8 @@ import 'package:mockito/mockito.dart';
import 'preview_test.mocks.dart';
import 'test_camerax_library.g.dart';
-@GenerateMocks([TestInstanceManagerHostApi, TestPreviewHostApi])
+@GenerateMocks(
+ [TestInstanceManagerHostApi, TestPreviewHostApi, ResolutionSelector])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
@@ -32,11 +34,11 @@ void main() {
Preview.detached(
instanceManager: instanceManager,
targetRotation: 90,
- targetResolution: ResolutionInfo(width: 50, height: 10),
+ resolutionSelector: MockResolutionSelector(),
);
verifyNever(mockApi.create(argThat(isA()), argThat(isA()),
- argThat(isA())));
+ argThat(isA())));
});
test('create calls create on the Java side', () async {
@@ -47,21 +49,26 @@ void main() {
onWeakReferenceRemoved: (_) {},
);
const int targetRotation = 90;
- const int targetResolutionWidth = 10;
- const int targetResolutionHeight = 50;
+ final MockResolutionSelector mockResolutionSelector =
+ MockResolutionSelector();
+ const int mockResolutionSelectorId = 24;
+
+ instanceManager.addHostCreatedInstance(
+ mockResolutionSelector, mockResolutionSelectorId,
+ onCopy: (ResolutionSelector original) {
+ return MockResolutionSelector();
+ });
+
Preview(
instanceManager: instanceManager,
targetRotation: targetRotation,
- targetResolution: ResolutionInfo(
- width: targetResolutionWidth, height: targetResolutionHeight),
+ resolutionSelector: mockResolutionSelector,
);
- final VerificationResult createVerification = verify(mockApi.create(
- argThat(isA()), argThat(equals(targetRotation)), captureAny));
- final ResolutionInfo capturedResolutionInfo =
- createVerification.captured.single as ResolutionInfo;
- expect(capturedResolutionInfo.width, equals(targetResolutionWidth));
- expect(capturedResolutionInfo.height, equals(targetResolutionHeight));
+ verify(mockApi.create(
+ argThat(isA()),
+ argThat(equals(targetRotation)),
+ argThat(equals(mockResolutionSelectorId))));
});
test(
diff --git a/packages/camera/camera_android_camerax/test/preview_test.mocks.dart b/packages/camera/camera_android_camerax/test/preview_test.mocks.dart
index ae3783641cec..d56e682ac68e 100644
--- a/packages/camera/camera_android_camerax/test/preview_test.mocks.dart
+++ b/packages/camera/camera_android_camerax/test/preview_test.mocks.dart
@@ -6,6 +6,7 @@
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:camera_android_camerax/src/camerax_library.g.dart' as _i2;
+import 'package:camera_android_camerax/src/resolution_selector.dart' as _i4;
import 'package:mockito/mockito.dart' as _i1;
import 'test_camerax_library.g.dart' as _i3;
@@ -64,7 +65,7 @@ class MockTestPreviewHostApi extends _i1.Mock
void create(
int? identifier,
int? rotation,
- _i2.ResolutionInfo? targetResolution,
+ int? resolutionSelectorId,
) =>
super.noSuchMethod(
Invocation.method(
@@ -72,7 +73,7 @@ class MockTestPreviewHostApi extends _i1.Mock
[
identifier,
rotation,
- targetResolution,
+ resolutionSelectorId,
],
),
returnValueForMissingStub: null,
@@ -108,3 +109,14 @@ class MockTestPreviewHostApi extends _i1.Mock
),
) as _i2.ResolutionInfo);
}
+
+/// A class which mocks [ResolutionSelector].
+///
+/// See the documentation for Mockito's code generation for more information.
+// ignore: must_be_immutable
+class MockResolutionSelector extends _i1.Mock
+ implements _i4.ResolutionSelector {
+ MockResolutionSelector() {
+ _i1.throwOnMissingStub(this);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/test/resolution_selector_test.dart b/packages/camera/camera_android_camerax/test/resolution_selector_test.dart
new file mode 100644
index 000000000000..45ecef576a3a
--- /dev/null
+++ b/packages/camera/camera_android_camerax/test/resolution_selector_test.dart
@@ -0,0 +1,124 @@
+// 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/aspect_ratio_strategy.dart';
+import 'package:camera_android_camerax/src/instance_manager.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';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+
+import 'resolution_selector_test.mocks.dart';
+import 'test_camerax_library.g.dart';
+
+@GenerateMocks([
+ AspectRatioStrategy,
+ ResolutionStrategy,
+ TestResolutionSelectorHostApi,
+ TestInstanceManagerHostApi,
+])
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ group('ResolutionSelector', () {
+ tearDown(() {
+ TestResolutionSelectorHostApi.setup(null);
+ TestInstanceManagerHostApi.setup(null);
+ });
+
+ test(
+ 'detached constructor does not make call to create expected AspectRatioStrategy instance',
+ () async {
+ final MockTestResolutionSelectorHostApi mockApi =
+ MockTestResolutionSelectorHostApi();
+ TestResolutionSelectorHostApi.setup(mockApi);
+ TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi());
+
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ const int preferredAspectRatio = 1;
+
+ const int fallbackRule = 1;
+
+ AspectRatioStrategy.detached(
+ preferredAspectRatio: preferredAspectRatio,
+ fallbackRule: fallbackRule,
+ instanceManager: instanceManager,
+ );
+
+ ResolutionSelector.detached(
+ resolutionStrategy: MockResolutionStrategy(),
+ aspectRatioStrategy: MockAspectRatioStrategy(),
+ instanceManager: instanceManager,
+ );
+
+ verifyNever(mockApi.create(
+ argThat(isA()),
+ argThat(isA()),
+ argThat(isA()),
+ ));
+ });
+
+ test('HostApi create creates expected ResolutionSelector instance', () {
+ final MockTestResolutionSelectorHostApi mockApi =
+ MockTestResolutionSelectorHostApi();
+ TestResolutionSelectorHostApi.setup(mockApi);
+ TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi());
+
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ final ResolutionStrategy resolutionStrategy = ResolutionStrategy.detached(
+ boundSize: const Size(50, 30),
+ fallbackRule: ResolutionStrategy.fallbackRuleClosestLower,
+ instanceManager: instanceManager,
+ );
+ const int resolutionStrategyIdentifier = 14;
+ instanceManager.addHostCreatedInstance(
+ resolutionStrategy,
+ resolutionStrategyIdentifier,
+ onCopy: (ResolutionStrategy original) => ResolutionStrategy.detached(
+ boundSize: original.boundSize,
+ fallbackRule: original.fallbackRule,
+ instanceManager: instanceManager,
+ ),
+ );
+
+ final AspectRatioStrategy aspectRatioStrategy =
+ AspectRatioStrategy.detached(
+ preferredAspectRatio: AspectRatio.ratio4To3,
+ fallbackRule: AspectRatioStrategy.fallbackRuleAuto,
+ instanceManager: instanceManager,
+ );
+ const int aspectRatioStrategyIdentifier = 15;
+ instanceManager.addHostCreatedInstance(
+ aspectRatioStrategy,
+ aspectRatioStrategyIdentifier,
+ onCopy: (AspectRatioStrategy original) => AspectRatioStrategy.detached(
+ preferredAspectRatio: original.preferredAspectRatio,
+ fallbackRule: original.fallbackRule,
+ instanceManager: instanceManager,
+ ),
+ );
+
+ final ResolutionSelector instance = ResolutionSelector(
+ resolutionStrategy: resolutionStrategy,
+ aspectRatioStrategy: aspectRatioStrategy,
+ instanceManager: instanceManager,
+ );
+
+ verify(mockApi.create(
+ instanceManager.getIdentifier(instance),
+ resolutionStrategyIdentifier,
+ 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
new file mode 100644
index 000000000000..6ab8de8316d9
--- /dev/null
+++ b/packages/camera/camera_android_camerax/test/resolution_selector_test.mocks.dart
@@ -0,0 +1,103 @@
+// Mocks generated by Mockito 5.4.1 from annotations
+// in camera_android_camerax/test/resolution_selector_test.dart.
+// Do not manually edit this file.
+
+// @dart=2.19
+
+// 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 'package:mockito/mockito.dart' as _i1;
+
+import 'test_camerax_library.g.dart' as _i4;
+
+// 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: 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 [AspectRatioStrategy].
+///
+/// See the documentation for Mockito's code generation for more information.
+// ignore: must_be_immutable
+class MockAspectRatioStrategy extends _i1.Mock
+ implements _i2.AspectRatioStrategy {
+ MockAspectRatioStrategy() {
+ _i1.throwOnMissingStub(this);
+ }
+
+ @override
+ int get preferredAspectRatio => (super.noSuchMethod(
+ Invocation.getter(#preferredAspectRatio),
+ returnValue: 0,
+ ) as int);
+ @override
+ int get fallbackRule => (super.noSuchMethod(
+ Invocation.getter(#fallbackRule),
+ returnValue: 0,
+ ) as int);
+}
+
+/// 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 {
+ MockResolutionStrategy() {
+ _i1.throwOnMissingStub(this);
+ }
+}
+
+/// A class which mocks [TestResolutionSelectorHostApi].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockTestResolutionSelectorHostApi extends _i1.Mock
+ implements _i4.TestResolutionSelectorHostApi {
+ MockTestResolutionSelectorHostApi() {
+ _i1.throwOnMissingStub(this);
+ }
+
+ @override
+ void create(
+ int? identifier,
+ int? resolutionStrategyIdentifier,
+ int? aspectRatioStrategyIdentifier,
+ ) =>
+ super.noSuchMethod(
+ Invocation.method(
+ #create,
+ [
+ identifier,
+ resolutionStrategyIdentifier,
+ aspectRatioStrategyIdentifier,
+ ],
+ ),
+ returnValueForMissingStub: null,
+ );
+}
+
+/// A class which mocks [TestInstanceManagerHostApi].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockTestInstanceManagerHostApi extends _i1.Mock
+ implements _i4.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_strategy_test.dart b/packages/camera/camera_android_camerax/test/resolution_strategy_test.dart
new file mode 100644
index 000000000000..9c098b946075
--- /dev/null
+++ b/packages/camera/camera_android_camerax/test/resolution_strategy_test.dart
@@ -0,0 +1,109 @@
+// 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_strategy.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+
+import 'resolution_strategy_test.mocks.dart';
+import 'test_camerax_library.g.dart';
+
+@GenerateMocks([
+ TestResolutionStrategyHostApi,
+ TestInstanceManagerHostApi,
+])
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ group('ResolutionStrategy', () {
+ tearDown(() {
+ TestResolutionStrategyHostApi.setup(null);
+ TestInstanceManagerHostApi.setup(null);
+ });
+
+ test(
+ 'detached resolutionStrategy constructors do not make call to Host API create',
+ () {
+ final MockTestResolutionStrategyHostApi mockApi =
+ MockTestResolutionStrategyHostApi();
+ TestResolutionStrategyHostApi.setup(mockApi);
+ TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi());
+
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ const Size boundSize = Size(70, 20);
+ const int fallbackRule = 1;
+
+ ResolutionStrategy.detached(
+ boundSize: boundSize,
+ fallbackRule: fallbackRule,
+ instanceManager: instanceManager,
+ );
+
+ verifyNever(mockApi.create(
+ argThat(isA()),
+ argThat(isA()
+ .having((ResolutionInfo size) => size.width, 'width', 50)
+ .having((ResolutionInfo size) => size.height, 'height', 30)),
+ fallbackRule,
+ ));
+
+ ResolutionStrategy.detachedHighestAvailableStrategy(
+ instanceManager: instanceManager,
+ );
+
+ verifyNever(mockApi.create(
+ argThat(isA()),
+ null,
+ null,
+ ));
+ });
+
+ test('HostApi create creates expected ResolutionStrategies', () {
+ final MockTestResolutionStrategyHostApi mockApi =
+ MockTestResolutionStrategyHostApi();
+ TestResolutionStrategyHostApi.setup(mockApi);
+ TestInstanceManagerHostApi.setup(MockTestInstanceManagerHostApi());
+
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ const Size boundSize = Size(50, 30);
+ const int fallbackRule = 0;
+
+ final ResolutionStrategy instance = ResolutionStrategy(
+ boundSize: boundSize,
+ fallbackRule: fallbackRule,
+ instanceManager: instanceManager,
+ );
+
+ verify(mockApi.create(
+ instanceManager.getIdentifier(instance),
+ argThat(isA()
+ .having((ResolutionInfo size) => size.width, 'width', 50)
+ .having((ResolutionInfo size) => size.height, 'height', 30)),
+ fallbackRule,
+ ));
+
+ final ResolutionStrategy highestAvailableInstance =
+ ResolutionStrategy.highestAvailableStrategy(
+ instanceManager: instanceManager,
+ );
+
+ verify(mockApi.create(
+ instanceManager.getIdentifier(highestAvailableInstance),
+ null,
+ null,
+ ));
+ });
+ });
+}
diff --git a/packages/camera/camera_android_camerax/test/resolution_strategy_test.mocks.dart b/packages/camera/camera_android_camerax/test/resolution_strategy_test.mocks.dart
new file mode 100644
index 000000000000..1a667389bac0
--- /dev/null
+++ b/packages/camera/camera_android_camerax/test/resolution_strategy_test.mocks.dart
@@ -0,0 +1,69 @@
+// Mocks generated by Mockito 5.4.1 from annotations
+// in camera_android_camerax/test/resolution_strategy_test.dart.
+// Do not manually edit this file.
+
+// @dart=2.19
+
+// 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: 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 [TestResolutionStrategyHostApi].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockTestResolutionStrategyHostApi extends _i1.Mock
+ implements _i2.TestResolutionStrategyHostApi {
+ MockTestResolutionStrategyHostApi() {
+ _i1.throwOnMissingStub(this);
+ }
+
+ @override
+ void create(
+ int? identifier,
+ _i3.ResolutionInfo? boundSize,
+ int? fallbackRule,
+ ) =>
+ super.noSuchMethod(
+ Invocation.method(
+ #create,
+ [
+ identifier,
+ boundSize,
+ fallbackRule,
+ ],
+ ),
+ 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/test_camerax_library.g.dart b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart
index 2c4afd19b26b..6a80cf0541fb 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
@@ -597,9 +597,6 @@ class _TestPreviewHostApiCodec extends StandardMessageCodec {
if (value is ResolutionInfo) {
buffer.putUint8(128);
writeValue(buffer, value.encode());
- } else if (value is ResolutionInfo) {
- buffer.putUint8(129);
- writeValue(buffer, value.encode());
} else {
super.writeValue(buffer, value);
}
@@ -610,8 +607,6 @@ class _TestPreviewHostApiCodec extends StandardMessageCodec {
switch (type) {
case 128:
return ResolutionInfo.decode(readValue(buffer)!);
- case 129:
- return ResolutionInfo.decode(readValue(buffer)!);
default:
return super.readValueOfType(type, buffer);
}
@@ -623,7 +618,7 @@ abstract class TestPreviewHostApi {
TestDefaultBinaryMessengerBinding.instance;
static const MessageCodec codec = _TestPreviewHostApiCodec();
- void create(int identifier, int? rotation, ResolutionInfo? targetResolution);
+ void create(int identifier, int? rotation, int? resolutionSelectorId);
int setSurfaceProvider(int identifier);
@@ -651,9 +646,8 @@ abstract class TestPreviewHostApi {
assert(arg_identifier != null,
'Argument for dev.flutter.pigeon.PreviewHostApi.create was null, expected non-null int.');
final int? arg_rotation = (args[1] as int?);
- final ResolutionInfo? arg_targetResolution =
- (args[2] as ResolutionInfo?);
- api.create(arg_identifier!, arg_rotation, arg_targetResolution);
+ final int? arg_resolutionSelectorId = (args[2] as int?);
+ api.create(arg_identifier!, arg_rotation, arg_resolutionSelectorId);
return [];
});
}
@@ -1033,35 +1027,12 @@ abstract class TestRecordingHostApi {
}
}
-class _TestImageCaptureHostApiCodec extends StandardMessageCodec {
- const _TestImageCaptureHostApiCodec();
- @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 TestImageCaptureHostApi {
static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
TestDefaultBinaryMessengerBinding.instance;
- static const MessageCodec codec = _TestImageCaptureHostApiCodec();
+ static const MessageCodec codec = StandardMessageCodec();
- void create(int identifier, int? flashMode, ResolutionInfo? targetResolution);
+ void create(int identifier, int? flashMode, int? resolutionSelectorId);
void setFlashMode(int identifier, int flashMode);
@@ -1087,9 +1058,8 @@ abstract class TestImageCaptureHostApi {
assert(arg_identifier != null,
'Argument for dev.flutter.pigeon.ImageCaptureHostApi.create was null, expected non-null int.');
final int? arg_flashMode = (args[1] as int?);
- final ResolutionInfo? arg_targetResolution =
- (args[2] as ResolutionInfo?);
- api.create(arg_identifier!, arg_flashMode, arg_targetResolution);
+ final int? arg_resolutionSelectorId = (args[2] as int?);
+ api.create(arg_identifier!, arg_flashMode, arg_resolutionSelectorId);
return [];
});
}
@@ -1144,8 +1114,8 @@ abstract class TestImageCaptureHostApi {
}
}
-class _TestImageAnalysisHostApiCodec extends StandardMessageCodec {
- const _TestImageAnalysisHostApiCodec();
+class _TestResolutionStrategyHostApiCodec extends StandardMessageCodec {
+ const _TestResolutionStrategyHostApiCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is ResolutionInfo) {
@@ -1167,12 +1137,128 @@ class _TestImageAnalysisHostApiCodec extends StandardMessageCodec {
}
}
+abstract class TestResolutionStrategyHostApi {
+ static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
+ TestDefaultBinaryMessengerBinding.instance;
+ static const MessageCodec codec =
+ _TestResolutionStrategyHostApiCodec();
+
+ void create(int identifier, ResolutionInfo? boundSize, int? fallbackRule);
+
+ static void setup(TestResolutionStrategyHostApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.ResolutionStrategyHostApi.create', 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.ResolutionStrategyHostApi.create 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.ResolutionStrategyHostApi.create was null, expected non-null int.');
+ final ResolutionInfo? arg_boundSize = (args[1] as ResolutionInfo?);
+ final int? arg_fallbackRule = (args[2] as int?);
+ api.create(arg_identifier!, arg_boundSize, arg_fallbackRule);
+ return [];
+ });
+ }
+ }
+ }
+}
+
+abstract class TestResolutionSelectorHostApi {
+ static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
+ TestDefaultBinaryMessengerBinding.instance;
+ static const MessageCodec codec = StandardMessageCodec();
+
+ void create(int identifier, int? resolutionStrategyIdentifier,
+ int? aspectRatioStrategyIdentifier);
+
+ static void setup(TestResolutionSelectorHostApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.ResolutionSelectorHostApi.create', 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.ResolutionSelectorHostApi.create 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.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,
+ arg_aspectRatioStrategyIdentifier);
+ return [];
+ });
+ }
+ }
+ }
+}
+
+abstract class TestAspectRatioStrategyHostApi {
+ static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
+ TestDefaultBinaryMessengerBinding.instance;
+ static const MessageCodec codec = StandardMessageCodec();
+
+ void create(int identifier, int preferredAspectRatio, int fallbackRule);
+
+ static void setup(TestAspectRatioStrategyHostApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.AspectRatioStrategyHostApi.create', 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.AspectRatioStrategyHostApi.create 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.AspectRatioStrategyHostApi.create was null, expected non-null int.');
+ final int? arg_preferredAspectRatio = (args[1] as int?);
+ assert(arg_preferredAspectRatio != null,
+ 'Argument for dev.flutter.pigeon.AspectRatioStrategyHostApi.create was null, expected non-null int.');
+ final int? arg_fallbackRule = (args[2] as int?);
+ assert(arg_fallbackRule != null,
+ 'Argument for dev.flutter.pigeon.AspectRatioStrategyHostApi.create was null, expected non-null int.');
+ api.create(
+ arg_identifier!, arg_preferredAspectRatio!, arg_fallbackRule!);
+ return [];
+ });
+ }
+ }
+ }
+}
+
abstract class TestImageAnalysisHostApi {
static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
TestDefaultBinaryMessengerBinding.instance;
- static const MessageCodec codec = _TestImageAnalysisHostApiCodec();
+ static const MessageCodec codec = StandardMessageCodec();
- void create(int identifier, ResolutionInfo? targetResolutionIdentifier);
+ void create(int identifier, int? resolutionSelectorId);
void setAnalyzer(int identifier, int analyzerIdentifier);
@@ -1197,9 +1283,8 @@ abstract class TestImageAnalysisHostApi {
final int? arg_identifier = (args[0] as int?);
assert(arg_identifier != null,
'Argument for dev.flutter.pigeon.ImageAnalysisHostApi.create was null, expected non-null int.');
- final ResolutionInfo? arg_targetResolutionIdentifier =
- (args[1] as ResolutionInfo?);
- api.create(arg_identifier!, arg_targetResolutionIdentifier);
+ final int? arg_resolutionSelectorId = (args[1] as int?);
+ api.create(arg_identifier!, arg_resolutionSelectorId);
return [];
});
}