-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[Camera] Return all possible cameras on iOS #5636
Changes from 10 commits
53af077
80abba9
efb576c
6ba4bd8
1a6417e
1ca4657
630f489
6a270ad
f851e6f
da3bad7
a315103
d2a096e
df37438
ac861fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
@import camera; | ||
@import camera.Test; | ||
@import XCTest; | ||
@import AVFoundation; | ||
#import <OCMock/OCMock.h> | ||
#import "MockFLTThreadSafeFlutterResult.h" | ||
|
||
@interface AvailableCamerasTest : XCTestCase | ||
@end | ||
|
||
@implementation AvailableCamerasTest | ||
|
||
- (void)testAvailableCamerasShouldReturnAllCamerasOnMultiCameraIPhone { | ||
CameraPlugin *camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil]; | ||
XCTestExpectation *expectation = | ||
[[XCTestExpectation alloc] initWithDescription:@"Result finished"]; | ||
|
||
// iPhone 13 Cameras: | ||
AVCaptureDevice *wideAngleCamera = OCMClassMock([AVCaptureDevice class]); | ||
OCMStub([wideAngleCamera uniqueID]).andReturn(@"0"); | ||
OCMStub([wideAngleCamera position]).andReturn(AVCaptureDevicePositionBack); | ||
|
||
AVCaptureDevice *frontFacingCamera = OCMClassMock([AVCaptureDevice class]); | ||
OCMStub([frontFacingCamera uniqueID]).andReturn(@"1"); | ||
OCMStub([frontFacingCamera position]).andReturn(AVCaptureDevicePositionFront); | ||
|
||
AVCaptureDevice *ultraWideCamera = OCMClassMock([AVCaptureDevice class]); | ||
OCMStub([ultraWideCamera uniqueID]).andReturn(@"2"); | ||
OCMStub([ultraWideCamera position]).andReturn(AVCaptureDevicePositionBack); | ||
|
||
AVCaptureDevice *telephotoCamera = OCMClassMock([AVCaptureDevice class]); | ||
OCMStub([telephotoCamera uniqueID]).andReturn(@"3"); | ||
OCMStub([telephotoCamera position]).andReturn(AVCaptureDevicePositionBack); | ||
|
||
NSMutableArray *requiredTypes = [NSMutableArray array]; | ||
[requiredTypes addObjectsFromArray:@[ | ||
AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeBuiltInTelephotoCamera | ||
]]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is both more readable and more performant (the latter doesn't matter in a test of course, but it's a better practice in general) as:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure 👍 |
||
if (@available(iOS 13.0, *)) { | ||
[requiredTypes addObject:AVCaptureDeviceTypeBuiltInUltraWideCamera]; | ||
} | ||
|
||
id discoverySessionMock = OCMClassMock([AVCaptureDeviceDiscoverySession class]); | ||
OCMStub([discoverySessionMock discoverySessionWithDeviceTypes:requiredTypes | ||
mediaType:AVMediaTypeVideo | ||
position:AVCaptureDevicePositionUnspecified]) | ||
.andReturn(discoverySessionMock); | ||
|
||
NSMutableArray *cameras = [NSMutableArray array]; | ||
[cameras addObjectsFromArray:@[ wideAngleCamera, frontFacingCamera, telephotoCamera ]]; | ||
if (@available(iOS 13.0, *)) { | ||
[cameras addObject:ultraWideCamera]; | ||
} | ||
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]; | ||
|
||
// Verify the result | ||
NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult; | ||
if (@available(iOS 13.0, *)) { | ||
XCTAssertTrue([dictionaryResult count] == 4); | ||
} else { | ||
XCTAssertTrue([dictionaryResult count] == 3); | ||
} | ||
} | ||
- (void)testAvailableCamerasShouldReturnOneCameraOnSingleCameraIPhone { | ||
CameraPlugin *camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil]; | ||
XCTestExpectation *expectation = | ||
[[XCTestExpectation alloc] initWithDescription:@"Result finished"]; | ||
|
||
// iPhone 8 Cameras: | ||
AVCaptureDevice *wideAngleCamera = OCMClassMock([AVCaptureDevice class]); | ||
OCMStub([wideAngleCamera uniqueID]).andReturn(@"0"); | ||
OCMStub([wideAngleCamera position]).andReturn(AVCaptureDevicePositionBack); | ||
|
||
AVCaptureDevice *frontFacingCamera = OCMClassMock([AVCaptureDevice class]); | ||
OCMStub([frontFacingCamera uniqueID]).andReturn(@"1"); | ||
OCMStub([frontFacingCamera position]).andReturn(AVCaptureDevicePositionFront); | ||
|
||
NSMutableArray *requiredTypes = [NSMutableArray array]; | ||
[requiredTypes addObjectsFromArray:@[ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeBuiltInTelephotoCamera | ||
]]; | ||
if (@available(iOS 13.0, *)) { | ||
[requiredTypes addObject:AVCaptureDeviceTypeBuiltInUltraWideCamera]; | ||
} | ||
|
||
id discoverySessionMock = OCMClassMock([AVCaptureDeviceDiscoverySession class]); | ||
OCMStub([discoverySessionMock discoverySessionWithDeviceTypes:requiredTypes | ||
mediaType:AVMediaTypeVideo | ||
position:AVCaptureDevicePositionUnspecified]) | ||
.andReturn(discoverySessionMock); | ||
|
||
NSMutableArray *cameras = [NSMutableArray array]; | ||
[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]; | ||
|
||
// Verify the result | ||
NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult; | ||
XCTAssertTrue([dictionaryResult count] == 2); | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,8 +100,14 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call | |
result:(FLTThreadSafeFlutterResult *)result { | ||
if ([@"availableCameras" isEqualToString:call.method]) { | ||
if (@available(iOS 10.0, *)) { | ||
NSMutableArray *discoveryDevices = [NSMutableArray array]; | ||
[discoveryDevices addObject:AVCaptureDeviceTypeBuiltInWideAngleCamera]; | ||
[discoveryDevices addObject:AVCaptureDeviceTypeBuiltInTelephotoCamera]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(run through clang-format, of course.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
if (@available(iOS 13.0, *)) { | ||
[discoveryDevices addObject:AVCaptureDeviceTypeBuiltInUltraWideCamera]; | ||
} | ||
AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession | ||
discoverySessionWithDeviceTypes:@[ AVCaptureDeviceTypeBuiltInWideAngleCamera ] | ||
discoverySessionWithDeviceTypes:discoveryDevices | ||
mediaType:AVMediaTypeVideo | ||
position:AVCaptureDevicePositionUnspecified]; | ||
NSArray<AVCaptureDevice *> *devices = discoverySession.devices; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returns
See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changelog-style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍