From 12f1d626b856fbd6882cd588d370831b0339c9bc Mon Sep 17 00:00:00 2001 From: Mairramer Date: Sat, 25 Jul 2026 11:00:12 -0300 Subject: [PATCH 1/3] Isolate UIKit and UIDeviceOrientation for macOS support --- .../darwin/Tests/CameraOrientationTests.swift | 266 +++++++++--------- .../darwin/Tests/CameraPropertiesTests.swift | 68 ++--- .../CameraSetDeviceOrientationTests.swift | 154 +++++----- .../darwin/Tests/Mocks/MockCamera.swift | 4 +- .../Mocks/MockDeviceOrientationProvider.swift | 16 +- .../Sources/camera_avfoundation/Camera.swift | 2 +- .../CameraConfiguration.swift | 18 +- .../camera_avfoundation/CameraPlugin.swift | 74 ++--- .../CameraProperties.swift | 76 ++--- .../camera_avfoundation/DefaultCamera.swift | 163 ++++++----- .../DeviceOrientationProvider.swift | 28 +- 11 files changed, 460 insertions(+), 409 deletions(-) diff --git a/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift b/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift index 4878cbe51d6f..e932c0ee4872 100644 --- a/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift +++ b/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift @@ -8,161 +8,163 @@ import XCTest @testable import camera_avfoundation -private final class MockUIDevice: UIDevice { - var mockOrientation: UIDeviceOrientation = .unknown +#if os(iOS) + private final class MockUIDevice: UIDevice { + var mockOrientation: UIDeviceOrientation = .unknown - override var orientation: UIDeviceOrientation { - return mockOrientation - } -} - -final class CameraOrientationTests: XCTestCase { - private func createCameraPlugin() -> ( - cameraPlugin: CameraPlugin, - mockCamera: MockCamera, - mockEventAPI: MockGlobalEventApi, - mockDevice: MockCaptureDevice, - mockDeviceDiscoverer: MockCameraDeviceDiscoverer, - captureSessionQueue: DispatchQueue - ) { - let mockDevice = MockCaptureDevice() - let mockCamera = MockCamera() - let mockEventAPI = MockGlobalEventApi() - let mockDeviceDiscoverer = MockCameraDeviceDiscoverer() - let captureSessionQueue = DispatchQueue(label: "io.flutter.camera.captureSessionQueue") - - let cameraPlugin = CameraPlugin( - registry: MockFlutterTextureRegistry(), - messenger: MockFlutterBinaryMessenger(), - globalAPI: mockEventAPI, - deviceDiscoverer: mockDeviceDiscoverer, - permissionManager: MockCameraPermissionManager(), - deviceFactory: { _ in mockDevice }, - captureSessionFactory: { MockCaptureSession() }, - captureDeviceInputFactory: MockCaptureDeviceInputFactory(), - captureSessionQueue: captureSessionQueue - ) - cameraPlugin.camera = mockCamera - - return ( - cameraPlugin, - mockCamera, - mockEventAPI, - mockDevice, - mockDeviceDiscoverer, - captureSessionQueue - ) - } - - private func sendOrientation( - _ orientation: UIDeviceOrientation, - to cameraPlugin: CameraPlugin, - captureSessionQueue: DispatchQueue - ) { - cameraPlugin.orientationChanged(createMockNotification(for: orientation)) - waitForQueueRoundTrip(with: captureSessionQueue) - } - - private func createMockNotification(for deviceOrientation: UIDeviceOrientation) -> Notification { - let mockDevice = MockUIDevice() - mockDevice.mockOrientation = deviceOrientation - return Notification(name: Notification.Name("orientation_test"), object: mockDevice) - } - - func testOrientationNotifications() { - let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() - - sendOrientation(.portraitUpsideDown, to: cameraPlugin, captureSessionQueue: captureSessionQueue) - XCTAssertEqual(mockEventAPI.lastOrientation, .portraitDown) - sendOrientation(.portrait, to: cameraPlugin, captureSessionQueue: captureSessionQueue) - XCTAssertEqual(mockEventAPI.lastOrientation, .portraitUp) - sendOrientation(.landscapeLeft, to: cameraPlugin, captureSessionQueue: captureSessionQueue) - XCTAssertEqual(mockEventAPI.lastOrientation, .landscapeLeft) - sendOrientation(.landscapeRight, to: cameraPlugin, captureSessionQueue: captureSessionQueue) - XCTAssertEqual(mockEventAPI.lastOrientation, .landscapeRight) - } - - func testOrientationNotificationsNotCalledForFaceUp() { - let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() - sendOrientation(.faceUp, to: cameraPlugin, captureSessionQueue: captureSessionQueue) - XCTAssertFalse(mockEventAPI.deviceOrientationChangedCalled) - } - - func testOrientationNotificationsNotCalledForFaceDown() { - let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() - sendOrientation(.faceDown, to: cameraPlugin, captureSessionQueue: captureSessionQueue) - XCTAssertFalse(mockEventAPI.deviceOrientationChangedCalled) - } - - func testOrientationUpdateMustBeOnCaptureSessionQueue() { - let queueExpectation = expectation( - description: "Orientation update must happen on the capture session queue") - let (cameraPlugin, mockCamera, _, _, _, captureSessionQueue) = createCameraPlugin() - let captureSessionQueueSpecific = DispatchSpecificKey() - captureSessionQueue.setSpecific( - key: captureSessionQueueSpecific, - value: ()) - - mockCamera.setDeviceOrientationStub = { orientation in - if DispatchQueue.getSpecific(key: captureSessionQueueSpecific) != nil { - queueExpectation.fulfill() - } + override var orientation: UIDeviceOrientation { + return mockOrientation } - - cameraPlugin.orientationChanged(createMockNotification(for: .landscapeLeft)) - waitForExpectations(timeout: 30, handler: nil) } - func testOrientationChangedNoRetainCycle() { - let (_, mockCamera, mockEventAPI, mockDevice, mockDeviceDiscoverer, _) = createCameraPlugin() - let captureSessionQueue = DispatchQueue(label: "capture_session_queue") - weak var weakPlugin: CameraPlugin? - weak var weakDevice = mockDevice + final class CameraOrientationTests: XCTestCase { + private func createCameraPlugin() -> ( + cameraPlugin: CameraPlugin, + mockCamera: MockCamera, + mockEventAPI: MockGlobalEventApi, + mockDevice: MockCaptureDevice, + mockDeviceDiscoverer: MockCameraDeviceDiscoverer, + captureSessionQueue: DispatchQueue + ) { + let mockDevice = MockCaptureDevice() + let mockCamera = MockCamera() + let mockEventAPI = MockGlobalEventApi() + let mockDeviceDiscoverer = MockCameraDeviceDiscoverer() + let captureSessionQueue = DispatchQueue(label: "io.flutter.camera.captureSessionQueue") - autoreleasepool { let cameraPlugin = CameraPlugin( registry: MockFlutterTextureRegistry(), messenger: MockFlutterBinaryMessenger(), globalAPI: mockEventAPI, deviceDiscoverer: mockDeviceDiscoverer, permissionManager: MockCameraPermissionManager(), - deviceFactory: { _ in weakDevice! }, + deviceFactory: { _ in mockDevice }, captureSessionFactory: { MockCaptureSession() }, captureDeviceInputFactory: MockCaptureDeviceInputFactory(), captureSessionQueue: captureSessionQueue ) - weakPlugin = cameraPlugin cameraPlugin.camera = mockCamera - cameraPlugin.orientationChanged(createMockNotification(for: .landscapeLeft)) + return ( + cameraPlugin, + mockCamera, + mockEventAPI, + mockDevice, + mockDeviceDiscoverer, + captureSessionQueue + ) } - // Sanity check. - let cameraDeallocatedExpectation = self.expectation( - description: "Camera must have been deallocated.") - captureSessionQueue.async { - XCTAssertNil(weakPlugin) - cameraDeallocatedExpectation.fulfill() + private func sendOrientation( + _ orientation: UIDeviceOrientation, + to cameraPlugin: CameraPlugin, + captureSessionQueue: DispatchQueue + ) { + cameraPlugin.orientationChanged(createMockNotification(for: orientation)) + waitForQueueRoundTrip(with: captureSessionQueue) } - // Awaiting expectation is needed. The test is flaky when checking for nil right away. - waitForExpectations(timeout: 1, handler: nil) - var setDeviceOrientationCalled = false - mockCamera.setDeviceOrientationStub = { orientation in - if orientation == .landscapeLeft { - setDeviceOrientationCalled = true - } + private func createMockNotification(for deviceOrientation: UIDeviceOrientation) -> Notification { + let mockDevice = MockUIDevice() + mockDevice.mockOrientation = deviceOrientation + return Notification(name: Notification.Name("orientation_test"), object: mockDevice) } - weak var weakEventAPI = mockEventAPI - // Must check in captureSessionQueue since orientationChanged dispatches to this queue. - let expectation = self.expectation(description: "Dispatched to capture session queue") - captureSessionQueue.async { - XCTAssertFalse(setDeviceOrientationCalled) - XCTAssertFalse(weakEventAPI?.deviceOrientationChangedCalled ?? false) - expectation.fulfill() + func testOrientationNotifications() { + let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() + + sendOrientation(.portraitUpsideDown, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + XCTAssertEqual(mockEventAPI.lastOrientation, .portraitDown) + sendOrientation(.portrait, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + XCTAssertEqual(mockEventAPI.lastOrientation, .portraitUp) + sendOrientation(.landscapeLeft, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + XCTAssertEqual(mockEventAPI.lastOrientation, .landscapeLeft) + sendOrientation(.landscapeRight, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + XCTAssertEqual(mockEventAPI.lastOrientation, .landscapeRight) } - waitForExpectations(timeout: 30, handler: nil) + func testOrientationNotificationsNotCalledForFaceUp() { + let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() + sendOrientation(.faceUp, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + XCTAssertFalse(mockEventAPI.deviceOrientationChangedCalled) + } + + func testOrientationNotificationsNotCalledForFaceDown() { + let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() + sendOrientation(.faceDown, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + XCTAssertFalse(mockEventAPI.deviceOrientationChangedCalled) + } + + func testOrientationUpdateMustBeOnCaptureSessionQueue() { + let queueExpectation = expectation( + description: "Orientation update must happen on the capture session queue") + let (cameraPlugin, mockCamera, _, _, _, captureSessionQueue) = createCameraPlugin() + let captureSessionQueueSpecific = DispatchSpecificKey() + captureSessionQueue.setSpecific( + key: captureSessionQueueSpecific, + value: ()) + + mockCamera.setDeviceOrientationStub = { orientation in + if DispatchQueue.getSpecific(key: captureSessionQueueSpecific) != nil { + queueExpectation.fulfill() + } + } + + cameraPlugin.orientationChanged(createMockNotification(for: .landscapeLeft)) + waitForExpectations(timeout: 30, handler: nil) + } + + func testOrientationChangedNoRetainCycle() { + let (_, mockCamera, mockEventAPI, mockDevice, mockDeviceDiscoverer, _) = createCameraPlugin() + let captureSessionQueue = DispatchQueue(label: "capture_session_queue") + weak var weakPlugin: CameraPlugin? + weak var weakDevice = mockDevice + + autoreleasepool { + let cameraPlugin = CameraPlugin( + registry: MockFlutterTextureRegistry(), + messenger: MockFlutterBinaryMessenger(), + globalAPI: mockEventAPI, + deviceDiscoverer: mockDeviceDiscoverer, + permissionManager: MockCameraPermissionManager(), + deviceFactory: { _ in weakDevice! }, + captureSessionFactory: { MockCaptureSession() }, + captureDeviceInputFactory: MockCaptureDeviceInputFactory(), + captureSessionQueue: captureSessionQueue + ) + weakPlugin = cameraPlugin + cameraPlugin.camera = mockCamera + + cameraPlugin.orientationChanged(createMockNotification(for: .landscapeLeft)) + } + + // Sanity check. + let cameraDeallocatedExpectation = self.expectation( + description: "Camera must have been deallocated.") + captureSessionQueue.async { + XCTAssertNil(weakPlugin) + cameraDeallocatedExpectation.fulfill() + } + // Awaiting expectation is needed. The test is flaky when checking for nil right away. + waitForExpectations(timeout: 1, handler: nil) + + var setDeviceOrientationCalled = false + mockCamera.setDeviceOrientationStub = { orientation in + if orientation == .landscapeLeft { + setDeviceOrientationCalled = true + } + } + + weak var weakEventAPI = mockEventAPI + // Must check in captureSessionQueue since orientationChanged dispatches to this queue. + let expectation = self.expectation(description: "Dispatched to capture session queue") + captureSessionQueue.async { + XCTAssertFalse(setDeviceOrientationCalled) + XCTAssertFalse(weakEventAPI?.deviceOrientationChangedCalled ?? false) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + } } -} +#endif diff --git a/packages/camera/camera_avfoundation/darwin/Tests/CameraPropertiesTests.swift b/packages/camera/camera_avfoundation/darwin/Tests/CameraPropertiesTests.swift index bac0ce6ed19e..63efe7978968 100644 --- a/packages/camera/camera_avfoundation/darwin/Tests/CameraPropertiesTests.swift +++ b/packages/camera/camera_avfoundation/darwin/Tests/CameraPropertiesTests.swift @@ -36,38 +36,40 @@ final class CameraPropertiesTests: XCTestCase { // MARK: - Device Orientation Tests - func testGetUIDeviceOrientationForPigeonDeviceOrientation() { - XCTAssertEqual( - UIDeviceOrientation.portraitUpsideDown, - getUIDeviceOrientation(for: .portraitDown) - ) - XCTAssertEqual( - UIDeviceOrientation.landscapeLeft, - getUIDeviceOrientation(for: .landscapeLeft)) - XCTAssertEqual( - UIDeviceOrientation.landscapeRight, - getUIDeviceOrientation(for: .landscapeRight)) - XCTAssertEqual( - UIDeviceOrientation.portrait, - getUIDeviceOrientation(for: .portraitUp)) - } + #if os(iOS) + func testGetUIDeviceOrientationForPigeonDeviceOrientation() { + XCTAssertEqual( + UIDeviceOrientation.portraitUpsideDown, + getUIDeviceOrientation(for: .portraitDown) + ) + XCTAssertEqual( + UIDeviceOrientation.landscapeLeft, + getUIDeviceOrientation(for: .landscapeLeft)) + XCTAssertEqual( + UIDeviceOrientation.landscapeRight, + getUIDeviceOrientation(for: .landscapeRight)) + XCTAssertEqual( + UIDeviceOrientation.portrait, + getUIDeviceOrientation(for: .portraitUp)) + } - func testGetPigeonDeviceOrientationForUIDeviceOrientation() { - XCTAssertEqual( - PlatformDeviceOrientation.portraitDown, - getPigeonDeviceOrientation(for: .portraitUpsideDown)) - XCTAssertEqual( - PlatformDeviceOrientation.landscapeLeft, - getPigeonDeviceOrientation(for: .landscapeLeft)) - XCTAssertEqual( - PlatformDeviceOrientation.landscapeRight, - getPigeonDeviceOrientation(for: .landscapeRight)) - XCTAssertEqual( - PlatformDeviceOrientation.portraitUp, - getPigeonDeviceOrientation(for: .portrait)) - // Test default case. - XCTAssertEqual( - PlatformDeviceOrientation.portraitUp, - getPigeonDeviceOrientation(for: .unknown)) - } + func testGetPigeonDeviceOrientationForUIDeviceOrientation() { + XCTAssertEqual( + PlatformDeviceOrientation.portraitDown, + getPigeonDeviceOrientation(for: .portraitUpsideDown)) + XCTAssertEqual( + PlatformDeviceOrientation.landscapeLeft, + getPigeonDeviceOrientation(for: .landscapeLeft)) + XCTAssertEqual( + PlatformDeviceOrientation.landscapeRight, + getPigeonDeviceOrientation(for: .landscapeRight)) + XCTAssertEqual( + PlatformDeviceOrientation.portraitUp, + getPigeonDeviceOrientation(for: .portrait)) + // Test default case. + XCTAssertEqual( + PlatformDeviceOrientation.portraitUp, + getPigeonDeviceOrientation(for: .unknown)) + } + #endif } diff --git a/packages/camera/camera_avfoundation/darwin/Tests/CameraSetDeviceOrientationTests.swift b/packages/camera/camera_avfoundation/darwin/Tests/CameraSetDeviceOrientationTests.swift index c6ca992d236b..5b72ec61b763 100644 --- a/packages/camera/camera_avfoundation/darwin/Tests/CameraSetDeviceOrientationTests.swift +++ b/packages/camera/camera_avfoundation/darwin/Tests/CameraSetDeviceOrientationTests.swift @@ -7,102 +7,104 @@ import XCTest @testable import camera_avfoundation -final class CameraSetDeviceOrientationTests: XCTestCase { - private func createCamera() -> (Camera, MockCaptureConnection, MockCaptureConnection) { - let camera = CameraTestUtils.createTestCamera() +#if os(iOS) + final class CameraSetDeviceOrientationTests: XCTestCase { + private func createCamera() -> (Camera, MockCaptureConnection, MockCaptureConnection) { + let camera = CameraTestUtils.createTestCamera() - let mockCapturePhotoOutput = MockCapturePhotoOutput() - let mockPhotoCaptureConnection = MockCaptureConnection() - mockPhotoCaptureConnection.isVideoOrientationSupported = true + let mockCapturePhotoOutput = MockCapturePhotoOutput() + let mockPhotoCaptureConnection = MockCaptureConnection() + mockPhotoCaptureConnection.isVideoOrientationSupported = true - mockCapturePhotoOutput.connectionWithMediaTypeStub = { _ in mockPhotoCaptureConnection } - camera.capturePhotoOutput = mockCapturePhotoOutput + mockCapturePhotoOutput.connectionWithMediaTypeStub = { _ in mockPhotoCaptureConnection } + camera.capturePhotoOutput = mockCapturePhotoOutput - let mockCaptureVideoDataOutput = MockCaptureVideoDataOutput() - let mockVideoCaptureConnection = MockCaptureConnection() - mockVideoCaptureConnection.isVideoOrientationSupported = true + let mockCaptureVideoDataOutput = MockCaptureVideoDataOutput() + let mockVideoCaptureConnection = MockCaptureConnection() + mockVideoCaptureConnection.isVideoOrientationSupported = true - mockCaptureVideoDataOutput.connectionWithMediaTypeStub = { _ in mockVideoCaptureConnection } - camera.captureVideoOutput = mockCaptureVideoDataOutput + mockCaptureVideoDataOutput.connectionWithMediaTypeStub = { _ in mockVideoCaptureConnection } + camera.captureVideoOutput = mockCaptureVideoDataOutput - return (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) - } - - func testSetDeviceOrientation_setsOrientationsOfCaptureConnections() { - let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() - var photoSetVideoOrientationCalled = false - mockPhotoCaptureConnection.setVideoOrientationStub = { orientation in - // Device orientation is flipped compared to video orientation. When UIDeviceOrientation - // is landscape left the video orientation should be landscape right. - XCTAssertEqual(orientation, .landscapeRight) - photoSetVideoOrientationCalled = true + return (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) } - var videoSetVideoOrientationCalled = false - mockVideoCaptureConnection.setVideoOrientationStub = { orientation in - // Device orientation is flipped compared to video orientation. When UIDeviceOrientation - // is landscape left the video orientation should be landscape right. - XCTAssertEqual(orientation, .landscapeRight) - videoSetVideoOrientationCalled = true + func testSetDeviceOrientation_setsOrientationsOfCaptureConnections() { + let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() + var photoSetVideoOrientationCalled = false + mockPhotoCaptureConnection.setVideoOrientationStub = { orientation in + // Device orientation is flipped compared to video orientation. When UIDeviceOrientation + // is landscape left the video orientation should be landscape right. + XCTAssertEqual(orientation, .landscapeRight) + photoSetVideoOrientationCalled = true + } + + var videoSetVideoOrientationCalled = false + mockVideoCaptureConnection.setVideoOrientationStub = { orientation in + // Device orientation is flipped compared to video orientation. When UIDeviceOrientation + // is landscape left the video orientation should be landscape right. + XCTAssertEqual(orientation, .landscapeRight) + videoSetVideoOrientationCalled = true + } + + camera.deviceOrientation = .landscapeLeft + + XCTAssertTrue(photoSetVideoOrientationCalled) + XCTAssertTrue(videoSetVideoOrientationCalled) } - camera.deviceOrientation = .landscapeLeft + func + testSetDeviceOrientation_setsLockedOrientationsOfCaptureConnection_ifCaptureOrientationIsLocked() + { + let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() + var photoSetVideoOrientationCalled = false + mockPhotoCaptureConnection.setVideoOrientationStub = { orientation in + XCTAssertEqual(orientation, .portraitUpsideDown) + photoSetVideoOrientationCalled = true + } - XCTAssertTrue(photoSetVideoOrientationCalled) - XCTAssertTrue(videoSetVideoOrientationCalled) - } + var videoSetVideoOrientationCalled = false + mockVideoCaptureConnection.setVideoOrientationStub = { orientation in + XCTAssertEqual(orientation, .portraitUpsideDown) + videoSetVideoOrientationCalled = true + } - func - testSetDeviceOrientation_setsLockedOrientationsOfCaptureConnection_ifCaptureOrientationIsLocked() - { - let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() - var photoSetVideoOrientationCalled = false - mockPhotoCaptureConnection.setVideoOrientationStub = { orientation in - XCTAssertEqual(orientation, .portraitUpsideDown) - photoSetVideoOrientationCalled = true - } + camera.lockCaptureOrientation(PlatformDeviceOrientation.portraitDown) - var videoSetVideoOrientationCalled = false - mockVideoCaptureConnection.setVideoOrientationStub = { orientation in - XCTAssertEqual(orientation, .portraitUpsideDown) - videoSetVideoOrientationCalled = true - } + camera.deviceOrientation = .landscapeLeft - camera.lockCaptureOrientation(PlatformDeviceOrientation.portraitDown) + XCTAssertTrue(photoSetVideoOrientationCalled) + XCTAssertTrue(videoSetVideoOrientationCalled) + } - camera.deviceOrientation = .landscapeLeft + func testSetDeviceOrientation_doesNotSetOrientations_ifRecordingIsInProgress() { + let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() - XCTAssertTrue(photoSetVideoOrientationCalled) - XCTAssertTrue(videoSetVideoOrientationCalled) - } + camera.startVideoRecording(completion: { _ in }, messengerForStreaming: nil) - func testSetDeviceOrientation_doesNotSetOrientations_ifRecordingIsInProgress() { - let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() + mockPhotoCaptureConnection.setVideoOrientationStub = { _ in XCTFail() } + mockVideoCaptureConnection.setVideoOrientationStub = { _ in XCTFail() } - camera.startVideoRecording(completion: { _ in }, messengerForStreaming: nil) + camera.deviceOrientation = .landscapeLeft + } - mockPhotoCaptureConnection.setVideoOrientationStub = { _ in XCTFail() } - mockVideoCaptureConnection.setVideoOrientationStub = { _ in XCTFail() } + func testSetDeviceOrientation_doesNotSetOrientations_forDuplicateUpdates() { + let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() + var photoSetVideoOrientationCallCount = 0 + mockPhotoCaptureConnection.setVideoOrientationStub = { _ in + photoSetVideoOrientationCallCount += 1 + } - camera.deviceOrientation = .landscapeLeft - } + var videoSetVideoOrientationCallCount = 0 + mockVideoCaptureConnection.setVideoOrientationStub = { _ in + videoSetVideoOrientationCallCount += 1 + } - func testSetDeviceOrientation_doesNotSetOrientations_forDuplicateUpdates() { - let (camera, mockPhotoCaptureConnection, mockVideoCaptureConnection) = createCamera() - var photoSetVideoOrientationCallCount = 0 - mockPhotoCaptureConnection.setVideoOrientationStub = { _ in - photoSetVideoOrientationCallCount += 1 - } + camera.deviceOrientation = .landscapeRight + camera.deviceOrientation = .landscapeRight - var videoSetVideoOrientationCallCount = 0 - mockVideoCaptureConnection.setVideoOrientationStub = { _ in - videoSetVideoOrientationCallCount += 1 + XCTAssertEqual(photoSetVideoOrientationCallCount, 1) + XCTAssertEqual(videoSetVideoOrientationCallCount, 1) } - - camera.deviceOrientation = .landscapeRight - camera.deviceOrientation = .landscapeRight - - XCTAssertEqual(photoSetVideoOrientationCallCount, 1) - XCTAssertEqual(videoSetVideoOrientationCallCount, 1) } -} +#endif diff --git a/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockCamera.swift b/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockCamera.swift index 569f55630155..cdd28d5b975c 100644 --- a/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockCamera.swift +++ b/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockCamera.swift @@ -23,7 +23,7 @@ final class MockCamera: NSObject, Camera { var resumeVideoRecordingStub: (() -> Void)? var stopVideoRecordingStub: ((@escaping (Result) -> Void) -> Void)? var captureToFileStub: ((@escaping (Result) -> Void) -> Void)? - var setDeviceOrientationStub: ((UIDeviceOrientation) -> Void)? + var setDeviceOrientationStub: ((PlatformDeviceOrientation) -> Void)? var lockCaptureOrientationStub: ((PlatformDeviceOrientation) -> Void)? var unlockCaptureOrientationStub: (() -> Void)? var setImageFileFormatStub: ((PlatformImageFileFormat) -> Void)? @@ -69,7 +69,7 @@ final class MockCamera: NSObject, Camera { var isPreviewPaused: Bool = false var isStreamingImages: Bool = false - var deviceOrientation: UIDeviceOrientation { + var deviceOrientation: PlatformDeviceOrientation { get { preconditionFailure("Attempted to access unimplemented property: deviceOrientation") } diff --git a/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockDeviceOrientationProvider.swift b/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockDeviceOrientationProvider.swift index 034eafc4d184..0716143ab432 100644 --- a/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockDeviceOrientationProvider.swift +++ b/packages/camera/camera_avfoundation/darwin/Tests/Mocks/MockDeviceOrientationProvider.swift @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import UIKit +#if os(iOS) + import UIKit -@testable import camera_avfoundation + @testable import camera_avfoundation -final class MockDeviceOrientationProvider: NSObject, DeviceOrientationProvider { - var orientationStub: (() -> UIDeviceOrientation)? + final class MockDeviceOrientationProvider: NSObject, DeviceOrientationProvider { + var orientationStub: (() -> UIDeviceOrientation)? - var orientation: UIDeviceOrientation { - return orientationStub?() ?? .unknown + var orientation: UIDeviceOrientation { + return orientationStub?() ?? .unknown + } } -} +#endif diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/Camera.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/Camera.swift index 02e9503f6adc..116ae31ee8cd 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/Camera.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/Camera.swift @@ -22,7 +22,7 @@ protocol Camera: FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate, var isPreviewPaused: Bool { get } var isStreamingImages: Bool { get } - var deviceOrientation: UIDeviceOrientation { get set } + var deviceOrientation: PlatformDeviceOrientation { get set } var minimumAvailableZoomFactor: CGFloat { get } var maximumAvailableZoomFactor: CGFloat { get } diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift index 83f8d40555cf..0caa6062c4cc 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift @@ -4,7 +4,9 @@ import AVFoundation import CoreMedia -import UIKit +#if os(iOS) + import UIKit +#endif /// Factory block returning an FLTCaptureDevice. /// Used in tests to inject a video capture device into DefaultCamera. @@ -34,9 +36,11 @@ class CameraConfiguration { var assetWriterFactory: AssetWriterFactory var inputPixelBufferAdaptorFactory: InputPixelBufferAdaptorFactory var videoDimensionsConverter: VideoDimensionsConverter - var deviceOrientationProvider: DeviceOrientationProvider + #if os(iOS) + var deviceOrientationProvider: DeviceOrientationProvider + #endif let initialCameraName: String - var orientation: UIDeviceOrientation + var orientation: PlatformDeviceOrientation init( mediaSettings: PlatformMediaSettings, @@ -57,8 +61,12 @@ class CameraConfiguration { self.audioCaptureSession = captureSessionFactory() self.captureDeviceInputFactory = captureDeviceInputFactory self.initialCameraName = initialCameraName - self.orientation = UIDevice.current.orientation - self.deviceOrientationProvider = DefaultDeviceOrientationProvider() + #if os(iOS) + self.orientation = getPigeonDeviceOrientation(for: UIDevice.current.orientation) + self.deviceOrientationProvider = DefaultDeviceOrientationProvider() + #else + self.orientation = .portraitUp + #endif self.videoDimensionsConverter = { format in return CMVideoFormatDescriptionGetDimensions(format.formatDescription) diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift index 136c05f18d58..7deca9f7f31c 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift @@ -67,18 +67,22 @@ public final class CameraPlugin: NSObject, FlutterPlugin { captureSessionQueue.setSpecific( key: captureSessionQueueSpecificKey, value: captureSessionQueueSpecificValue) - UIDevice.current.beginGeneratingDeviceOrientationNotifications() - NotificationCenter.default.addObserver( - forName: UIDevice.orientationDidChangeNotification, - object: UIDevice.current, - queue: .main - ) { [weak self] notification in - self?.orientationChanged(notification) - } + #if os(iOS) + UIDevice.current.beginGeneratingDeviceOrientationNotifications() + NotificationCenter.default.addObserver( + forName: UIDevice.orientationDidChangeNotification, + object: UIDevice.current, + queue: .main + ) { [weak self] notification in + self?.orientationChanged(notification) + } + #endif } public func detachFromEngine(for registrar: FlutterPluginRegistrar) { - UIDevice.current.endGeneratingDeviceOrientationNotifications() + #if os(iOS) + UIDevice.current.endGeneratingDeviceOrientationNotifications() + #endif } private static func pigeonErrorFromNSError(_ error: NSError) -> PigeonError { @@ -88,35 +92,37 @@ public final class CameraPlugin: NSObject, FlutterPlugin { details: error.domain) } - func orientationChanged(_ notification: Notification) { - guard let device = notification.object as? UIDevice else { return } - let orientation = device.orientation + #if os(iOS) + func orientationChanged(_ notification: Notification) { + guard let device = notification.object as? UIDevice else { return } + let orientation = device.orientation - if orientation == .faceUp || orientation == .faceDown { - // Do not change when oriented flat. - return - } + if orientation == .faceUp || orientation == .faceDown { + // Do not change when oriented flat. + return + } - self.captureSessionQueue.async { [weak self] in - guard let strongSelf = self else { return } - // `Camera.deviceOrientation` must be set on capture session queue. - strongSelf.camera?.deviceOrientation = orientation - // `CameraPlugin.sendDeviceOrientation` can be called on any queue. - strongSelf.sendDeviceOrientation(orientation) + self.captureSessionQueue.async { [weak self] in + guard let strongSelf = self else { return } + // `Camera.deviceOrientation` must be set on capture session queue. + strongSelf.camera?.deviceOrientation = getPigeonDeviceOrientation(for: orientation) + // `CameraPlugin.sendDeviceOrientation` can be called on any queue. + strongSelf.sendDeviceOrientation(orientation) + } } - } - func sendDeviceOrientation(_ orientation: UIDeviceOrientation) { - DispatchQueue.main.async { [weak self] in - self?.globalEventAPI.deviceOrientationChanged( - orientation: getPigeonDeviceOrientation(for: orientation) - ) { _ in - // Ignore errors; this is essentially a broadcast stream, and - // it's fine if the other end doesn't receive the message - // (e.g., if it doesn't currently have a listener set up). + func sendDeviceOrientation(_ orientation: UIDeviceOrientation) { + DispatchQueue.main.async { [weak self] in + self?.globalEventAPI.deviceOrientationChanged( + orientation: getPigeonDeviceOrientation(for: orientation) + ) { _ in + // Ignore errors; this is essentially a broadcast stream, and + // it's fine if the other end doesn't receive the message + // (e.g., if it doesn't currently have a listener set up). + } } } - } + #endif } extension CameraPlugin: CameraApi { @@ -309,7 +315,9 @@ extension CameraPlugin: CameraApi { ) camera.reportInitializationState() - sendDeviceOrientation(UIDevice.current.orientation) + #if os(iOS) + sendDeviceOrientation(UIDevice.current.orientation) + #endif camera.start() completion(.success(())) } diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift index a7dfd4551048..300a2d64a12c 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift @@ -3,7 +3,9 @@ // found in the LICENSE file. import AVFoundation -import UIKit +#if os(iOS) + import UIKit +#endif /// Gets AVCaptureFlashMode from PlatformFlashMode. /// mode - flash mode. @@ -24,44 +26,46 @@ func getAVCaptureFlashMode(for mode: PlatformFlashMode) -> AVCaptureDevice.Flash } } -/// Gets UIDeviceOrientation from its Pigeon representation. -/// orientation - the Pigeon device orientation. -func getUIDeviceOrientation( - for orientation: PlatformDeviceOrientation -) -> UIDeviceOrientation { - switch orientation { - case .portraitDown: - return .portraitUpsideDown - case .landscapeLeft: - return .landscapeLeft - case .landscapeRight: - return .landscapeRight - case .portraitUp: - return .portrait - @unknown default: - assertionFailure("Unknown device orientation") - return .portrait +#if os(iOS) + /// Gets UIDeviceOrientation from its Pigeon representation. + /// orientation - the Pigeon device orientation. + func getUIDeviceOrientation( + for orientation: PlatformDeviceOrientation + ) -> UIDeviceOrientation { + switch orientation { + case .portraitDown: + return .portraitUpsideDown + case .landscapeLeft: + return .landscapeLeft + case .landscapeRight: + return .landscapeRight + case .portraitUp: + return .portrait + @unknown default: + assertionFailure("Unknown device orientation") + return .portrait + } } -} -/// Gets a Pigeon representation of UIDeviceOrientation. -/// orientation - the UIDeviceOrientation. -func getPigeonDeviceOrientation( - for orientation: UIDeviceOrientation -) -> PlatformDeviceOrientation { - switch orientation { - case .portraitUpsideDown: - return .portraitDown - case .landscapeLeft: - return .landscapeLeft - case .landscapeRight: - return .landscapeRight - case .portrait: - return .portraitUp - default: - return .portraitUp + /// Gets a Pigeon representation of UIDeviceOrientation. + /// orientation - the UIDeviceOrientation. + func getPigeonDeviceOrientation( + for orientation: UIDeviceOrientation + ) -> PlatformDeviceOrientation { + switch orientation { + case .portraitUpsideDown: + return .portraitDown + case .landscapeLeft: + return .landscapeLeft + case .landscapeRight: + return .landscapeRight + case .portrait: + return .portraitUp + default: + return .portraitUp + } } -} +#endif /// Gets pixel format from its Pigeon representation. /// imageFormat - the Pigeon image format. diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index d702248a6d7b..85068a286f15 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -55,7 +55,9 @@ final class DefaultCamera: NSObject, Camera { /// Allows for alternate implementations in tests. private let videoDimensionsConverter: VideoDimensionsConverter - private let deviceOrientationProvider: DeviceOrientationProvider + #if os(iOS) + private let deviceOrientationProvider: DeviceOrientationProvider + #endif private let motionManager = CMMotionManager() private(set) var captureDevice: CaptureDevice @@ -81,7 +83,7 @@ final class DefaultCamera: NSObject, Camera { private var imageStreamHandler: ImageStreamHandler? private var previewSize: CGSize? - var deviceOrientation: UIDeviceOrientation { + var deviceOrientation: PlatformDeviceOrientation { didSet { guard deviceOrientation != oldValue else { return } updateOrientation() @@ -122,7 +124,7 @@ final class DefaultCamera: NSObject, Camera { private var fileFormat = PlatformImageFileFormat.jpeg private var imageQuality: Int64 = 100 - private var lockedCaptureOrientation = UIDeviceOrientation.unknown + private var lockedCaptureOrientation: PlatformDeviceOrientation? = nil private var exposureMode = PlatformExposureMode.auto private var focusMode = PlatformFocusMode.auto private var flashMode: PlatformFlashMode @@ -173,7 +175,9 @@ final class DefaultCamera: NSObject, Camera { assetWriterFactory = configuration.assetWriterFactory inputPixelBufferAdaptorFactory = configuration.inputPixelBufferAdaptorFactory videoDimensionsConverter = configuration.videoDimensionsConverter - deviceOrientationProvider = configuration.deviceOrientationProvider + #if os(iOS) + deviceOrientationProvider = configuration.deviceOrientationProvider + #endif captureDevice = videoCaptureDeviceFactory(configuration.initialCameraName) flashMode = captureDevice.hasFlash ? .auto : .off @@ -801,52 +805,53 @@ final class DefaultCamera: NSObject, Camera { private func updateOrientation() { guard !isRecording else { return } - let orientation = - (lockedCaptureOrientation != .unknown) - ? lockedCaptureOrientation - : deviceOrientation + let orientation = lockedCaptureOrientation ?? deviceOrientation updateOrientation(orientation, forCaptureOutput: capturePhotoOutput) updateOrientation(orientation, forCaptureOutput: captureVideoOutput) } private func updateOrientation( - _ orientation: UIDeviceOrientation, forCaptureOutput captureOutput: CaptureOutput + _ pigeonOrientation: PlatformDeviceOrientation, forCaptureOutput captureOutput: CaptureOutput ) { - if let connection = captureOutput.connection(with: .video), - connection.isVideoOrientationSupported - { - connection.videoOrientation = videoOrientation(forDeviceOrientation: orientation) - } + #if os(iOS) + let orientation = getUIDeviceOrientation(for: pigeonOrientation) + if let connection = captureOutput.connection(with: .video), + connection.isVideoOrientationSupported + { + connection.videoOrientation = videoOrientation(forDeviceOrientation: orientation) + } + #endif } - private func videoOrientation(forDeviceOrientation deviceOrientation: UIDeviceOrientation) - -> AVCaptureVideoOrientation - { - switch deviceOrientation { - case .portrait: - return .portrait - case .landscapeLeft: - return .landscapeRight - case .landscapeRight: - return .landscapeLeft - case .portraitUpsideDown: - return .portraitUpsideDown - default: - return .portrait + #if os(iOS) + private func videoOrientation(forDeviceOrientation deviceOrientation: UIDeviceOrientation) + -> AVCaptureVideoOrientation + { + switch deviceOrientation { + case .portrait: + return .portrait + case .landscapeLeft: + return .landscapeRight + case .landscapeRight: + return .landscapeLeft + case .portraitUpsideDown: + return .portraitUpsideDown + default: + return .portrait + } } - } + #endif func lockCaptureOrientation(_ pigeonOrientation: PlatformDeviceOrientation) { - let orientation = getUIDeviceOrientation(for: pigeonOrientation) - if lockedCaptureOrientation != orientation { - lockedCaptureOrientation = orientation + if lockedCaptureOrientation != pigeonOrientation { + lockedCaptureOrientation = pigeonOrientation updateOrientation() } } func unlockCaptureOrientation() { - lockedCaptureOrientation = .unknown + lockedCaptureOrientation = nil updateOrientation() } @@ -900,12 +905,19 @@ final class DefaultCamera: NSObject, Camera { return } - let orientation = UIDevice.current.orientation - try? captureDevice.lockForConfiguration() - // A nil point resets to the center. - let exposurePoint = cgPoint( - for: point ?? PlatformPoint(x: 0.5, y: 0.5), withOrientation: orientation) - captureDevice.exposurePointOfInterest = exposurePoint + #if os(iOS) + let orientation = UIDevice.current.orientation + try? captureDevice.lockForConfiguration() + // A nil point resets to the center. + let exposurePoint = cgPoint( + for: point ?? PlatformPoint(x: 0.5, y: 0.5), withOrientation: orientation) + captureDevice.exposurePointOfInterest = exposurePoint + #else + try? captureDevice.lockForConfiguration() + captureDevice.exposurePointOfInterest = CGPoint( + x: (point ?? PlatformPoint(x: 0.5, y: 0.5)).x, + y: (point ?? PlatformPoint(x: 0.5, y: 0.5)).y) + #endif captureDevice.unlockForConfiguration() // Retrigger auto exposure applyExposureMode() @@ -930,13 +942,20 @@ final class DefaultCamera: NSObject, Camera { return } - let orientation = deviceOrientationProvider.orientation - try? captureDevice.lockForConfiguration() - // A nil point resets to the center. - captureDevice.focusPointOfInterest = - cgPoint( - for: point ?? PlatformPoint(x: 0.5, y: 0.5), - withOrientation: orientation) + #if os(iOS) + let orientation = deviceOrientationProvider.orientation + try? captureDevice.lockForConfiguration() + // A nil point resets to the center. + captureDevice.focusPointOfInterest = + cgPoint( + for: point ?? PlatformPoint(x: 0.5, y: 0.5), + withOrientation: orientation) + #else + try? captureDevice.lockForConfiguration() + captureDevice.focusPointOfInterest = CGPoint( + x: (point ?? PlatformPoint(x: 0.5, y: 0.5)).x, + y: (point ?? PlatformPoint(x: 0.5, y: 0.5)).y) + #endif captureDevice.unlockForConfiguration() // Retrigger auto focus @@ -970,32 +989,34 @@ final class DefaultCamera: NSObject, Camera { captureDevice.unlockForConfiguration() } - private func cgPoint( - for point: PlatformPoint, withOrientation orientation: UIDeviceOrientation - ) - -> CGPoint - { - var x = point.x - var y = point.y - switch orientation { - case .portrait: // 90 ccw - y = 1 - point.x - x = point.y - case .portraitUpsideDown: // 90 cw - x = 1 - point.y - y = point.x - case .landscapeRight: // 180 - x = 1 - point.x - y = 1 - point.y - case .landscapeLeft: - // No rotation required - break - default: - // No rotation required - break + #if os(iOS) + private func cgPoint( + for point: PlatformPoint, withOrientation orientation: UIDeviceOrientation + ) + -> CGPoint + { + var x = point.x + var y = point.y + switch orientation { + case .portrait: // 90 ccw + y = 1 - point.x + x = point.y + case .portraitUpsideDown: // 90 cw + x = 1 - point.y + y = point.x + case .landscapeRight: // 180 + x = 1 - point.x + y = 1 - point.y + case .landscapeLeft: + // No rotation required + break + default: + // No rotation required + break + } + return CGPoint(x: x, y: y) } - return CGPoint(x: x, y: y) - } + #endif func setZoomLevel( _ zoom: CGFloat, withCompletion completion: @escaping (Result) -> Void diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DeviceOrientationProvider.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DeviceOrientationProvider.swift index 2da9298e6104..e8ba8e9a22c2 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DeviceOrientationProvider.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DeviceOrientationProvider.swift @@ -2,19 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import UIKit +#if os(iOS) + import UIKit -/// A protocol which provides the current device orientation. -/// It exists to allow replacing UIDevice in tests. -protocol DeviceOrientationProvider { - /// Returns the physical orientation of the device. - var orientation: UIDeviceOrientation { get } -} + /// A protocol which provides the current device orientation. + /// It exists to allow replacing UIDevice in tests. + protocol DeviceOrientationProvider { + /// Returns the physical orientation of the device. + var orientation: UIDeviceOrientation { get } + } -/// A default implementation of DeviceOrientationProvider which uses orientation -/// of the current device from UIDevice. -@objc public class DefaultDeviceOrientationProvider: NSObject, DeviceOrientationProvider { - @objc public var orientation: UIDeviceOrientation { - return UIDevice.current.orientation + /// A default implementation of DeviceOrientationProvider which uses orientation + /// of the current device from UIDevice. + @objc public class DefaultDeviceOrientationProvider: NSObject, DeviceOrientationProvider { + @objc public var orientation: UIDeviceOrientation { + return UIDevice.current.orientation + } } -} +#endif From 358089f73bb797490f19904ade19d1a786b78477 Mon Sep 17 00:00:00 2001 From: Mairramer Date: Sat, 25 Jul 2026 11:03:53 -0300 Subject: [PATCH 2/3] style: fix formatting and whitespace in camera AVFoundation Darwin sources and tests --- .../darwin/Tests/CameraOrientationTests.swift | 6 ++++-- .../Sources/camera_avfoundation/CameraConfiguration.swift | 1 + .../Sources/camera_avfoundation/CameraProperties.swift | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift b/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift index e932c0ee4872..1bc8b036494a 100644 --- a/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift +++ b/packages/camera/camera_avfoundation/darwin/Tests/CameraOrientationTests.swift @@ -64,7 +64,8 @@ import XCTest waitForQueueRoundTrip(with: captureSessionQueue) } - private func createMockNotification(for deviceOrientation: UIDeviceOrientation) -> Notification { + private func createMockNotification(for deviceOrientation: UIDeviceOrientation) -> Notification + { let mockDevice = MockUIDevice() mockDevice.mockOrientation = deviceOrientation return Notification(name: Notification.Name("orientation_test"), object: mockDevice) @@ -73,7 +74,8 @@ import XCTest func testOrientationNotifications() { let (cameraPlugin, _, mockEventAPI, _, _, captureSessionQueue) = createCameraPlugin() - sendOrientation(.portraitUpsideDown, to: cameraPlugin, captureSessionQueue: captureSessionQueue) + sendOrientation( + .portraitUpsideDown, to: cameraPlugin, captureSessionQueue: captureSessionQueue) XCTAssertEqual(mockEventAPI.lastOrientation, .portraitDown) sendOrientation(.portrait, to: cameraPlugin, captureSessionQueue: captureSessionQueue) XCTAssertEqual(mockEventAPI.lastOrientation, .portraitUp) diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift index 0caa6062c4cc..275578e0e06d 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift @@ -4,6 +4,7 @@ import AVFoundation import CoreMedia + #if os(iOS) import UIKit #endif diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift index 300a2d64a12c..07aa835fd291 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift @@ -3,6 +3,7 @@ // found in the LICENSE file. import AVFoundation + #if os(iOS) import UIKit #endif From 610a87eae8b4135a0b130d9d5b19a7584007fe42 Mon Sep 17 00:00:00 2001 From: Mairramer Date: Sat, 25 Jul 2026 11:03:53 -0300 Subject: [PATCH 3/3] style: fix formatting and whitespace in camera AVFoundation Darwin sources and tests --- .../Sources/camera_avfoundation/DefaultCamera.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 85068a286f15..687186e6d053 100644 --- a/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/darwin/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -915,8 +915,8 @@ final class DefaultCamera: NSObject, Camera { #else try? captureDevice.lockForConfiguration() captureDevice.exposurePointOfInterest = CGPoint( - x: (point ?? PlatformPoint(x: 0.5, y: 0.5)).x, - y: (point ?? PlatformPoint(x: 0.5, y: 0.5)).y) + x: point?.x ?? 0.5, + y: point?.y ?? 0.5) #endif captureDevice.unlockForConfiguration() // Retrigger auto exposure @@ -953,8 +953,8 @@ final class DefaultCamera: NSObject, Camera { #else try? captureDevice.lockForConfiguration() captureDevice.focusPointOfInterest = CGPoint( - x: (point ?? PlatformPoint(x: 0.5, y: 0.5)).x, - y: (point ?? PlatformPoint(x: 0.5, y: 0.5)).y) + x: point?.x ?? 0.5, + y: point?.y ?? 0.5) #endif captureDevice.unlockForConfiguration()