diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 63e8e56144c..c64efc82427 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,7 +1,8 @@ -## NEXT +## 0.6.12 * Suppresses deprecation and removal warnings for `TextureRegistry.SurfaceProducer.onSurfaceDestroyed`. +* Removes logic added to correct the rotation of the camera preview, since it is no longer required. ## 0.6.11 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 1d068eb24f1..279956f8b17 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 @@ -10,7 +10,7 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart' show DeviceOrientation, PlatformException; import 'package:flutter/widgets.dart' - show RotatedBox, Size, Texture, Widget, visibleForTesting; + show Size, Texture, Widget, visibleForTesting; import 'package:stream_transform/stream_transform.dart'; import 'analyzer.dart'; @@ -237,26 +237,10 @@ class AndroidCameraCameraX extends CameraPlatform { @visibleForTesting late bool cameraIsFrontFacing; - /// Whether or not the Surface used to create the camera preview is backed - /// by a SurfaceTexture. - @visibleForTesting - late bool isPreviewPreTransformed; - - /// The initial orientation of the device. - /// - /// The camera preview will use this orientation as the natural orientation - /// to correct its rotation with respect to, if necessary. - @visibleForTesting - DeviceOrientation? naturalOrientation; - /// The camera sensor orientation. @visibleForTesting late int sensorOrientation; - /// The current orientation of the device. - @visibleForTesting - DeviceOrientation? currentDeviceOrientation; - /// Subscription for listening to changes in device orientation. StreamSubscription? _subscriptionForDeviceOrientationChanges; @@ -399,20 +383,7 @@ class AndroidCameraCameraX extends CameraPlatform { final Camera2CameraInfo camera2CameraInfo = await proxy.getCamera2CameraInfo(cameraInfo!); - await Future.wait(>[ - SystemServices.isPreviewPreTransformed() - .then((bool value) => isPreviewPreTransformed = value), - proxy - .getSensorOrientation(camera2CameraInfo) - .then((int value) => sensorOrientation = value), - proxy - .getUiOrientation() - .then((DeviceOrientation value) => naturalOrientation ??= value), - ]); - _subscriptionForDeviceOrientationChanges = onDeviceOrientationChanged() - .listen((DeviceOrientationChangedEvent event) { - currentDeviceOrientation = event.orientation; - }); + sensorOrientation = await proxy.getSensorOrientation(camera2CameraInfo); return flutterSurfaceTextureId; } @@ -865,68 +836,7 @@ class AndroidCameraCameraX extends CameraPlatform { ); } - final Widget cameraPreview = Texture(textureId: cameraId); - final Map degreesForDeviceOrientation = - { - DeviceOrientation.portraitUp: 0, - DeviceOrientation.landscapeRight: 90, - DeviceOrientation.portraitDown: 180, - DeviceOrientation.landscapeLeft: 270, - }; - int naturalDeviceOrientationDegrees = - degreesForDeviceOrientation[naturalOrientation]!; - - if (isPreviewPreTransformed) { - // If the camera preview is backed by a SurfaceTexture, the transformation - // needed to correctly rotate the preview has already been applied. - // However, we may need to correct the camera preview rotation if the - // device is naturally landscape-oriented. - if (naturalOrientation == DeviceOrientation.landscapeLeft || - naturalOrientation == DeviceOrientation.landscapeRight) { - final int quarterTurnsToCorrectForLandscape = - (-naturalDeviceOrientationDegrees + 360) ~/ 4; - return RotatedBox( - quarterTurns: quarterTurnsToCorrectForLandscape, - child: cameraPreview); - } - return cameraPreview; - } - - // Fix for the rotation of the camera preview not backed by a SurfaceTexture - // with respect to the naturalOrientation of the device: - - final int signForCameraDirection = cameraIsFrontFacing ? 1 : -1; - - if (signForCameraDirection == 1 && - (currentDeviceOrientation == DeviceOrientation.landscapeLeft || - currentDeviceOrientation == DeviceOrientation.landscapeRight)) { - // For front-facing cameras, the image buffer is rotated counterclockwise, - // so we determine the rotation needed to correct the camera preview with - // respect to the naturalOrientation of the device based on the inverse of - // naturalOrientation. - naturalDeviceOrientationDegrees += 180; - } - - // See https://developer.android.com/media/camera/camera2/camera-preview#orientation_calculation - // for more context on this formula. - final double rotation = (sensorOrientation + - naturalDeviceOrientationDegrees * signForCameraDirection + - 360) % - 360; - int quarterTurnsToCorrectPreview = rotation ~/ 90; - - if (naturalOrientation == DeviceOrientation.landscapeLeft || - naturalOrientation == DeviceOrientation.landscapeRight) { - // We may need to correct the camera preview rotation if the device is - // naturally landscape-oriented. - quarterTurnsToCorrectPreview += - (-naturalDeviceOrientationDegrees + 360) ~/ 4; - return RotatedBox( - quarterTurns: quarterTurnsToCorrectPreview, child: cameraPreview); - } - - return RotatedBox( - quarterTurns: quarterTurnsToCorrectPreview, child: cameraPreview); + return Texture(textureId: cameraId); } /// Captures an image and returns the file where it was saved. diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index 0cdcd81c840..e007029d2c1 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.6.11 +version: 0.6.12 environment: sdk: ^3.6.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 1f9ea762ce2..bf1ff878edd 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 @@ -50,8 +50,7 @@ import 'package:camera_android_camerax/src/zoom_state.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart' show DeviceOrientation, PlatformException, Uint8List; -import 'package:flutter/widgets.dart' - show BuildContext, RotatedBox, Size, Texture, Widget; +import 'package:flutter/widgets.dart' show BuildContext, Size, Texture, Widget; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -920,9 +919,7 @@ void main() { expect(camera.recorder!.qualitySelector, isNull); }); - test( - 'createCamera sets sensor and device orientations needed to correct preview rotation as expected', - () async { + test('createCamera sets sensor orientation as expected', () async { final AndroidCameraCameraX camera = AndroidCameraCameraX(); const CameraLensDirection testLensDirection = CameraLensDirection.back; const int testSensorOrientation = 270; @@ -933,8 +930,6 @@ void main() { const bool enableAudio = true; const ResolutionPreset testResolutionPreset = ResolutionPreset.veryHigh; const DeviceOrientation testUiOrientation = DeviceOrientation.portraitDown; - const DeviceOrientation testCurrentOrientation = - DeviceOrientation.portraitUp; // Mock/Detached objects for (typically attached) objects created by // createCamera. @@ -965,18 +960,7 @@ void main() { await camera.createCamera(testCameraDescription, testResolutionPreset, enableAudio: enableAudio); - const DeviceOrientationChangedEvent testEvent = - DeviceOrientationChangedEvent(testCurrentOrientation); - - DeviceOrientationManager.deviceOrientationChangedStreamController - .add(testEvent); - - // Wait for currentDeviceOrientation to update. - await Future.value(); - - expect(camera.naturalOrientation, testUiOrientation); expect(camera.sensorOrientation, testSensorOrientation); - expect(camera.currentDeviceOrientation, testCurrentOrientation); }); test( @@ -1336,148 +1320,12 @@ void main() { // bound to the lifecycle of the camera. camera.previewInitiallyBound = true; - // Tell camera the Surface used to build camera preview is backed by a - // SurfaceTexture. - camera.isPreviewPreTransformed = true; - - camera.naturalOrientation = DeviceOrientation.portraitDown; - final Widget widget = camera.buildPreview(cameraId); expect(widget is Texture, isTrue); expect((widget as Texture).textureId, cameraId); }); - test( - 'buildPreview returns preview with expected rotation if camera is not front facing and the preview is not backed by a SurfaceTexture', - () async { - final AndroidCameraCameraX camera = AndroidCameraCameraX(); - const int cameraId = 33; - - // Tell camera that createCamera has been called and thus, preview has been - // bound to the lifecycle of the camera. - camera.previewInitiallyBound = true; - - // Tell camera the Surface used to build camera preview is not backed by a - // SurfaceTexture. - camera.isPreviewPreTransformed = false; - - // Mock sensor and device orientation. - camera.sensorOrientation = 270; - camera.cameraIsFrontFacing = false; - camera.naturalOrientation = DeviceOrientation.portraitUp; - - final double expectedRotation = (camera.sensorOrientation + - 0 /* the natural orientation in clockwise degrees */ * - -1 /* camera is not front facing */ + - 360) % - 360; - final int expectedQuarterTurns = (expectedRotation / 90).toInt(); - - final Widget widget = camera.buildPreview(cameraId); - - expect(widget is RotatedBox, isTrue); - expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); - expect(widget.child is Texture, isTrue); - expect((widget.child! as Texture).textureId, cameraId); - }); - - test( - 'buildPreview returns preview with expected rotation if camera is front facing, the current orientation is landscape, and the preview is not backed by a SurfaceTexture', - () async { - final AndroidCameraCameraX camera = AndroidCameraCameraX(); - const int cameraId = 7; - - // Tell camera that createCamera has been called and thus, preview has been - // bound to the lifecycle of the camera. - camera.previewInitiallyBound = true; - - // Tell camera the Surface used to build camera preview is not backed by a - // SurfaceTexture. - camera.isPreviewPreTransformed = false; - - // Mock sensor and device orientation. - camera.sensorOrientation = 270; - camera.naturalOrientation = DeviceOrientation.portraitUp; - camera.cameraIsFrontFacing = true; - - // Calculate expected rotation with offset due to counter-clockwise rotation - // of the image with th efront camera in use. - final double expectedRotation = ((camera.sensorOrientation + - 0 /* the natural orientation in clockwise degrees */ * - 1 /* camera is front facing */ + - 360) % - 360) + - 180; - final int expectedQuarterTurns = (expectedRotation / 90).toInt() % 4; - - // Test landscape left. - camera.currentDeviceOrientation = DeviceOrientation.landscapeLeft; - Widget widget = camera.buildPreview(cameraId); - - expect(widget is RotatedBox, isTrue); - expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); - expect(widget.child is Texture, isTrue); - expect((widget.child! as Texture).textureId, cameraId); - - // Test landscape right. - camera.currentDeviceOrientation = DeviceOrientation.landscapeRight; - widget = camera.buildPreview(cameraId); - - expect(widget is RotatedBox, isTrue); - expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); - expect(widget.child is Texture, isTrue); - expect((widget.child! as Texture).textureId, cameraId); - }); - - test( - 'buildPreview returns preview with expected rotation if camera is front facing, the current orientation is not landscape, and the preview is not backed by a SurfaceTexture', - () async { - final AndroidCameraCameraX camera = AndroidCameraCameraX(); - const int cameraId = 733; - - // Tell camera that createCamera has been called and thus, preview has been - // bound to the lifecycle of the camera. - camera.previewInitiallyBound = true; - - // Tell camera the Surface used to build camera preview is not backed by a - // SurfaceTexture. - camera.isPreviewPreTransformed = false; - - // Mock sensor and device orientation. - camera.sensorOrientation = 270; - camera.naturalOrientation = DeviceOrientation.portraitUp; - camera.cameraIsFrontFacing = true; - - // Calculate expected rotation without offset needed for landscape orientations - // due to counter-clockwise rotation of the image with th efront camera in use. - final double expectedRotation = (camera.sensorOrientation + - 0 /* the natural orientation in clockwise degrees */ * - 1 /* camera is front facing */ + - 360) % - 360; - - final int expectedQuarterTurns = (expectedRotation / 90).toInt() % 4; - - // Test portrait up. - camera.currentDeviceOrientation = DeviceOrientation.portraitUp; - Widget widget = camera.buildPreview(cameraId); - - expect(widget is RotatedBox, isTrue); - expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); - expect(widget.child is Texture, isTrue); - expect((widget.child! as Texture).textureId, cameraId); - - // Test portrait down. - camera.currentDeviceOrientation = DeviceOrientation.portraitDown; - widget = camera.buildPreview(cameraId); - - expect(widget is RotatedBox, isTrue); - expect((widget as RotatedBox).quarterTurns, expectedQuarterTurns); - expect(widget.child is Texture, isTrue); - expect((widget.child! as Texture).textureId, cameraId); - }); - group('video recording', () { test( 'startVideoCapturing binds video capture use case, updates saved camera instance and its properties, and starts the recording',