Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/camera/camera_android_camerax/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.6.20

* Fixes pausing and resuming the camera preview.
* Updates minimum supported SDK version to Flutter 3.32.8/Dart 3.8.1.

## 0.6.19+1

* Fixes incorrect camera switching by selecting a camera via its CameraInfo.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public void onSurfaceCleanup() {
// Provide surface.
surfaceProducer.setSize(
request.getResolution().getWidth(), request.getResolution().getHeight());
Surface flutterSurface = surfaceProducer.getSurface();
Surface flutterSurface = surfaceProducer.getForcedNewSurface();
request.provideSurface(
flutterSurface,
Executors.newSingleThreadExecutor(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ TextureRegistry getTextureRegistry() {
ArgumentCaptor.forClass(TextureRegistry.SurfaceProducer.Callback.class);

when(mockSurfaceRequest.getResolution()).thenReturn(new Size(5, 6));
when(mockSurfaceProducer.getSurface()).thenReturn(mock(Surface.class));
when(mockSurfaceProducer.getForcedNewSurface()).thenReturn(mock(Surface.class));

final Preview.SurfaceProvider previewSurfaceProvider =
api.createSurfaceProvider(mockSurfaceProducer, mockSystemServicesManager);
Expand Down Expand Up @@ -155,7 +155,7 @@ TextureRegistry getTextureRegistry() {

when(mockSurfaceRequest.getResolution())
.thenReturn(new Size(resolutionWidth, resolutionHeight));
when(mockSurfaceProducer.getSurface()).thenReturn(mockSurface);
when(mockSurfaceProducer.getForcedNewSurface()).thenReturn(mockSurface);

final ArgumentCaptor<Surface> surfaceCaptor = ArgumentCaptor.forClass(Surface.class);
final ArgumentCaptor<Consumer<SurfaceRequest.Result>> consumerCaptor =
Expand Down
Copy link
Contributor Author

@camsim99 camsim99 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File just reformatted due to Flutter/Dart bump.

Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,14 @@ class AndroidCameraCameraX extends CameraPlatform {
// Determine the lens direction by filtering the CameraInfo
// TODO(gmackall): replace this with call to CameraInfo.getLensFacing when changes containing that method are available
if ((await proxy
.newCameraSelector(requireLensFacing: LensFacing.back)
.filter(<CameraInfo>[cameraInfo])).isNotEmpty) {
.newCameraSelector(requireLensFacing: LensFacing.back)
.filter(<CameraInfo>[cameraInfo]))
.isNotEmpty) {
cameraLensDirection = CameraLensDirection.back;
} else if ((await proxy
.newCameraSelector(requireLensFacing: LensFacing.front)
.filter(<CameraInfo>[cameraInfo])).isNotEmpty) {
.newCameraSelector(requireLensFacing: LensFacing.front)
.filter(<CameraInfo>[cameraInfo]))
.isNotEmpty) {
cameraLensDirection = CameraLensDirection.front;
} else {
//Skip this CameraInfo as its lens direction is unknown
Expand Down Expand Up @@ -439,13 +441,13 @@ class AndroidCameraCameraX extends CameraPlatform {
.toDouble();

sensorOrientationDegrees = cameraDescription.sensorOrientation.toDouble();
_handlesCropAndRotation =
await preview!.surfaceProducerHandlesCropAndRotation();
_handlesCropAndRotation = await preview!
.surfaceProducerHandlesCropAndRotation();
_initialDeviceOrientation = _deserializeDeviceOrientation(
await deviceOrientationManager.getUiOrientation(),
);
_initialDefaultDisplayRotation =
await deviceOrientationManager.getDefaultDisplayRotation();
_initialDefaultDisplayRotation = await deviceOrientationManager
.getDefaultDisplayRotation();

return flutterSurfaceTextureId;
}
Expand Down Expand Up @@ -476,8 +478,8 @@ class AndroidCameraCameraX extends CameraPlatform {
);
}

final ResolutionInfo previewResolutionInfo =
(await preview!.getResolutionInfo())!;
final ResolutionInfo previewResolutionInfo = (await preview!
.getResolutionInfo())!;

// Mark auto-focus, auto-exposure and setting points for focus & exposure
// as available operations as CameraX does its best across devices to
Expand Down Expand Up @@ -647,10 +649,9 @@ class AndroidCameraCameraX extends CameraPlatform {
case FocusMode.auto:
// Determine auto-focus point to restore, if any. We do not restore
// default auto-focus point if set previously to lock focus.
final MeteringPoint? unLockedFocusPoint =
_defaultFocusPointLocked
? null
: currentFocusMeteringAction!.meteringPointsAf.first;
final MeteringPoint? unLockedFocusPoint = _defaultFocusPointLocked
? null
: currentFocusMeteringAction!.meteringPointsAf.first;
_defaultFocusPointLocked = false;
autoFocusPoint = unLockedFocusPoint;
disableAutoCancel = false;
Expand All @@ -661,10 +662,9 @@ class AndroidCameraCameraX extends CameraPlatform {
if (currentFocusMeteringAction != null) {
final List<MeteringPoint> possibleCurrentAfPoints =
currentFocusMeteringAction!.meteringPointsAf;
lockedFocusPoint =
possibleCurrentAfPoints.isEmpty
? null
: possibleCurrentAfPoints.first;
lockedFocusPoint = possibleCurrentAfPoints.isEmpty
? null
: possibleCurrentAfPoints.first;
}

// If there isn't, lock center of entire sensor area by default.
Expand Down Expand Up @@ -1494,13 +1494,12 @@ class AndroidCameraCameraX extends CameraPlatform {
);
final ResolutionFilter resolutionFilter = proxy
.createWithOnePreferredSizeResolutionFilter(preferredSize: boundSize);
final AspectRatioStrategy? aspectRatioStrategy =
aspectRatio == null
? null
: proxy.newAspectRatioStrategy(
preferredAspectRatio: aspectRatio,
fallbackRule: AspectRatioStrategyFallbackRule.auto,
);
final AspectRatioStrategy? aspectRatioStrategy = aspectRatio == null
? null
: proxy.newAspectRatioStrategy(
preferredAspectRatio: aspectRatio,
fallbackRule: AspectRatioStrategyFallbackRule.auto,
);
return proxy.newResolutionSelector(
resolutionStrategy: resolutionStrategy,
resolutionFilter: resolutionFilter,
Expand Down Expand Up @@ -1617,17 +1616,17 @@ class AndroidCameraCameraX extends CameraPlatform {
// Remove metering point with specified meteringMode from current focus
// and metering action, as only one focus or exposure point may be set
// at once in this plugin.
final List<(MeteringPoint, MeteringMode)> newMeteringPointInfos =
originalMeteringPoints
.where(
((MeteringPoint, MeteringMode) meteringPointInfo) =>
// meteringPointInfo may technically include points without a
// mode specified, but this logic is safe because this plugin
// only uses points that explicitly have mode
// FocusMeteringAction.flagAe or FocusMeteringAction.flagAf.
meteringPointInfo.$2 != meteringMode,
)
.toList();
final List<(MeteringPoint, MeteringMode)>
newMeteringPointInfos = originalMeteringPoints
.where(
((MeteringPoint, MeteringMode) meteringPointInfo) =>
// meteringPointInfo may technically include points without a
// mode specified, but this logic is safe because this plugin
// only uses points that explicitly have mode
// FocusMeteringAction.flagAe or FocusMeteringAction.flagAf.
meteringPointInfo.$2 != meteringMode,
)
.toList();

if (newMeteringPointInfos.isEmpty) {
// If no other metering points were specified, cancel any previously
Expand Down Expand Up @@ -1664,17 +1663,16 @@ class AndroidCameraCameraX extends CameraPlatform {
final Iterable<(MeteringPoint, MeteringMode)> originalMeteringPoints =
_combineMeteringPoints(currentFocusMeteringAction!);

newMeteringPointInfos =
originalMeteringPoints
.where(
((MeteringPoint, MeteringMode) meteringPointInfo) =>
// meteringPointInfo may technically include points without a
// mode specified, but this logic is safe because this plugin
// only uses points that explicitly have mode
// FocusMeteringAction.flagAe or FocusMeteringAction.flagAf.
meteringPointInfo.$2 != meteringMode,
)
.toList();
newMeteringPointInfos = originalMeteringPoints
.where(
((MeteringPoint, MeteringMode) meteringPointInfo) =>
// meteringPointInfo may technically include points without a
// mode specified, but this logic is safe because this plugin
// only uses points that explicitly have mode
// FocusMeteringAction.flagAe or FocusMeteringAction.flagAf.
meteringPointInfo.$2 != meteringMode,
)
.toList();
}

newMeteringPointInfos.add((meteringPoint, meteringMode));
Expand Down
Copy link
Contributor Author

@camsim99 camsim99 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File just reformatted due to Flutter/Dart bump.

Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,15 @@ void setUpGenerics({
);

camerax.CameraInfo.pigeon_setUpMessageHandlers(
pigeon_newInstance: (
int sensorRotationDegrees,
camerax.ExposureState exposureState,
) {
return CameraInfo.detached(
sensorRotationDegrees: sensorRotationDegrees,
exposureState: exposureState,
pigeon_binaryMessenger: pigeonBinaryMessenger,
pigeon_instanceManager: pigeonInstanceManager,
);
},
pigeon_newInstance:
(int sensorRotationDegrees, camerax.ExposureState exposureState) {
return CameraInfo.detached(
sensorRotationDegrees: sensorRotationDegrees,
exposureState: exposureState,
pigeon_binaryMessenger: pigeonBinaryMessenger,
pigeon_instanceManager: pigeonInstanceManager,
);
},
);
}

Expand Down
Copy link
Contributor Author

@camsim99 camsim99 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File just reformatted due to Flutter/Dart bump.

Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ class PigeonInstanceManager {
final PigeonInternalProxyApiBaseClass? strongInstance =
_strongInstances[identifier];
if (strongInstance != null) {
final PigeonInternalProxyApiBaseClass copy =
strongInstance.pigeon_copy();
final PigeonInternalProxyApiBaseClass copy = strongInstance
.pigeon_copy();
_identifiers[copy] = identifier;
_weakInstances[identifier] =
WeakReference<PigeonInternalProxyApiBaseClass>(copy);
Expand Down
Copy link
Contributor Author

@camsim99 camsim99 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File just reformatted due to Flutter/Dart bump.

Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ final class _ImageReaderRotatedPreviewState
late StreamSubscription<DeviceOrientation> deviceOrientationSubscription;

Future<int> _getCurrentDefaultDisplayRotationDegrees() async {
final int currentDefaultDisplayRotationQuarterTurns =
await widget.deviceOrientationManager.getDefaultDisplayRotation();
final int currentDefaultDisplayRotationQuarterTurns = await widget
.deviceOrientationManager
.getDefaultDisplayRotation();
return getQuarterTurnsFromSurfaceRotationConstant(
currentDefaultDisplayRotationQuarterTurns,
) *
Expand Down
Copy link
Contributor Author

@camsim99 camsim99 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File just reformatted due to Flutter/Dart bump.

Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ int getQuarterTurnsFromSurfaceRotationConstant(int surfaceRotationConstant) {
Surface.rotation90 => 3,
Surface.rotation180 => 2,
Surface.rotation270 => 1,
int() =>
throw ArgumentError(
'$surfaceRotationConstant is an unknown Surface rotation constant, so counter-clockwise quarter turns cannot be determined.',
),
int() => throw ArgumentError(
'$surfaceRotationConstant is an unknown Surface rotation constant, so counter-clockwise quarter turns cannot be determined.',
),
};
}

Expand Down
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File just reformatted due to Flutter/Dart bump.

Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ final class _SurfaceTextureRotatedPreviewState
late Future<int> defaultDisplayRotationQuarterTurns;

Future<int> _getCurrentDefaultDisplayRotationQuarterTurns() async {
final int currentDefaultDisplayRotationQuarterTurns =
await widget.deviceOrientationManager.getDefaultDisplayRotation();
final int currentDefaultDisplayRotationQuarterTurns = await widget
.deviceOrientationManager
.getDefaultDisplayRotation();
return getQuarterTurnsFromSurfaceRotationConstant(
currentDefaultDisplayRotationQuarterTurns,
);
Expand Down
6 changes: 3 additions & 3 deletions packages/camera/camera_android_camerax/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: camera_android_camerax
description: Android implementation of the camera plugin using the CameraX library.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.6.19+1
version: 0.6.20

environment:
sdk: ^3.7.0
flutter: ">=3.29.0"
sdk: ^3.8.1
flutter: ">=3.32.8"

flutter:
plugin:
Expand Down
Loading