Skip to content

[camera] Finish converting iOS to Pigeon #6601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 24, 2024
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
9 changes: 7 additions & 2 deletions packages/camera/camera_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.9.16

* Converts Dart-to-host communcation to Pigeon.
* Fixes a race condition in camera disposal.

## 0.9.15+4

* Converts host-to-Dart communcation to Pigeon.
Expand Down Expand Up @@ -121,11 +126,11 @@

## 0.9.8+5

* Fixes a regression introduced in 0.9.8+4 where the stream handler is not set.
* Fixes a regression introduced in 0.9.8+4 where the stream handler is not set.

## 0.9.8+4

* Fixes a crash due to sending orientation change events when the engine is torn down.
* Fixes a crash due to sending orientation change events when the engine is torn down.

## 0.9.8+3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
E071CF7227B3061B006EF3BA /* FLTCamPhotoCaptureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E071CF7127B3061B006EF3BA /* FLTCamPhotoCaptureTests.m */; };
E071CF7427B31DE4006EF3BA /* FLTCamSampleBufferTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E071CF7327B31DE4006EF3BA /* FLTCamSampleBufferTests.m */; };
E0B0D2BB27DFF2AF00E71E4B /* CameraPermissionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B0D2BA27DFF2AF00E71E4B /* CameraPermissionTests.m */; };
E0C6E2012770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */; };
E0C6E2022770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */; };
E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */; };
E0F95E3D27A32AB900699390 /* CameraPropertiesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */; };
Expand Down Expand Up @@ -95,7 +94,6 @@
E071CF7127B3061B006EF3BA /* FLTCamPhotoCaptureTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTCamPhotoCaptureTests.m; sourceTree = "<group>"; };
E071CF7327B31DE4006EF3BA /* FLTCamSampleBufferTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTCamSampleBufferTests.m; sourceTree = "<group>"; };
E0B0D2BA27DFF2AF00E71E4B /* CameraPermissionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraPermissionTests.m; sourceTree = "<group>"; };
E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadSafeTextureRegistryTests.m; sourceTree = "<group>"; };
E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadSafeEventChannelTests.m; sourceTree = "<group>"; };
E0CDBAC027CD9729002561D9 /* CameraTestUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CameraTestUtils.h; sourceTree = "<group>"; };
E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraTestUtils.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -132,7 +130,6 @@
03BB766C2665316900CE5A93 /* Info.plist */,
033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */,
E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */,
E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */,
E04F108527A87CA600573D0C /* FLTSavePhotoDelegateTests.m */,
E071CF7127B3061B006EF3BA /* FLTCamPhotoCaptureTests.m */,
E071CF7327B31DE4006EF3BA /* FLTCamSampleBufferTests.m */,
Expand Down Expand Up @@ -449,7 +446,6 @@
E032F250279F5E94009E9028 /* CameraCaptureSessionQueueRaceConditionTests.m in Sources */,
788A065A27B0E02900533D74 /* StreamingTest.m in Sources */,
E0C6E2022770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m in Sources */,
E0C6E2012770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m in Sources */,
E0B0D2BB27DFF2AF00E71E4B /* CameraPermissionTests.m in Sources */,
E01EE4A82799F3A5008C1950 /* QueueUtilsTests.m in Sources */,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,25 @@ - (void)testFixForCaptureSessionQueueNullPointerCrashDueToRaceCondition {
[self expectationWithDescription:@"dispose's result block must be called"];
XCTestExpectation *createExpectation =
[self expectationWithDescription:@"create's result block must be called"];
FlutterMethodCall *disposeCall = [FlutterMethodCall methodCallWithMethodName:@"dispose"
arguments:nil];
FlutterMethodCall *createCall = [FlutterMethodCall
methodCallWithMethodName:@"create"
arguments:@{@"resolutionPreset" : @"medium", @"enableAudio" : @(1)}];
// Mimic a dispose call followed by a create call, which can be triggered by slightly dragging the
// home bar, causing the app to be inactive, and immediately regain active.
[camera handleMethodCall:disposeCall
result:^(id _Nullable result) {
[disposeExpectation fulfill];
}];
[camera createCameraOnSessionQueueWithCreateMethodCall:createCall
result:^(id _Nullable result) {
[createExpectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
[camera disposeCamera:0
completion:^(FlutterError *_Nullable error) {
[disposeExpectation fulfill];
}];
[camera createCameraOnSessionQueueWithName:@"acamera"
settings:[FCPPlatformMediaSettings
makeWithResolutionPreset:
FCPPlatformResolutionPresetMedium
framesPerSecond:nil
videoBitrate:nil
audioBitrate:nil
enableAudio:YES]
completion:^(NSNumber *_Nullable result,
FlutterError *_Nullable error) {
[createExpectation fulfill];
}];
[self waitForExpectationsWithTimeout:30 handler:nil];
// `captureSessionQueue` must not be nil after `create` call. Otherwise a nil
// `captureSessionQueue` passed into `AVCaptureVideoDataOutput::setSampleBufferDelegate:queue:`
// API will cause a crash.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,9 @@ - (void)testSetFocusPointWithResult_SetsFocusPointOfInterest {
[_camera setValue:_mockDevice forKey:@"captureDevice"];

// Run test
[_camera
setFocusPointWithResult:^(id _Nullable result) {
}
x:1
y:1];
[_camera setFocusPoint:[FCPPlatformPoint makeWithX:1 y:1]
withCompletion:^(FlutterError *_Nullable error){
}];

// Verify the focus point of interest has been set
OCMVerify([_mockDevice setFocusPointOfInterest:CGPointMake(1, 1)]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,24 @@ - (void)testCreate_ShouldCallResultOnMainThread {
OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);

// Set up method call
FlutterMethodCall *call = [FlutterMethodCall
methodCallWithMethodName:@"create"
arguments:@{@"resolutionPreset" : @"medium", @"enableAudio" : @(1)}];

__block id resultValue;
[camera createCameraOnSessionQueueWithCreateMethodCall:call
result:^(id _Nullable result) {
resultValue = result;
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
__block NSNumber *resultValue;
[camera createCameraOnSessionQueueWithName:@"acamera"
settings:[FCPPlatformMediaSettings
makeWithResolutionPreset:
FCPPlatformResolutionPresetMedium
framesPerSecond:nil
videoBitrate:nil
audioBitrate:nil
enableAudio:YES]
completion:^(NSNumber *_Nullable result,
FlutterError *_Nullable error) {
resultValue = result;
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:30 handler:nil];

// Verify the result
NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssertNotNil(dictionaryResult);
XCTAssert([[dictionaryResult allKeys] containsObject:@"cameraId"]);
XCTAssertNotNil(resultValue);
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@ @implementation CameraPreviewPauseTests
- (void)testPausePreviewWithResult_shouldPausePreview {
FLTCam *camera = [[FLTCam alloc] init];

[camera pausePreviewWithResult:^(id _Nullable result){
}];
[camera pausePreview];
XCTAssertTrue(camera.isPreviewPaused);
}

- (void)testResumePreviewWithResult_shouldResumePreview {
FLTCam *camera = [[FLTCam alloc] init];

[camera resumePreviewWithResult:^(id _Nullable result){
}];
[camera resumePreview];
XCTAssertFalse(camera.isPreviewPaused);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,68 +15,39 @@ @implementation CameraPropertiesTests

#pragma mark - flash mode tests

- (void)testFLTGetFLTFlashModeForString {
XCTAssertEqual(FLTFlashModeOff, FLTGetFLTFlashModeForString(@"off"));
XCTAssertEqual(FLTFlashModeAuto, FLTGetFLTFlashModeForString(@"auto"));
XCTAssertEqual(FLTFlashModeAlways, FLTGetFLTFlashModeForString(@"always"));
XCTAssertEqual(FLTFlashModeTorch, FLTGetFLTFlashModeForString(@"torch"));
XCTAssertEqual(FLTFlashModeInvalid, FLTGetFLTFlashModeForString(@"unknown"));
}

- (void)testFLTGetAVCaptureFlashModeForFLTFlashMode {
XCTAssertEqual(AVCaptureFlashModeOff, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeOff));
XCTAssertEqual(AVCaptureFlashModeAuto, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeAuto));
XCTAssertEqual(AVCaptureFlashModeOn, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeAlways));
XCTAssertEqual(-1, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeTorch));
}

#pragma mark - exposure mode tests

- (void)testFCPGetExposureModeForString {
XCTAssertEqual(FCPPlatformExposureModeAuto, FCPGetExposureModeForString(@"auto"));
XCTAssertEqual(FCPPlatformExposureModeLocked, FCPGetExposureModeForString(@"locked"));
}

#pragma mark - focus mode tests

- (void)testFLTGetFLTFocusModeForString {
XCTAssertEqual(FCPPlatformFocusModeAuto, FCPGetFocusModeForString(@"auto"));
XCTAssertEqual(FCPPlatformFocusModeLocked, FCPGetFocusModeForString(@"locked"));
}

#pragma mark - resolution preset tests

- (void)testFLTGetFLTResolutionPresetForString {
XCTAssertEqual(FLTResolutionPresetVeryLow, FLTGetFLTResolutionPresetForString(@"veryLow"));
XCTAssertEqual(FLTResolutionPresetLow, FLTGetFLTResolutionPresetForString(@"low"));
XCTAssertEqual(FLTResolutionPresetMedium, FLTGetFLTResolutionPresetForString(@"medium"));
XCTAssertEqual(FLTResolutionPresetHigh, FLTGetFLTResolutionPresetForString(@"high"));
XCTAssertEqual(FLTResolutionPresetVeryHigh, FLTGetFLTResolutionPresetForString(@"veryHigh"));
XCTAssertEqual(FLTResolutionPresetUltraHigh, FLTGetFLTResolutionPresetForString(@"ultraHigh"));
XCTAssertEqual(FLTResolutionPresetMax, FLTGetFLTResolutionPresetForString(@"max"));
XCTAssertEqual(FLTResolutionPresetInvalid, FLTGetFLTResolutionPresetForString(@"unknown"));
- (void)testFCPGetAVCaptureFlashModeForPigeonFlashMode {
XCTAssertEqual(AVCaptureFlashModeOff,
FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeOff));
XCTAssertEqual(AVCaptureFlashModeAuto,
FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeAuto));
XCTAssertEqual(AVCaptureFlashModeOn,
FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeAlways));
XCTAssertThrows(FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeTorch));
}

#pragma mark - video format tests

- (void)testFLTGetVideoFormatFromString {
XCTAssertEqual(kCVPixelFormatType_32BGRA, FLTGetVideoFormatFromString(@"bgra8888"));
- (void)testFCPGetPixelFormatForPigeonFormat {
XCTAssertEqual(kCVPixelFormatType_32BGRA,
FCPGetPixelFormatForPigeonFormat(FCPPlatformImageFormatGroupBgra8888));
XCTAssertEqual(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
FLTGetVideoFormatFromString(@"yuv420"));
XCTAssertEqual(kCVPixelFormatType_32BGRA, FLTGetVideoFormatFromString(@"unknown"));
FCPGetPixelFormatForPigeonFormat(FCPPlatformImageFormatGroupYuv420));
}

#pragma mark - device orientation tests

- (void)testFLTGetUIDeviceOrientationForString {
- (void)testFCPGetUIDeviceOrientationForPigeonDeviceOrientation {
XCTAssertEqual(UIDeviceOrientationPortraitUpsideDown,
FLTGetUIDeviceOrientationForString(@"portraitDown"));
FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
FCPPlatformDeviceOrientationPortraitDown));
XCTAssertEqual(UIDeviceOrientationLandscapeLeft,
FLTGetUIDeviceOrientationForString(@"landscapeLeft"));
FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
FCPPlatformDeviceOrientationLandscapeLeft));
XCTAssertEqual(UIDeviceOrientationLandscapeRight,
FLTGetUIDeviceOrientationForString(@"landscapeRight"));
XCTAssertEqual(UIDeviceOrientationPortrait, FLTGetUIDeviceOrientationForString(@"portraitUp"));
XCTAssertEqual(UIDeviceOrientationUnknown, FLTGetUIDeviceOrientationForString(@"unknown"));
FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
FCPPlatformDeviceOrientationLandscapeRight));
XCTAssertEqual(UIDeviceOrientationPortrait, FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
FCPPlatformDeviceOrientationPortraitUp));
}

- (void)testFLTGetStringForUIDeviceOrientation {
Expand All @@ -93,12 +64,4 @@ - (void)testFLTGetStringForUIDeviceOrientation {
FCPGetPigeonDeviceOrientationForOrientation(-1));
}

#pragma mark - file format tests

- (void)testFLTGetFileFormatForString {
XCTAssertEqual(FCPFileFormatJPEG, FCPGetFileFormatFromString(@"jpg"));
XCTAssertEqual(FCPFileFormatHEIF, FCPGetFileFormatFromString(@"heif"));
XCTAssertEqual(FCPFileFormatInvalid, FCPGetFileFormatFromString(@"unknown"));
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ - (void)testResolutionPresetWithBestFormat_mustUpdateCaptureSessionPreset {
OCMExpect([captureDeviceMock lockForConfiguration:NULL]).andReturn(YES);
OCMExpect([videoSessionMock setSessionPreset:expectedPreset]);

FLTCreateCamWithVideoDimensionsForFormat(videoSessionMock, @"max", captureDeviceMock,
FLTCreateCamWithVideoDimensionsForFormat(videoSessionMock, FCPPlatformResolutionPresetMax,
captureDeviceMock,
^CMVideoDimensions(AVCaptureDeviceFormat *format) {
CMVideoDimensions videoDimensions;
videoDimensions.width = 1;
Expand All @@ -53,7 +54,7 @@ - (void)testResolutionPresetWithCanSetSessionPresetMax_mustUpdateCaptureSessionP

OCMExpect([videoSessionMock setSessionPreset:expectedPreset]);

FLTCreateCamWithVideoCaptureSession(videoSessionMock, @"max");
FLTCreateCamWithVideoCaptureSession(videoSessionMock, FCPPlatformResolutionPresetMax);

OCMVerifyAll(videoSessionMock);
}
Expand All @@ -70,7 +71,7 @@ - (void)testResolutionPresetWithCanSetSessionPresetUltraHigh_mustUpdateCaptureSe
// Expect that setting "ultraHigh" resolutionPreset correctly updates videoCaptureSession.
OCMExpect([videoSessionMock setSessionPreset:expectedPreset]);

FLTCreateCamWithVideoCaptureSession(videoSessionMock, @"ultraHigh");
FLTCreateCamWithVideoCaptureSession(videoSessionMock, FCPPlatformResolutionPresetUltraHigh);

OCMVerifyAll(videoSessionMock);
}
Expand Down
Loading