From 45f59eef62d8c8c146793d15f60b584e293dfe5a Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Thu, 10 Jul 2025 14:34:00 +0200 Subject: [PATCH 1/5] Migrate exposure offset and zoom factor limit getters to Swift --- packages/camera/camera_avfoundation/CHANGELOG.md | 4 ++++ .../camera_avfoundation/DefaultCamera.swift | 5 +++++ .../Sources/camera_avfoundation_objc/FLTCam.m | 16 ---------------- .../include/camera_avfoundation/FLTCam.h | 4 ---- packages/camera/camera_avfoundation/pubspec.yaml | 2 +- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index abc280db2ad2..1b73dedcd888 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.20+2 + +* Migrates exposure offset and zoom factor limit getters to Swift. + ## 0.9.20+1 * Migrates lifecycle methods (`start`, `stop`, `close`) to Swift. diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 109a7f768145..c59997fc6779 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -10,6 +10,11 @@ import CoreMotion #endif final class DefaultCamera: FLTCam, Camera { + var minimumExposureOffset: CGFloat { CGFloat(captureDevice.minExposureTargetBias) } + var maximumExposureOffset: CGFloat { CGFloat(captureDevice.maxExposureTargetBias) } + var minimumAvailableZoomFactor: CGFloat { captureDevice.minAvailableVideoZoomFactor } + var maximumAvailableZoomFactor: CGFloat { captureDevice.maxAvailableVideoZoomFactor } + /// The queue on which `latestPixelBuffer` property is accessed. /// To avoid unnecessary contention, do not access `latestPixelBuffer` on the `captureSessionQueue`. private let pixelBufferSynchronizationQueue = DispatchQueue( diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m index ce7ec49118be..43ffe7ce5cc4 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m @@ -737,22 +737,6 @@ - (void)setZoomLevel:(CGFloat)zoom withCompletion:(void (^)(FlutterError *_Nulla completion(nil); } -- (CGFloat)minimumAvailableZoomFactor { - return _captureDevice.minAvailableVideoZoomFactor; -} - -- (CGFloat)maximumAvailableZoomFactor { - return _captureDevice.maxAvailableVideoZoomFactor; -} - -- (CGFloat)minimumExposureOffset { - return _captureDevice.minExposureTargetBias; -} - -- (CGFloat)maximumExposureOffset { - return _captureDevice.maxExposureTargetBias; -} - - (BOOL)setupWriterForPath:(NSString *)path { NSError *error = nil; NSURL *outputURL; diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h index 12b22d615f8d..ab9bde8106e5 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h @@ -29,10 +29,6 @@ NS_ASSUME_NONNULL_BEGIN // Format used for video and image streaming. @property(assign, nonatomic) FourCharCode videoFormat; @property(assign, nonatomic) FCPPlatformImageFileFormat fileFormat; -@property(readonly, nonatomic) CGFloat minimumAvailableZoomFactor; -@property(readonly, nonatomic) CGFloat maximumAvailableZoomFactor; -@property(readonly, nonatomic) CGFloat minimumExposureOffset; -@property(readonly, nonatomic) CGFloat maximumExposureOffset; // Properties exposed for the Swift DefaultCamera subclass @property(nonatomic, nullable) FLTImageStreamHandler *imageStreamHandler; diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index c4a77a5a9a8b..779bc7fb09fc 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.20+1 +version: 0.9.20+2 environment: sdk: ^3.6.0 From d2658fc08e1b0be6e884ac4b4159322462641076 Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Thu, 10 Jul 2025 14:34:15 +0200 Subject: [PATCH 2/5] Migrate setImageFileFormat method to Swift --- packages/camera/camera_avfoundation/CHANGELOG.md | 1 + .../Sources/camera_avfoundation/DefaultCamera.swift | 4 ++++ .../Sources/camera_avfoundation_objc/FLTCam.m | 4 ---- .../include/camera_avfoundation/FLTCam.h | 1 - 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index 1b73dedcd888..bf989203efdc 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.9.20+2 * Migrates exposure offset and zoom factor limit getters to Swift. +* Migrates `setImageFileFormat` method to Swift. ## 0.9.20+1 diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index c59997fc6779..2a238c0ea7f9 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -69,6 +69,10 @@ final class DefaultCamera: FLTCam, Camera { audioCaptureSession.stopRunning() } + func setImageFileFormat(_ fileFormat: FCPPlatformImageFileFormat) { + self.fileFormat = fileFormat + } + func setExposureMode(_ mode: FCPPlatformExposureMode) { exposureMode = mode applyExposureMode() diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m index 43ffe7ce5cc4..9e94d441d62e 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m @@ -202,10 +202,6 @@ - (void)setVideoFormat:(OSType)videoFormat { @{(NSString *)kCVPixelBufferPixelFormatTypeKey : @(videoFormat)}; } -- (void)setImageFileFormat:(FCPPlatformImageFileFormat)fileFormat { - _fileFormat = fileFormat; -} - - (void)setDeviceOrientation:(UIDeviceOrientation)orientation { if (_deviceOrientation == orientation) { return; diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h index ab9bde8106e5..a3b1a35c84e9 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h @@ -56,7 +56,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)setDeviceOrientation:(UIDeviceOrientation)orientation; - (void)captureToFileWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)setImageFileFormat:(FCPPlatformImageFileFormat)fileFormat; /// Starts recording a video with an optional streaming messenger. /// If the messenger is non-nil then it will be called for each /// captured frame, allowing streaming concurrently with recording. From d4f0d70d6be635b624ef6ab550db2faeb56e9109 Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Thu, 10 Jul 2025 14:34:20 +0200 Subject: [PATCH 3/5] Migrate pause and resume methods to Swift --- .../camera/camera_avfoundation/CHANGELOG.md | 1 + .../camera_avfoundation/DefaultCamera.swift | 18 ++++++++++++++++++ .../Sources/camera_avfoundation_objc/FLTCam.m | 18 ------------------ .../include/camera_avfoundation/FLTCam.h | 4 ---- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index bf989203efdc..c45467ea797a 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -2,6 +2,7 @@ * Migrates exposure offset and zoom factor limit getters to Swift. * Migrates `setImageFileFormat` method to Swift. +* Migrates pause and resume methods to Swift. ## 0.9.20+1 diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 2a238c0ea7f9..5216d6df86dc 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -69,6 +69,16 @@ final class DefaultCamera: FLTCam, Camera { audioCaptureSession.stopRunning() } + func pauseVideoRecording() { + isRecordingPaused = true + videoIsDisconnected = true + audioIsDisconnected = true + } + + func resumeVideoRecording() { + isRecordingPaused = false + } + func setImageFileFormat(_ fileFormat: FCPPlatformImageFileFormat) { self.fileFormat = fileFormat } @@ -208,6 +218,14 @@ final class DefaultCamera: FLTCam, Camera { return CGPoint(x: x, y: y) } + func pausePreview() { + isPreviewPaused = true + } + + func resumePreview() { + isPreviewPaused = false + } + func captureOutput( _ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m index 9e94d441d62e..879726cfdbba 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m @@ -522,16 +522,6 @@ - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, } } -- (void)pauseVideoRecording { - _isRecordingPaused = YES; - _videoIsDisconnected = YES; - _audioIsDisconnected = YES; -} - -- (void)resumeVideoRecording { - _isRecordingPaused = NO; -} - - (void)lockCaptureOrientation:(FCPPlatformDeviceOrientation)pigeonOrientation { UIDeviceOrientation orientation = FCPGetUIDeviceOrientationForPigeonDeviceOrientation(pigeonOrientation); @@ -591,14 +581,6 @@ - (void)setFlashMode:(FCPPlatformFlashMode)mode completion(nil); } -- (void)pausePreview { - _isPreviewPaused = true; -} - -- (void)resumePreview { - _isPreviewPaused = false; -} - - (void)setDescriptionWhileRecording:(NSString *)cameraName withCompletion:(void (^)(FlutterError *_Nullable))completion { if (!_isRecording) { diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h index a3b1a35c84e9..429e6950c1f3 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h @@ -65,16 +65,12 @@ NS_ASSUME_NONNULL_BEGIN messengerForStreaming:(nullable NSObject *)messenger; - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)pauseVideoRecording; -- (void)resumeVideoRecording; - (void)lockCaptureOrientation:(FCPPlatformDeviceOrientation)orientation NS_SWIFT_NAME(lockCaptureOrientation(_:)); - (void)unlockCaptureOrientation; - (void)setFlashMode:(FCPPlatformFlashMode)mode withCompletion:(void (^)(FlutterError *_Nullable))completion; -- (void)pausePreview; -- (void)resumePreview; - (void)setDescriptionWhileRecording:(NSString *)cameraName withCompletion:(void (^)(FlutterError *_Nullable))completion; From 7833be930015a054c7077f3095cbfb7528b48820 Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Thu, 10 Jul 2025 14:34:25 +0200 Subject: [PATCH 4/5] Migrate setDeviceOrientation, lockCaptureOrientation, and unlockCaptureOrientation methods to Swift --- .../camera/camera_avfoundation/CHANGELOG.md | 1 + .../camera_avfoundation/DefaultCamera.swift | 22 ++++++++++++++++ .../Sources/camera_avfoundation_objc/FLTCam.m | 25 ------------------- .../include/camera_avfoundation/FLTCam.h | 9 ++++--- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index c45467ea797a..6806f3b34d55 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -3,6 +3,7 @@ * Migrates exposure offset and zoom factor limit getters to Swift. * Migrates `setImageFileFormat` method to Swift. * Migrates pause and resume methods to Swift. +* Migrates `setDeviceOrientation`, `lockCaptureOrientation`, and `unlockCaptureOrientation` methods to Swift. ## 0.9.20+1 diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 5216d6df86dc..1304348e57b9 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -79,6 +79,28 @@ final class DefaultCamera: FLTCam, Camera { isRecordingPaused = false } + func setDeviceOrientation(_ orientation: UIDeviceOrientation) { + if deviceOrientation == orientation { + return + } + + deviceOrientation = orientation + updateOrientation() + } + + func lockCaptureOrientation(_ pigeonOrientation: FCPPlatformDeviceOrientation) { + let orientation = FCPGetUIDeviceOrientationForPigeonDeviceOrientation(pigeonOrientation) + if lockedCaptureOrientation != orientation { + lockedCaptureOrientation = orientation + updateOrientation() + } + } + + func unlockCaptureOrientation() { + lockedCaptureOrientation = .unknown + updateOrientation() + } + func setImageFileFormat(_ fileFormat: FCPPlatformImageFileFormat) { self.fileFormat = fileFormat } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m index 879726cfdbba..c44b6e184ed3 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m @@ -42,14 +42,12 @@ @interface FLTCam () *videoCaptureSession; @property(readonly, nonatomic) NSObject *audioCaptureSession; @property(readonly, nonatomic) NSObject *deviceOrientationProvider; +@property(assign, nonatomic) UIDeviceOrientation lockedCaptureOrientation; +@property(assign, nonatomic) UIDeviceOrientation deviceOrientation; /// Initializes an `FLTCam` instance with the given configuration. /// @param error report to the caller if any error happened creating the camera. - (instancetype)initWithConfiguration:(FLTCamConfiguration *)configuration error:(NSError **)error; -- (void)setDeviceOrientation:(UIDeviceOrientation)orientation; - (void)captureToFileWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; /// Starts recording a video with an optional streaming messenger. @@ -65,9 +66,6 @@ NS_ASSUME_NONNULL_BEGIN messengerForStreaming:(nullable NSObject *)messenger; - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)lockCaptureOrientation:(FCPPlatformDeviceOrientation)orientation - NS_SWIFT_NAME(lockCaptureOrientation(_:)); -- (void)unlockCaptureOrientation; - (void)setFlashMode:(FCPPlatformFlashMode)mode withCompletion:(void (^)(FlutterError *_Nullable))completion; @@ -80,6 +78,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)setZoomLevel:(CGFloat)zoom withCompletion:(void (^)(FlutterError *_Nullable))completion; - (void)setUpCaptureSessionForAudioIfNeeded; +// Methods exposed for the Swift DefaultCamera subclass +- (void)updateOrientation; + @end NS_ASSUME_NONNULL_END From d4e829ebdf36114536ddb3791eed871f34d5f473 Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Fri, 11 Jul 2025 13:59:34 +0200 Subject: [PATCH 5/5] Convert setDeviceOrientation method to property setter --- .../camera/camera_avfoundation/CHANGELOG.md | 3 ++- .../FLTCamSetDeviceOrientationTests.swift | 10 +++++----- .../ios/RunnerTests/Mocks/MockCamera.swift | 13 +++++++++---- .../Sources/camera_avfoundation/Camera.swift | 3 ++- .../camera_avfoundation/CameraPlugin.swift | 4 ++-- .../camera_avfoundation/DefaultCamera.swift | 19 ++++++++++--------- 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index 6806f3b34d55..c057802fe75b 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -3,7 +3,8 @@ * Migrates exposure offset and zoom factor limit getters to Swift. * Migrates `setImageFileFormat` method to Swift. * Migrates pause and resume methods to Swift. -* Migrates `setDeviceOrientation`, `lockCaptureOrientation`, and `unlockCaptureOrientation` methods to Swift. +* Migrates capture orientation locking methods to Swift. +* Converts `setDeviceOrientation` method to property setter and migrated to Swift. ## 0.9.20+1 diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift index cd8d5d858a86..d7fbb505b7ea 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift @@ -51,7 +51,7 @@ final class FLTCamSetDeviceOrientationTests: XCTestCase { videoSetVideoOrientationCalled = true } - camera.setDeviceOrientation(.landscapeLeft) + camera.deviceOrientation = .landscapeLeft XCTAssertTrue(photoSetVideoOrientationCalled) XCTAssertTrue(videoSetVideoOrientationCalled) @@ -75,7 +75,7 @@ final class FLTCamSetDeviceOrientationTests: XCTestCase { camera.lockCaptureOrientation(FCPPlatformDeviceOrientation.portraitDown) - camera.setDeviceOrientation(.landscapeLeft) + camera.deviceOrientation = .landscapeLeft XCTAssertTrue(photoSetVideoOrientationCalled) XCTAssertTrue(videoSetVideoOrientationCalled) @@ -89,7 +89,7 @@ final class FLTCamSetDeviceOrientationTests: XCTestCase { mockPhotoCaptureConnection.setVideoOrientationStub = { _ in XCTFail() } mockVideoCaptureConnection.setVideoOrientationStub = { _ in XCTFail() } - camera.setDeviceOrientation(.landscapeLeft) + camera.deviceOrientation = .landscapeLeft } func testSetDeviceOrientation_doesNotSetOrientations_forDuplicateUpdates() { @@ -104,8 +104,8 @@ final class FLTCamSetDeviceOrientationTests: XCTestCase { videoSetVideoOrientationCallCount += 1 } - camera.setDeviceOrientation(.landscapeRight) - camera.setDeviceOrientation(.landscapeRight) + camera.deviceOrientation = .landscapeRight + camera.deviceOrientation = .landscapeRight XCTAssertEqual(photoSetVideoOrientationCallCount, 1) XCTAssertEqual(videoSetVideoOrientationCallCount, 1) diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift index 7cb2dd6dccdc..1996b785fb63 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift @@ -65,6 +65,15 @@ final class MockCamera: NSObject, Camera { var isPreviewPaused: Bool = false var isStreamingImages: Bool = false + var deviceOrientation: UIDeviceOrientation { + get { + preconditionFailure("Attempted to access unimplemented property: deviceOrientation") + } + set { + setDeviceOrientationStub?(newValue) + } + } + var minimumExposureOffset: CGFloat { return getMinimumExposureOffsetStub?() ?? 0 } @@ -120,10 +129,6 @@ final class MockCamera: NSObject, Camera { captureToFileStub?(completion) } - func setDeviceOrientation(_ orientation: UIDeviceOrientation) { - setDeviceOrientationStub?(orientation) - } - func lockCaptureOrientation(_ orientation: FCPPlatformDeviceOrientation) { lockCaptureOrientationStub?(orientation) } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift index b890f2ddaa98..1acb3e2a90ce 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift @@ -27,6 +27,8 @@ protocol Camera: FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate, var isPreviewPaused: Bool { get } var isStreamingImages: Bool { get } + var deviceOrientation: UIDeviceOrientation { get set } + var minimumAvailableZoomFactor: CGFloat { get } var maximumAvailableZoomFactor: CGFloat { get } var minimumExposureOffset: CGFloat { get } @@ -61,7 +63,6 @@ protocol Camera: FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate, func captureToFile(completion: @escaping (_ path: String?, _ error: FlutterError?) -> Void) - func setDeviceOrientation(_ orientation: UIDeviceOrientation) func lockCaptureOrientation(_ orientation: FCPPlatformDeviceOrientation) func unlockCaptureOrientation() diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift index d3c3c81275fd..1297256d9c39 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift @@ -103,8 +103,8 @@ public final class CameraPlugin: NSObject, FlutterPlugin { self.captureSessionQueue.async { [weak self] in guard let strongSelf = self else { return } - // `FLTCam.setDeviceOrientation` must be called on capture session queue. - strongSelf.camera?.setDeviceOrientation(orientation) + // `Camera.deviceOrientation` must be set on capture session queue. + strongSelf.camera?.deviceOrientation = orientation // `CameraPlugin.sendDeviceOrientation` can be called on any queue. strongSelf.sendDeviceOrientation(orientation) } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 1304348e57b9..4ebe0efec87f 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -10,6 +10,16 @@ import CoreMotion #endif final class DefaultCamera: FLTCam, Camera { + override var deviceOrientation: UIDeviceOrientation { + get { super.deviceOrientation } + set { + guard newValue != super.deviceOrientation else { return } + + super.deviceOrientation = newValue + updateOrientation() + } + } + var minimumExposureOffset: CGFloat { CGFloat(captureDevice.minExposureTargetBias) } var maximumExposureOffset: CGFloat { CGFloat(captureDevice.maxExposureTargetBias) } var minimumAvailableZoomFactor: CGFloat { captureDevice.minAvailableVideoZoomFactor } @@ -79,15 +89,6 @@ final class DefaultCamera: FLTCam, Camera { isRecordingPaused = false } - func setDeviceOrientation(_ orientation: UIDeviceOrientation) { - if deviceOrientation == orientation { - return - } - - deviceOrientation = orientation - updateOrientation() - } - func lockCaptureOrientation(_ pigeonOrientation: FCPPlatformDeviceOrientation) { let orientation = FCPGetUIDeviceOrientationForPigeonDeviceOrientation(pigeonOrientation) if lockedCaptureOrientation != orientation {