Skip to content

Commit

Permalink
[camera] Remove iOS thread-safe result class (#6498)
Browse files Browse the repository at this point in the history
`FlutterResult` is thread-safe in all versions of Flutter that this plugin now supports, so the wrapper class to move result calls to the main thread is no longer necessary.
  • Loading branch information
stuartmorgan committed Apr 16, 2024
1 parent 18c4ca4 commit 554f936
Show file tree
Hide file tree
Showing 28 changed files with 283 additions and 583 deletions.
4 changes: 4 additions & 0 deletions packages/camera/camera_avfoundation/CHANGELOG.md
@@ -1,3 +1,7 @@
## 0.9.15+1

* Simplifies internal handling of method channel responses.

## 0.9.15

* Adds support to control video FPS and bitrate. See `CameraController.withSettings`.
Expand Down
Expand Up @@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
033B94BE269C40A200B4DF97 /* CameraMethodChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */; };
03BB766B2665316900CE5A93 /* CameraFocusTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 03BB766A2665316900CE5A93 /* CameraFocusTests.m */; };
03F6F8B226CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F6F8B126CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
236906D1621AE863A5B2E770 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 89D82918721FABF772705DB0 /* libPods-Runner.a */; };
25C3919135C3D981E6F800D0 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1944D8072499F3B5E7653D44 /* libPods-RunnerTests.a */; };
Expand All @@ -36,7 +35,6 @@
E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */; };
E0F95E3D27A32AB900699390 /* CameraPropertiesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */; };
E487C86026D686A10034AC92 /* CameraPreviewPauseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E487C85F26D686A10034AC92 /* CameraPreviewPauseTests.m */; };
F6EE622F2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m in Sources */ = {isa = PBXBuildFile; fileRef = F6EE622E2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -68,7 +66,6 @@
03BB766A2665316900CE5A93 /* CameraFocusTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraFocusTests.m; sourceTree = "<group>"; };
03BB766C2665316900CE5A93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
03BB767226653ABE00CE5A93 /* CameraOrientationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraOrientationTests.m; sourceTree = "<group>"; };
03F6F8B126CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThreadSafeFlutterResultTests.m; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
14AE82C910C2A12F2ECB2094 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -106,8 +103,6 @@
E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraTestUtils.m; sourceTree = "<group>"; };
E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraPropertiesTests.m; sourceTree = "<group>"; };
E487C85F26D686A10034AC92 /* CameraPreviewPauseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraPreviewPauseTests.m; sourceTree = "<group>"; };
F63F9EED27143B19002479BF /* MockFLTThreadSafeFlutterResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockFLTThreadSafeFlutterResult.h; sourceTree = "<group>"; };
F6EE622E2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockFLTThreadSafeFlutterResult.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -138,7 +133,6 @@
03BB767226653ABE00CE5A93 /* CameraOrientationTests.m */,
03BB766C2665316900CE5A93 /* Info.plist */,
033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */,
03F6F8B126CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m */,
E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */,
E0C6E1FD2770F01A00EA6AA3 /* ThreadSafeMethodChannelTests.m */,
E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */,
Expand All @@ -150,8 +144,6 @@
E0CDBAC027CD9729002561D9 /* CameraTestUtils.h */,
E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */,
E487C85F26D686A10034AC92 /* CameraPreviewPauseTests.m */,
F6EE622E2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m */,
F63F9EED27143B19002479BF /* MockFLTThreadSafeFlutterResult.h */,
E032F24F279F5E94009E9028 /* CameraCaptureSessionQueueRaceConditionTests.m */,
E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */,
788A065927B0E02900533D74 /* StreamingTest.m */,
Expand Down Expand Up @@ -287,7 +279,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
03BB76672665316900CE5A93 = {
Expand Down Expand Up @@ -445,7 +437,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
03F6F8B226CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m in Sources */,
033B94BE269C40A200B4DF97 /* CameraMethodChannelTests.m in Sources */,
E071CF7227B3061B006EF3BA /* FLTCamPhotoCaptureTests.m in Sources */,
E0F95E3D27A32AB900699390 /* CameraPropertiesTests.m in Sources */,
Expand All @@ -455,7 +446,6 @@
E071CF7427B31DE4006EF3BA /* FLTCamSampleBufferTests.m in Sources */,
E04F108627A87CA600573D0C /* FLTSavePhotoDelegateTests.m in Sources */,
43ED1537282570DE00EB00DE /* AvailableCamerasTest.m in Sources */,
F6EE622F2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m in Sources */,
E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */,
334733EA2668111C00DCC49E /* CameraOrientationTests.m in Sources */,
CEF6611A2B5E36A500D33FD4 /* CameraSessionPresetsTests.m in Sources */,
Expand Down
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Expand Up @@ -7,7 +7,6 @@
@import XCTest;
@import AVFoundation;
#import <OCMock/OCMock.h>
#import "MockFLTThreadSafeFlutterResult.h"

@interface AvailableCamerasTest : XCTestCase
@end
Expand Down Expand Up @@ -56,17 +55,19 @@ - (void)testAvailableCamerasShouldReturnAllCamerasOnMultiCameraIPhone {
}
OCMStub([discoverySessionMock devices]).andReturn([NSArray arrayWithArray:cameras]);

MockFLTThreadSafeFlutterResult *resultObject =
[[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];

// Set up method call
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"availableCameras"
arguments:nil];

[camera handleMethodCallAsync:call result:resultObject];
__block id resultValue;
[camera handleMethodCallAsync:call
result:^(id _Nullable result) {
resultValue = result;
[expectation fulfill];
}];

// Verify the result
NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
if (@available(iOS 13.0, *)) {
XCTAssertTrue([dictionaryResult count] == 4);
} else {
Expand Down Expand Up @@ -104,17 +105,19 @@ - (void)testAvailableCamerasShouldReturnOneCameraOnSingleCameraIPhone {
[cameras addObjectsFromArray:@[ wideAngleCamera, frontFacingCamera ]];
OCMStub([discoverySessionMock devices]).andReturn([NSArray arrayWithArray:cameras]);

MockFLTThreadSafeFlutterResult *resultObject =
[[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];

// Set up method call
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"availableCameras"
arguments:nil];

[camera handleMethodCallAsync:call result:resultObject];
__block id resultValue;
[camera handleMethodCallAsync:call
result:^(id _Nullable result) {
resultValue = result;
[expectation fulfill];
}];

// Verify the result
NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssertTrue([dictionaryResult count] == 2);
}

Expand Down
Expand Up @@ -30,10 +30,9 @@ - (void)testFixForCaptureSessionQueueNullPointerCrashDueToRaceCondition {
[disposeExpectation fulfill];
}];
[camera createCameraOnSessionQueueWithCreateMethodCall:createCall
result:[[FLTThreadSafeFlutterResult alloc]
initWithResult:^(id _Nullable result) {
[createExpectation fulfill];
}]];
result:^(id _Nullable result) {
[createExpectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
// `captureSessionQueue` must not be nil after `create` call. Otherwise a nil
// `captureSessionQueue` passed into `AVCaptureVideoDataOutput::setSampleBufferDelegate:queue:`
Expand Down
Expand Up @@ -114,11 +114,11 @@ - (void)testSetFocusPointWithResult_SetsFocusPointOfInterest {
[_camera setValue:_mockDevice forKey:@"captureDevice"];

// Run test
[_camera setFocusPointWithResult:[[FLTThreadSafeFlutterResult alloc]
initWithResult:^(id _Nullable result){
}]
x:1
y:1];
[_camera
setFocusPointWithResult:^(id _Nullable result) {
}
x:1
y:1];

// Verify the focus point of interest has been set
OCMVerify([_mockDevice setFocusPointOfInterest:CGPointMake(1, 1)]);
Expand Down
Expand Up @@ -7,7 +7,6 @@
@import XCTest;
@import AVFoundation;
#import <OCMock/OCMock.h>
#import "MockFLTThreadSafeFlutterResult.h"

@interface CameraMethodChannelTests : XCTestCase
@end
Expand All @@ -28,19 +27,21 @@ - (void)testCreate_ShouldCallResultOnMainThread {
OCMStub([avCaptureSessionMock alloc]).andReturn(avCaptureSessionMock);
OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);

MockFLTThreadSafeFlutterResult *resultObject =
[[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];

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

[camera createCameraOnSessionQueueWithCreateMethodCall:call result:resultObject];
__block id resultValue;
[camera createCameraOnSessionQueueWithCreateMethodCall:call
result:^(id _Nullable result) {
resultValue = result;
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];

// Verify the result
NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssertNotNil(dictionaryResult);
XCTAssert([[dictionaryResult allKeys] containsObject:@"cameraId"]);
}
Expand Down
Expand Up @@ -7,7 +7,6 @@
@import XCTest;
@import AVFoundation;
#import <OCMock/OCMock.h>
#import "MockFLTThreadSafeFlutterResult.h"

@interface CameraPreviewPauseTests : XCTestCase
@end
Expand All @@ -16,17 +15,17 @@ @implementation CameraPreviewPauseTests

- (void)testPausePreviewWithResult_shouldPausePreview {
FLTCam *camera = [[FLTCam alloc] init];
MockFLTThreadSafeFlutterResult *resultObject = [[MockFLTThreadSafeFlutterResult alloc] init];

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

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

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

Expand Down

0 comments on commit 554f936

Please sign in to comment.