Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 7978ee8

Browse files
committed
[camera]manages ios camera's orientation states on capture session queue
1 parent f7138f7 commit 7978ee8

5 files changed

Lines changed: 38 additions & 8 deletions

File tree

packages/camera/camera/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.9.4+11
2+
3+
* Manages iOS camera's orientation-related states on a background queue to prevent potential race conditions.
4+
15
## 0.9.4+10
26

37
* iOS performance improvement by moving file writing from the main queue to a background IO queue.

packages/camera/camera/example/ios/RunnerTests/CameraOrientationTests.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,28 @@ - (void)testOrientationNotifications {
4949
OCMVerifyAll(mockMessenger);
5050
}
5151

52+
- (void)testOrientationUpdateMustBeOnCaptureSessionQueue {
53+
XCTestExpectation *queueExpectation = [self
54+
expectationWithDescription:@"Orientation update must happen on the capture session queue"];
55+
56+
CameraPlugin *camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil];
57+
const char *captureSessionQueueSpecific = "capture_session_queue";
58+
dispatch_queue_set_specific(camera.captureSessionQueue, captureSessionQueueSpecific,
59+
(void *)captureSessionQueueSpecific, NULL);
60+
FLTCam *mockCam = OCMClassMock([FLTCam class]);
61+
camera.camera = mockCam;
62+
OCMStub([mockCam setDeviceOrientation:UIDeviceOrientationLandscapeLeft])
63+
.andDo(^(NSInvocation *invocation) {
64+
if (dispatch_get_specific(captureSessionQueueSpecific)) {
65+
[queueExpectation fulfill];
66+
}
67+
});
68+
69+
[camera orientationChanged:
70+
[self createMockNotificationForOrientation:UIDeviceOrientationLandscapeLeft]];
71+
[self waitForExpectationsWithTimeout:1 handler:nil];
72+
}
73+
5274
- (void)rotate:(UIDeviceOrientation)deviceOrientation
5375
expectedChannelOrientation:(NSString *)channelOrientation
5476
cameraPlugin:(CameraPlugin *)cameraPlugin

packages/camera/camera/ios/Classes/CameraPlugin.m

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
@interface CameraPlugin ()
1818
@property(readonly, nonatomic) FLTThreadSafeTextureRegistry *registry;
1919
@property(readonly, nonatomic) NSObject<FlutterBinaryMessenger> *messenger;
20-
@property(readonly, nonatomic) FLTCam *camera;
2120
@property(readonly, nonatomic) FLTThreadSafeMethodChannel *deviceEventMethodChannel;
2221
@end
2322

@@ -69,11 +68,12 @@ - (void)orientationChanged:(NSNotification *)note {
6968
return;
7069
}
7170

72-
if (_camera) {
73-
[_camera setDeviceOrientation:orientation];
74-
}
75-
76-
[self sendDeviceOrientation:orientation];
71+
dispatch_async(self.captureSessionQueue, ^{
72+
// `setDeviceOrientation` must be called on capture session queue
73+
[self.camera setDeviceOrientation:orientation];
74+
// `sendDeviceOrientation` can be called on any queue
75+
[self sendDeviceOrientation:orientation];
76+
});
7777
}
7878

7979
- (void)sendDeviceOrientation:(UIDeviceOrientation)orientation {

packages/camera/camera/ios/Classes/CameraPlugin_Test.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55
// This header is available in the Test module. Import via "@import camera.Test;"
66

77
#import <camera/CameraPlugin.h>
8+
#import <camera/FLTCam.h>
89
#import <camera/FLTThreadSafeFlutterResult.h>
910

1011
/// Methods exposed for unit testing.
1112
@interface CameraPlugin ()
1213

13-
// All FLTCam's state access and capture session related operations should be on run on this queue.
14+
/// All FLTCam's state access and capture session related operations should be on run on this queue.
1415
@property(nonatomic, strong) dispatch_queue_t captureSessionQueue;
1516

17+
/// An internal camera object that manages camera's state and performs camera operations.
18+
@property(nonatomic, strong) FLTCam *camera;
19+
1620
/// Inject @p FlutterTextureRegistry and @p FlutterBinaryMessenger for unit testing.
1721
- (instancetype)initWithRegistry:(NSObject<FlutterTextureRegistry> *)registry
1822
messenger:(NSObject<FlutterBinaryMessenger> *)messenger

packages/camera/camera/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
44
Dart.
55
repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera
66
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
7-
version: 0.9.4+10
7+
version: 0.9.4+11
88

99
environment:
1010
sdk: ">=2.14.0 <3.0.0"

0 commit comments

Comments
 (0)