Skip to content

Commit 59916a9

Browse files
[camera] Finish converting iOS to Pigeon (#6601)
Converts all remaining Dart->host communication in the iOS implementation to use Pigeon. Given the boilerplate nature of many of the changes, it seemed easiest to just do the remaining calls all at once now that the structure is in place. Some high-level notes: - Many methods used to send the `cameraId` without it ever being used on the native side, so the Pigeon versions do not send them. - `ThreadSafeTextureRegistry` is removed because I discovered that it was masking a bug, so was more trouble than it was worth (see inline comments in PR). - A number of enums have been removed in favor of using the Pigeon-generated enums to pass data from the plugin class to `FLTCam`. - In many cases where the completion callback (previously `result`) was being passed to `FLTCam` in a call, only to have it always just call `result(nil)`, that's now done in the plugin class since it's easier to reason about completions being called when they aren't passed around. (Long term we should consider moving almost all of the rest out, and using `FlutterError*` out params that the plugin class passes to `completion`, but that is more surgery than I wanted to do in this PR.) Completes the iOS portion of flutter/flutter#117905
1 parent 890ec36 commit 59916a9

37 files changed

+3497
-2179
lines changed

packages/camera/camera_avfoundation/CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.9.16
2+
3+
* Converts Dart-to-host communcation to Pigeon.
4+
* Fixes a race condition in camera disposal.
5+
16
## 0.9.15+4
27

38
* Converts host-to-Dart communcation to Pigeon.
@@ -121,11 +126,11 @@
121126

122127
## 0.9.8+5
123128

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

126131
## 0.9.8+4
127132

128-
* Fixes a crash due to sending orientation change events when the engine is torn down.
133+
* Fixes a crash due to sending orientation change events when the engine is torn down.
129134

130135
## 0.9.8+3
131136

packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
E071CF7227B3061B006EF3BA /* FLTCamPhotoCaptureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E071CF7127B3061B006EF3BA /* FLTCamPhotoCaptureTests.m */; };
3030
E071CF7427B31DE4006EF3BA /* FLTCamSampleBufferTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E071CF7327B31DE4006EF3BA /* FLTCamSampleBufferTests.m */; };
3131
E0B0D2BB27DFF2AF00E71E4B /* CameraPermissionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B0D2BA27DFF2AF00E71E4B /* CameraPermissionTests.m */; };
32-
E0C6E2012770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */; };
3332
E0C6E2022770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */; };
3433
E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */; };
3534
E0F95E3D27A32AB900699390 /* CameraPropertiesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */; };
@@ -95,7 +94,6 @@
9594
E071CF7127B3061B006EF3BA /* FLTCamPhotoCaptureTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTCamPhotoCaptureTests.m; sourceTree = "<group>"; };
9695
E071CF7327B31DE4006EF3BA /* FLTCamSampleBufferTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTCamSampleBufferTests.m; sourceTree = "<group>"; };
9796
E0B0D2BA27DFF2AF00E71E4B /* CameraPermissionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraPermissionTests.m; sourceTree = "<group>"; };
98-
E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadSafeTextureRegistryTests.m; sourceTree = "<group>"; };
9997
E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadSafeEventChannelTests.m; sourceTree = "<group>"; };
10098
E0CDBAC027CD9729002561D9 /* CameraTestUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CameraTestUtils.h; sourceTree = "<group>"; };
10199
E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraTestUtils.m; sourceTree = "<group>"; };
@@ -132,7 +130,6 @@
132130
03BB766C2665316900CE5A93 /* Info.plist */,
133131
033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */,
134132
E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */,
135-
E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */,
136133
E04F108527A87CA600573D0C /* FLTSavePhotoDelegateTests.m */,
137134
E071CF7127B3061B006EF3BA /* FLTCamPhotoCaptureTests.m */,
138135
E071CF7327B31DE4006EF3BA /* FLTCamSampleBufferTests.m */,
@@ -449,7 +446,6 @@
449446
E032F250279F5E94009E9028 /* CameraCaptureSessionQueueRaceConditionTests.m in Sources */,
450447
788A065A27B0E02900533D74 /* StreamingTest.m in Sources */,
451448
E0C6E2022770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m in Sources */,
452-
E0C6E2012770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m in Sources */,
453449
E0B0D2BB27DFF2AF00E71E4B /* CameraPermissionTests.m in Sources */,
454450
E01EE4A82799F3A5008C1950 /* QueueUtilsTests.m in Sources */,
455451
);

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,25 @@ - (void)testFixForCaptureSessionQueueNullPointerCrashDueToRaceCondition {
1818
[self expectationWithDescription:@"dispose's result block must be called"];
1919
XCTestExpectation *createExpectation =
2020
[self expectationWithDescription:@"create's result block must be called"];
21-
FlutterMethodCall *disposeCall = [FlutterMethodCall methodCallWithMethodName:@"dispose"
22-
arguments:nil];
23-
FlutterMethodCall *createCall = [FlutterMethodCall
24-
methodCallWithMethodName:@"create"
25-
arguments:@{@"resolutionPreset" : @"medium", @"enableAudio" : @(1)}];
2621
// Mimic a dispose call followed by a create call, which can be triggered by slightly dragging the
2722
// home bar, causing the app to be inactive, and immediately regain active.
28-
[camera handleMethodCall:disposeCall
29-
result:^(id _Nullable result) {
30-
[disposeExpectation fulfill];
31-
}];
32-
[camera createCameraOnSessionQueueWithCreateMethodCall:createCall
33-
result:^(id _Nullable result) {
34-
[createExpectation fulfill];
35-
}];
36-
[self waitForExpectationsWithTimeout:1 handler:nil];
23+
[camera disposeCamera:0
24+
completion:^(FlutterError *_Nullable error) {
25+
[disposeExpectation fulfill];
26+
}];
27+
[camera createCameraOnSessionQueueWithName:@"acamera"
28+
settings:[FCPPlatformMediaSettings
29+
makeWithResolutionPreset:
30+
FCPPlatformResolutionPresetMedium
31+
framesPerSecond:nil
32+
videoBitrate:nil
33+
audioBitrate:nil
34+
enableAudio:YES]
35+
completion:^(NSNumber *_Nullable result,
36+
FlutterError *_Nullable error) {
37+
[createExpectation fulfill];
38+
}];
39+
[self waitForExpectationsWithTimeout:30 handler:nil];
3740
// `captureSessionQueue` must not be nil after `create` call. Otherwise a nil
3841
// `captureSessionQueue` passed into `AVCaptureVideoDataOutput::setSampleBufferDelegate:queue:`
3942
// API will cause a crash.

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,9 @@ - (void)testSetFocusPointWithResult_SetsFocusPointOfInterest {
114114
[_camera setValue:_mockDevice forKey:@"captureDevice"];
115115

116116
// Run test
117-
[_camera
118-
setFocusPointWithResult:^(id _Nullable result) {
119-
}
120-
x:1
121-
y:1];
117+
[_camera setFocusPoint:[FCPPlatformPoint makeWithX:1 y:1]
118+
withCompletion:^(FlutterError *_Nullable error){
119+
}];
122120

123121
// Verify the focus point of interest has been set
124122
OCMVerify([_mockDevice setFocusPointOfInterest:CGPointMake(1, 1)]);

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,24 @@ - (void)testCreate_ShouldCallResultOnMainThread {
2828
OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);
2929

3030
// Set up method call
31-
FlutterMethodCall *call = [FlutterMethodCall
32-
methodCallWithMethodName:@"create"
33-
arguments:@{@"resolutionPreset" : @"medium", @"enableAudio" : @(1)}];
34-
35-
__block id resultValue;
36-
[camera createCameraOnSessionQueueWithCreateMethodCall:call
37-
result:^(id _Nullable result) {
38-
resultValue = result;
39-
[expectation fulfill];
40-
}];
41-
[self waitForExpectationsWithTimeout:1 handler:nil];
31+
__block NSNumber *resultValue;
32+
[camera createCameraOnSessionQueueWithName:@"acamera"
33+
settings:[FCPPlatformMediaSettings
34+
makeWithResolutionPreset:
35+
FCPPlatformResolutionPresetMedium
36+
framesPerSecond:nil
37+
videoBitrate:nil
38+
audioBitrate:nil
39+
enableAudio:YES]
40+
completion:^(NSNumber *_Nullable result,
41+
FlutterError *_Nullable error) {
42+
resultValue = result;
43+
[expectation fulfill];
44+
}];
45+
[self waitForExpectationsWithTimeout:30 handler:nil];
4246

4347
// Verify the result
44-
NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
45-
XCTAssertNotNil(dictionaryResult);
46-
XCTAssert([[dictionaryResult allKeys] containsObject:@"cameraId"]);
48+
XCTAssertNotNil(resultValue);
4749
}
4850

4951
@end

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@ @implementation CameraPreviewPauseTests
1616
- (void)testPausePreviewWithResult_shouldPausePreview {
1717
FLTCam *camera = [[FLTCam alloc] init];
1818

19-
[camera pausePreviewWithResult:^(id _Nullable result){
20-
}];
19+
[camera pausePreview];
2120
XCTAssertTrue(camera.isPreviewPaused);
2221
}
2322

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

27-
[camera resumePreviewWithResult:^(id _Nullable result){
28-
}];
26+
[camera resumePreview];
2927
XCTAssertFalse(camera.isPreviewPaused);
3028
}
3129

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPropertiesTests.m

Lines changed: 21 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,68 +15,39 @@ @implementation CameraPropertiesTests
1515

1616
#pragma mark - flash mode tests
1717

18-
- (void)testFLTGetFLTFlashModeForString {
19-
XCTAssertEqual(FLTFlashModeOff, FLTGetFLTFlashModeForString(@"off"));
20-
XCTAssertEqual(FLTFlashModeAuto, FLTGetFLTFlashModeForString(@"auto"));
21-
XCTAssertEqual(FLTFlashModeAlways, FLTGetFLTFlashModeForString(@"always"));
22-
XCTAssertEqual(FLTFlashModeTorch, FLTGetFLTFlashModeForString(@"torch"));
23-
XCTAssertEqual(FLTFlashModeInvalid, FLTGetFLTFlashModeForString(@"unknown"));
24-
}
25-
26-
- (void)testFLTGetAVCaptureFlashModeForFLTFlashMode {
27-
XCTAssertEqual(AVCaptureFlashModeOff, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeOff));
28-
XCTAssertEqual(AVCaptureFlashModeAuto, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeAuto));
29-
XCTAssertEqual(AVCaptureFlashModeOn, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeAlways));
30-
XCTAssertEqual(-1, FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashModeTorch));
31-
}
32-
33-
#pragma mark - exposure mode tests
34-
35-
- (void)testFCPGetExposureModeForString {
36-
XCTAssertEqual(FCPPlatformExposureModeAuto, FCPGetExposureModeForString(@"auto"));
37-
XCTAssertEqual(FCPPlatformExposureModeLocked, FCPGetExposureModeForString(@"locked"));
38-
}
39-
40-
#pragma mark - focus mode tests
41-
42-
- (void)testFLTGetFLTFocusModeForString {
43-
XCTAssertEqual(FCPPlatformFocusModeAuto, FCPGetFocusModeForString(@"auto"));
44-
XCTAssertEqual(FCPPlatformFocusModeLocked, FCPGetFocusModeForString(@"locked"));
45-
}
46-
47-
#pragma mark - resolution preset tests
48-
49-
- (void)testFLTGetFLTResolutionPresetForString {
50-
XCTAssertEqual(FLTResolutionPresetVeryLow, FLTGetFLTResolutionPresetForString(@"veryLow"));
51-
XCTAssertEqual(FLTResolutionPresetLow, FLTGetFLTResolutionPresetForString(@"low"));
52-
XCTAssertEqual(FLTResolutionPresetMedium, FLTGetFLTResolutionPresetForString(@"medium"));
53-
XCTAssertEqual(FLTResolutionPresetHigh, FLTGetFLTResolutionPresetForString(@"high"));
54-
XCTAssertEqual(FLTResolutionPresetVeryHigh, FLTGetFLTResolutionPresetForString(@"veryHigh"));
55-
XCTAssertEqual(FLTResolutionPresetUltraHigh, FLTGetFLTResolutionPresetForString(@"ultraHigh"));
56-
XCTAssertEqual(FLTResolutionPresetMax, FLTGetFLTResolutionPresetForString(@"max"));
57-
XCTAssertEqual(FLTResolutionPresetInvalid, FLTGetFLTResolutionPresetForString(@"unknown"));
18+
- (void)testFCPGetAVCaptureFlashModeForPigeonFlashMode {
19+
XCTAssertEqual(AVCaptureFlashModeOff,
20+
FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeOff));
21+
XCTAssertEqual(AVCaptureFlashModeAuto,
22+
FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeAuto));
23+
XCTAssertEqual(AVCaptureFlashModeOn,
24+
FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeAlways));
25+
XCTAssertThrows(FCPGetAVCaptureFlashModeForPigeonFlashMode(FCPPlatformFlashModeTorch));
5826
}
5927

6028
#pragma mark - video format tests
6129

62-
- (void)testFLTGetVideoFormatFromString {
63-
XCTAssertEqual(kCVPixelFormatType_32BGRA, FLTGetVideoFormatFromString(@"bgra8888"));
30+
- (void)testFCPGetPixelFormatForPigeonFormat {
31+
XCTAssertEqual(kCVPixelFormatType_32BGRA,
32+
FCPGetPixelFormatForPigeonFormat(FCPPlatformImageFormatGroupBgra8888));
6433
XCTAssertEqual(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
65-
FLTGetVideoFormatFromString(@"yuv420"));
66-
XCTAssertEqual(kCVPixelFormatType_32BGRA, FLTGetVideoFormatFromString(@"unknown"));
34+
FCPGetPixelFormatForPigeonFormat(FCPPlatformImageFormatGroupYuv420));
6735
}
6836

6937
#pragma mark - device orientation tests
7038

71-
- (void)testFLTGetUIDeviceOrientationForString {
39+
- (void)testFCPGetUIDeviceOrientationForPigeonDeviceOrientation {
7240
XCTAssertEqual(UIDeviceOrientationPortraitUpsideDown,
73-
FLTGetUIDeviceOrientationForString(@"portraitDown"));
41+
FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
42+
FCPPlatformDeviceOrientationPortraitDown));
7443
XCTAssertEqual(UIDeviceOrientationLandscapeLeft,
75-
FLTGetUIDeviceOrientationForString(@"landscapeLeft"));
44+
FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
45+
FCPPlatformDeviceOrientationLandscapeLeft));
7646
XCTAssertEqual(UIDeviceOrientationLandscapeRight,
77-
FLTGetUIDeviceOrientationForString(@"landscapeRight"));
78-
XCTAssertEqual(UIDeviceOrientationPortrait, FLTGetUIDeviceOrientationForString(@"portraitUp"));
79-
XCTAssertEqual(UIDeviceOrientationUnknown, FLTGetUIDeviceOrientationForString(@"unknown"));
47+
FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
48+
FCPPlatformDeviceOrientationLandscapeRight));
49+
XCTAssertEqual(UIDeviceOrientationPortrait, FCPGetUIDeviceOrientationForPigeonDeviceOrientation(
50+
FCPPlatformDeviceOrientationPortraitUp));
8051
}
8152

8253
- (void)testFLTGetStringForUIDeviceOrientation {
@@ -93,12 +64,4 @@ - (void)testFLTGetStringForUIDeviceOrientation {
9364
FCPGetPigeonDeviceOrientationForOrientation(-1));
9465
}
9566

96-
#pragma mark - file format tests
97-
98-
- (void)testFLTGetFileFormatForString {
99-
XCTAssertEqual(FCPFileFormatJPEG, FCPGetFileFormatFromString(@"jpg"));
100-
XCTAssertEqual(FCPFileFormatHEIF, FCPGetFileFormatFromString(@"heif"));
101-
XCTAssertEqual(FCPFileFormatInvalid, FCPGetFileFormatFromString(@"unknown"));
102-
}
103-
10467
@end

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.m

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ - (void)testResolutionPresetWithBestFormat_mustUpdateCaptureSessionPreset {
3030
OCMExpect([captureDeviceMock lockForConfiguration:NULL]).andReturn(YES);
3131
OCMExpect([videoSessionMock setSessionPreset:expectedPreset]);
3232

33-
FLTCreateCamWithVideoDimensionsForFormat(videoSessionMock, @"max", captureDeviceMock,
33+
FLTCreateCamWithVideoDimensionsForFormat(videoSessionMock, FCPPlatformResolutionPresetMax,
34+
captureDeviceMock,
3435
^CMVideoDimensions(AVCaptureDeviceFormat *format) {
3536
CMVideoDimensions videoDimensions;
3637
videoDimensions.width = 1;
@@ -53,7 +54,7 @@ - (void)testResolutionPresetWithCanSetSessionPresetMax_mustUpdateCaptureSessionP
5354

5455
OCMExpect([videoSessionMock setSessionPreset:expectedPreset]);
5556

56-
FLTCreateCamWithVideoCaptureSession(videoSessionMock, @"max");
57+
FLTCreateCamWithVideoCaptureSession(videoSessionMock, FCPPlatformResolutionPresetMax);
5758

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

73-
FLTCreateCamWithVideoCaptureSession(videoSessionMock, @"ultraHigh");
74+
FLTCreateCamWithVideoCaptureSession(videoSessionMock, FCPPlatformResolutionPresetUltraHigh);
7475

7576
OCMVerifyAll(videoSessionMock);
7677
}

0 commit comments

Comments
 (0)