Add setting to AppRTCMobile for iOS, that can change capture resolution.

To achieve this, several changes needed to be made on both UI and
app logic level.
* Settings view controller is added (modally shown when the settings
button is pressed).
	- From there the user can see the current capture resolution
and select another capture resolution.
* Model class for the capture resolution added.
	- Improves readability and makes separation of concerns cleaner
	- Handles persisting
	- Provides defaults
	- Maps video resolution setting to RTCMediaConstraints dictionary
* Test for the model class

In future it would be possible to extend this CL and add further settings (i.e
bit rate).
Also it would be easy to remove the hardcoded resolutions and use dynamic values
depending on device capability.

BUG=webrtc:6473

Review-Url: https://codereview.webrtc.org/2462623002
Cr-Commit-Position: refs/heads/master@{#14881}
This commit is contained in:
denicija 2016-11-02 02:56:09 -07:00 committed by Commit bot
parent b763e39beb
commit d17d536577
13 changed files with 654 additions and 17 deletions

View File

@ -241,6 +241,12 @@ if (is_ios || (is_mac && target_cpu != "x86")) {
"objc/AppRTCMobile/ios/ARDMainView.m",
"objc/AppRTCMobile/ios/ARDMainViewController.h",
"objc/AppRTCMobile/ios/ARDMainViewController.m",
"objc/AppRTCMobile/ios/ARDMediaConstraintsModel.h",
"objc/AppRTCMobile/ios/ARDMediaConstraintsModel.m",
"objc/AppRTCMobile/ios/ARDMediaConstraintsSettingsStore.h",
"objc/AppRTCMobile/ios/ARDMediaConstraintsSettingsStore.m",
"objc/AppRTCMobile/ios/ARDSettingsViewController.h",
"objc/AppRTCMobile/ios/ARDSettingsViewController.m",
"objc/AppRTCMobile/ios/ARDStatsView.h",
"objc/AppRTCMobile/ios/ARDStatsView.m",
"objc/AppRTCMobile/ios/ARDVideoCallView.h",

View File

@ -23,6 +23,8 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
};
@class ARDAppClient;
@class RTCMediaConstraints;
// The delegate is informed of pertinent events and will be called on the
// main queue.
@protocol ARDAppClientDelegate <NSObject>
@ -56,11 +58,13 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
@property(nonatomic, assign) BOOL shouldGetStats;
@property(nonatomic, readonly) ARDAppClientState state;
@property(nonatomic, weak) id<ARDAppClientDelegate> delegate;
// Convenience constructor since all expected use cases will need a delegate
// in order to receive remote tracks.
- (instancetype)initWithDelegate:(id<ARDAppClientDelegate>)delegate;
// Sets camera constraints.
- (void)setCameraConstraints:(RTCMediaConstraints *)mediaConstraints;
// Establishes a connection with the AppRTC servers for the given room id.
// If |isLoopback| is true, the call will connect to itself.
// If |isAudioOnly| is true, video will be disabled for the call.

View File

@ -101,6 +101,7 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
@implementation ARDAppClient {
RTCFileLogger *_fileLogger;
ARDTimerProxy *_statsTimer;
RTCMediaConstraints *_cameraConstraints;
}
@synthesize shouldGetStats = _shouldGetStats;
@ -321,6 +322,10 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
#endif
}
- (void)setCameraConstraints:(RTCMediaConstraints *)mediaConstraints {
_cameraConstraints = mediaConstraints;
}
#pragma mark - ARDSignalingChannelDelegate
- (void)channel:(id<ARDSignalingChannel>)channel
@ -695,10 +700,10 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
// trying to open a local stream.
#if !TARGET_IPHONE_SIMULATOR
if (!_isAudioOnly) {
RTCMediaConstraints *mediaConstraints =
[self defaultMediaStreamConstraints];
RTCMediaConstraints *cameraConstraints =
[self cameraConstraints];
RTCAVFoundationVideoSource *source =
[_factory avFoundationVideoSourceWithConstraints:mediaConstraints];
[_factory avFoundationVideoSourceWithConstraints:cameraConstraints];
localVideoTrack =
[_factory videoTrackWithSource:source
trackId:kARDVideoTrackId];
@ -737,18 +742,14 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
NSString *valueLevelControl = _shouldUseLevelControl ?
kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse;
NSDictionary *mandatoryConstraints = @{ kRTCMediaConstraintsLevelControl : valueLevelControl };
RTCMediaConstraints* constraints =
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints
optionalConstraints:nil];
RTCMediaConstraints *constraints =
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints
optionalConstraints:nil];
return constraints;
}
- (RTCMediaConstraints *)defaultMediaStreamConstraints {
RTCMediaConstraints* constraints =
[[RTCMediaConstraints alloc]
initWithMandatoryConstraints:nil
optionalConstraints:nil];
return constraints;
- (RTCMediaConstraints *)cameraConstraints {
return _cameraConstraints;
}
- (RTCMediaConstraints *)defaultAnswerConstraints {

View File

@ -19,9 +19,11 @@
#import "ARDAppClient.h"
#import "ARDMainView.h"
#import "ARDMediaConstraintsModel.h"
#import "ARDSettingsViewController.h"
#import "ARDVideoCallViewController.h"
static NSString *barButtonImageString = @"ic_settings_black_24dp.png";
static NSString *const barButtonImageString = @"ic_settings_black_24dp.png";
@interface ARDMainViewController () <
ARDMainViewDelegate,
@ -169,6 +171,16 @@ static NSString *barButtonImageString = @"ic_settings_black_24dp.png";
#pragma mark - Private
- (void)showSettings:(id)sender {
ARDSettingsViewController *settingsController =
[[ARDSettingsViewController alloc] initWithStyle:UITableViewStylePlain
mediaConstraintsModel:[[ARDMediaConstraintsModel alloc] init]];
UINavigationController *navigationController =
[[UINavigationController alloc] initWithRootViewController:settingsController];
[self presentViewControllerAsModal:navigationController];
}
- (void)presentViewControllerAsModal:(UIViewController *)viewController {
[self presentViewController:viewController animated:YES completion:nil];
}
- (void)configureAudioSession {

View File

@ -0,0 +1,22 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import "ARDMediaConstraintsModel.h"
@class ARDMediaConstraintsSettingsStore;
NS_ASSUME_NONNULL_BEGIN
@interface ARDMediaConstraintsModel ()
- (ARDMediaConstraintsSettingsStore *)settingsStore;
- (nullable NSString *)currentVideoResolutionWidthFromStore;
- (nullable NSString *)currentVideoResolutionHeightFromStore;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,60 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Model class for user defined media constraints.
*
* Currently used for streaming media constraints only.
* In future audio media constraints support can be added as well.
* Offers list of avaliable video resolutions that can construct streaming media constraint.
* Exposes methods for reading and storing media constraints from persistent store.
* Also translates current user defined media constraint into RTCMediaConstraints
* dictionary.
*/
@interface ARDMediaConstraintsModel : NSObject
/**
* Returns array of available capture resoultions.
*
* The capture resolutions are represented as strings in the following format
* [width]x[height]
*/
- (NSArray<NSString *> *)availableVideoResoultionsMediaConstraints;
/**
* Returns current video resolution media constraint string.
* If no constraint is in store, default value of 640x480 is returned.
* When defaulting to value, the default is saved in store for consistency reasons.
*/
- (NSString *)currentVideoResoultionConstraintFromStore;
/**
* Stores the provided video resolution media constraint string into the store.
*
* If the provided constraint is no part of the available video resolutions
* the store operation will not be executed and NO will be returned.
* @param constraint the string to be stored.
* @return YES/NO depending on success.
*/
- (BOOL)storeVideoResoultionConstraint:(NSString *)constraint;
/**
* Converts the current media constraints from store into dictionary with RTCMediaConstraints
* values.
*
* @return NSDictionary with RTC width and height parameters
*/
- (nullable NSDictionary *)currentMediaConstraintFromStoreAsRTCDictionary;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,104 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import "ARDMediaConstraintsModel+Private.h"
#import "ARDMediaConstraintsSettingsStore.h"
#import "WebRTC/RTCMediaConstraints.h"
NS_ASSUME_NONNULL_BEGIN
static NSArray<NSString *> *videoResolutionsStaticValues() {
return @[ @"640x480", @"960x540", @"1280x720" ];
}
@interface ARDMediaConstraintsModel () {
ARDMediaConstraintsSettingsStore *_settingsStore;
}
@end
@implementation ARDMediaConstraintsModel
- (NSArray<NSString *> *)availableVideoResoultionsMediaConstraints {
return videoResolutionsStaticValues();
}
- (NSString *)currentVideoResoultionConstraintFromStore {
NSString *constraint = [[self settingsStore] videoResolutionConstraintsSetting];
if (!constraint) {
constraint = [self defaultVideoResolutionMediaConstraint];
// To ensure consistency add the default to the store.
[[self settingsStore] setVideoResolutionConstraintsSetting:constraint];
}
return constraint;
}
- (BOOL)storeVideoResoultionConstraint:(NSString *)constraint {
if (![[self availableVideoResoultionsMediaConstraints] containsObject:constraint]) {
return NO;
}
[[self settingsStore] setVideoResolutionConstraintsSetting:constraint];
return YES;
}
#pragma mark - Testable
- (ARDMediaConstraintsSettingsStore *)settingsStore {
if (!_settingsStore) {
_settingsStore = [[ARDMediaConstraintsSettingsStore alloc] init];
}
return _settingsStore;
}
- (nullable NSString *)currentVideoResolutionWidthFromStore {
NSString *mediaConstraintFromStore = [self currentVideoResoultionConstraintFromStore];
return [self videoResolutionComponentAtIndex:0 inConstraintsString:mediaConstraintFromStore];
}
- (nullable NSString *)currentVideoResolutionHeightFromStore {
NSString *mediaConstraintFromStore = [self currentVideoResoultionConstraintFromStore];
return [self videoResolutionComponentAtIndex:1 inConstraintsString:mediaConstraintFromStore];
}
#pragma mark -
- (NSString *)defaultVideoResolutionMediaConstraint {
return videoResolutionsStaticValues()[0];
}
- (nullable NSString *)videoResolutionComponentAtIndex:(int)index
inConstraintsString:(NSString *)constraint {
if (index != 0 && index != 1) {
return nil;
}
NSArray *components = [constraint componentsSeparatedByString:@"x"];
if (components.count != 2) {
return nil;
}
return components[index];
}
#pragma mark - Conversion to RTCMediaConstraints
- (nullable NSDictionary *)currentMediaConstraintFromStoreAsRTCDictionary {
NSDictionary *mediaConstraintsDictionary = nil;
NSString *widthConstraint = [self currentVideoResolutionWidthFromStore];
NSString *heightConstraint = [self currentVideoResolutionHeightFromStore];
if (widthConstraint && heightConstraint) {
mediaConstraintsDictionary = @{
kRTCMediaConstraintsMinWidth : widthConstraint,
kRTCMediaConstraintsMinHeight : heightConstraint
};
}
return mediaConstraintsDictionary;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,34 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Light-weight persistent store for media constraints user settings.
*
* It will persist between application launches and application updates.
*/
@interface ARDMediaConstraintsSettingsStore : NSObject
/**
* Returns current video resolution media constraint string stored in the store.
*/
- (nullable NSString *)videoResolutionConstraintsSetting;
/**
* Stores the provided value as video resolution media constraint.
* @param value the string to be stored
*/
- (void)setVideoResolutionConstraintsSetting:(NSString *)value;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,29 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import "ARDMediaConstraintsSettingsStore.h"
static NSString *const kUserDefaultsMediaConstraintsKey =
@"rtc_video_resolution_media_constraints_key";
NS_ASSUME_NONNULL_BEGIN
@implementation ARDMediaConstraintsSettingsStore
- (nullable NSString *)videoResolutionConstraintsSetting {
return [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultsMediaConstraintsKey];
}
- (void)setVideoResolutionConstraintsSetting:(NSString *)constraintsString {
[[NSUserDefaults standardUserDefaults] setObject:constraintsString
forKey:kUserDefaultsMediaConstraintsKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,37 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <UIKit/UIKit.h>
@class ARDMediaConstraintsModel;
NS_ASSUME_NONNULL_BEGIN
/**
* Displays settings options.
*/
@interface ARDSettingsViewController : UITableViewController
/**
* Creates new instance.
*
* @param style the table view style that should be used
* @param mediaConstraintsModel model class for the media constraints settings.
*/
- (instancetype)initWithStyle:(UITableViewStyle)style
mediaConstraintsModel:(ARDMediaConstraintsModel *)mediaConstraintsModel;
#pragma mark - Unavailable
- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype) new NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,162 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import "ARDSettingsViewController.h"
#import "ARDMediaConstraintsModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface ARDSettingsViewController () {
ARDMediaConstraintsModel *_mediaConstraintsModel;
}
@end
@implementation ARDSettingsViewController
- (instancetype)initWithStyle:(UITableViewStyle)style
mediaConstraintsModel:(ARDMediaConstraintsModel *)mediaConstraintsModel {
self = [super initWithStyle:style];
if (self) {
_mediaConstraintsModel = mediaConstraintsModel;
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Settings";
[self addDoneBarButton];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self selectCurrentlyStoredOrDefaultMediaConstraints];
}
#pragma mark - Data source
- (NSArray<NSString *> *)mediaConstraintsArray {
return _mediaConstraintsModel.availableVideoResoultionsMediaConstraints;
}
#pragma mark -
- (void)addDoneBarButton {
UIBarButtonItem *barItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(dismissModally:)];
self.navigationItem.leftBarButtonItem = barItem;
}
- (void)selectCurrentlyStoredOrDefaultMediaConstraints {
NSString *currentSelection = [_mediaConstraintsModel currentVideoResoultionConstraintFromStore];
NSUInteger indexOfSelection = [[self mediaConstraintsArray] indexOfObject:currentSelection];
NSIndexPath *pathToBeSelected = [NSIndexPath indexPathForRow:indexOfSelection inSection:0];
[self.tableView selectRowAtIndexPath:pathToBeSelected
animated:NO
scrollPosition:UITableViewScrollPositionNone];
// Manully invoke the delegate method because the previous invocation will not.
[self tableView:self.tableView didSelectRowAtIndexPath:pathToBeSelected];
}
#pragma mark - Dismissal of view controller
- (void)dismissModally:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.mediaConstraintsArray.count;
}
#pragma mark - Table view delegate
- (BOOL)sectionIsMediaConstraints:(int)section {
return section == 0;
}
- (BOOL)indexPathIsMediaConstraints:(NSIndexPath *)indexPath {
return [self sectionIsMediaConstraints:indexPath.section];
}
- (nullable NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
if ([self sectionIsMediaConstraints:section]) {
return @"Media constraints";
}
return @"";
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self indexPathIsMediaConstraints:indexPath]) {
return [self mediaConstraintsTableViewCellForTableView:tableView atIndexPath:indexPath];
}
return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"identifier"];
}
- (nullable NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
if ([self indexPathIsMediaConstraints:indexPath]) {
return [self tableView:tableView willDeselectMediaConstraintsRowAtIndexPath:indexPath];
}
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self indexPathIsMediaConstraints:indexPath]) {
[self tableView:tableView didSelectMediaConstraintsCellAtIndexPath:indexPath];
}
}
#pragma mark - Table view delegate(Media Constraints)
- (UITableViewCell *)mediaConstraintsTableViewCellForTableView:(UITableView *)tableView
atIndexPath:(NSIndexPath *)indexPath {
NSString *dequeueIdentifier = @"ARDSettingsMediaConstraintsViewCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:dequeueIdentifier];
}
cell.textLabel.text = self.mediaConstraintsArray[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView
didSelectMediaConstraintsCellAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *mediaConstraintsString = self.mediaConstraintsArray[indexPath.row];
[_mediaConstraintsModel storeVideoResoultionConstraint:mediaConstraintsString];
}
- (NSIndexPath *)tableView:(UITableView *)tableView
willDeselectMediaConstraintsRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *oldSelection = [tableView indexPathForSelectedRow];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:oldSelection];
cell.accessoryType = UITableViewCellAccessoryNone;
return indexPath;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -12,12 +12,13 @@
#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h"
#import "ARDAppClient.h"
#import "ARDMediaConstraintsModel.h"
#import "ARDVideoCallView.h"
#import "WebRTC/RTCAVFoundationVideoSource.h"
#import "WebRTC/RTCDispatcher.h"
#import "WebRTC/RTCLogging.h"
#import "ARDAppClient.h"
#import "ARDVideoCallView.h"
#import "WebRTC/RTCMediaConstraints.h"
@interface ARDVideoCallViewController () <ARDAppClientDelegate,
ARDVideoCallViewDelegate>
@ -45,6 +46,12 @@
if (self = [super init]) {
_delegate = delegate;
_client = [[ARDAppClient alloc] initWithDelegate:self];
ARDMediaConstraintsModel *mediaConstraintsModel = [[ARDMediaConstraintsModel alloc] init];
RTCMediaConstraints *cameraConstraints = [[RTCMediaConstraints alloc]
initWithMandatoryConstraints:nil
optionalConstraints:[mediaConstraintsModel
currentMediaConstraintFromStoreAsRTCDictionary]];
[_client setCameraConstraints:cameraConstraints];
[_client connectToRoomWithId:room
isLoopback:isLoopback
isAudioOnly:isAudioOnly

View File

@ -0,0 +1,159 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import "ARDMediaConstraintsModel+Private.h"
#import "ARDMediaConstraintsSettingsStore.h"
#import "WebRTC/RTCMediaConstraints.h"
#include "webrtc/base/gunit.h"
@interface ARDMediaConstraintsModelTests : NSObject {
ARDMediaConstraintsModel *_model;
}
- (void)testStoringInavlidConstraintReturnsNo;
- (void)testDefaultMediaFromStore;
- (void)testWidthConstraintFromStore;
- (void)testHeightConstraintFromStore;
@end
@implementation ARDMediaConstraintsModelTests
- (instancetype)init {
self = [super init];
if (self) {
_model = [[ARDMediaConstraintsModel alloc] init];
}
return self;
}
- (id)setupMockStoreWithMediaConstraintString:(NSString *)constraintString {
id storeMock = [OCMockObject mockForClass:[ARDMediaConstraintsSettingsStore class]];
[([[storeMock stub] andReturn:constraintString]) videoResolutionConstraintsSetting];
id partialMock = [OCMockObject partialMockForObject:_model];
[[[partialMock stub] andReturn:storeMock] settingsStore];
return storeMock;
}
- (void)testDefaultMediaFromStore {
// given
id storeMock = [self setupMockStoreWithMediaConstraintString:nil];
[[storeMock expect] setVideoResolutionConstraintsSetting:@"640x480"];
// when
NSString *string = [_model currentVideoResoultionConstraintFromStore];
// then
EXPECT_TRUE([string isEqualToString:@"640x480"]);
[storeMock verify];
}
- (void)testStoringInavlidConstraintReturnsNo {
// given
id storeMock = [self setupMockStoreWithMediaConstraintString:@"960x480"];
// when
BOOL result = [_model storeVideoResoultionConstraint:@"960x480"];
// then
EXPECT_TRUE(result);
}
- (void)testWidthConstraintFromStore {
// given
[self setupMockStoreWithMediaConstraintString:@"1270x480"];
// when
NSString *width = [_model currentVideoResolutionWidthFromStore];
// then
EXPECT_TRUE([width isEqualToString:@"1270"]);
}
- (void)testHeightConstraintFromStore {
// given
[self setupMockStoreWithMediaConstraintString:@"960x540"];
// when
NSString *height = [_model currentVideoResolutionHeightFromStore];
// then
EXPECT_TRUE([height isEqualToString:@"540"]);
}
- (void)testConstraintComponentIsNilWhenInvalidConstraintString {
// given
[self setupMockStoreWithMediaConstraintString:@"invalid"];
// when
NSString *width = [_model currentVideoResolutionWidthFromStore];
// then
EXPECT_TRUE(width == nil);
}
- (void)testConstraintsDictionaryIsNilWhenInvalidConstraintString {
// given
[self setupMockStoreWithMediaConstraintString:@"invalid"];
// when
NSDictionary *constraintsDictionary = [_model currentMediaConstraintFromStoreAsRTCDictionary];
// then
EXPECT_TRUE(constraintsDictionary == nil);
}
@end
class ARDMediaConstraintsModelTest : public ::testing::Test {
protected:
ARDMediaConstraintsModelTests *test;
ARDMediaConstraintsModelTest() { test = [[ARDMediaConstraintsModelTests alloc] init]; }
};
TEST_F(ARDMediaConstraintsModelTest, DefaultMediaFromStore) {
@autoreleasepool {
[test testDefaultMediaFromStore];
}
}
TEST_F(ARDMediaConstraintsModelTest, StoringInvalidConstraintsReturnsNo) {
@autoreleasepool {
[test testStoringInavlidConstraintReturnsNo];
}
}
TEST_F(ARDMediaConstraintsModelTest, WidthConstraintFromStore) {
@autoreleasepool {
[test testWidthConstraintFromStore];
}
}
TEST_F(ARDMediaConstraintsModelTest, HeightConstraintFromStore) {
@autoreleasepool {
[test testHeightConstraintFromStore];
}
}
TEST_F(ARDMediaConstraintsModelTest, ConstratintIsNil) {
@autoreleasepool {
[test testConstraintComponentIsNilWhenInvalidConstraintString];
}
}
TEST_F(ARDMediaConstraintsModelTest, DictionaryIsNil) {
@autoreleasepool {
[test testConstraintsDictionaryIsNilWhenInvalidConstraintString];
}
}