Move setting switches in AppRTCMobile to Settings screen
All setting switches except "Loopback mode" is now in the Settings screen instead of the main screen. They are also persisted across app launches. Bug: webrtc:7748 Change-Id: Iafd84e5e39639770118e2503148d1bf7fb9c3d8d Reviewed-on: https://chromium-review.googlesource.com/527034 Commit-Queue: Magnus Jedvert <magjed@webrtc.org> Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Cr-Commit-Position: refs/heads/master@{#18626}
This commit is contained in:
committed by
Commit Bot
parent
7c303907a4
commit
e150058236
@ -42,9 +42,6 @@
|
||||
@property(nonatomic, strong) NSURL *webSocketURL;
|
||||
@property(nonatomic, strong) NSURL *webSocketRestURL;
|
||||
@property(nonatomic, readonly) BOOL isLoopback;
|
||||
@property(nonatomic, readonly) BOOL isAudioOnly;
|
||||
@property(nonatomic, readonly) BOOL shouldMakeAecDump;
|
||||
@property(nonatomic, readonly) BOOL shouldUseLevelControl;
|
||||
|
||||
@property(nonatomic, strong)
|
||||
RTCMediaConstraints *defaultPeerConnectionConstraints;
|
||||
|
||||
@ -70,16 +70,9 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
|
||||
// Establishes a connection with the AppRTC servers for the given room id.
|
||||
// |settings| is an object containing settings such as video codec for the call.
|
||||
// If |isLoopback| is true, the call will connect to itself.
|
||||
// If |isAudioOnly| is true, video will be disabled for the call.
|
||||
// If |shouldMakeAecDump| is true, an aecdump will be created for the call.
|
||||
// If |shouldUseLevelControl| is true, the level controller will be used
|
||||
// in the call.
|
||||
- (void)connectToRoomWithId:(NSString *)roomId
|
||||
settings:(ARDSettingsModel *)settings
|
||||
isLoopback:(BOOL)isLoopback
|
||||
isAudioOnly:(BOOL)isAudioOnly
|
||||
shouldMakeAecDump:(BOOL)shouldMakeAecDump
|
||||
shouldUseLevelControl:(BOOL)shouldUseLevelControl;
|
||||
isLoopback:(BOOL)isLoopback;
|
||||
|
||||
// Disconnects from the AppRTC servers and any connected clients.
|
||||
- (void)disconnect;
|
||||
|
||||
@ -126,9 +126,6 @@ static int const kKbpsMultiplier = 1000;
|
||||
@synthesize defaultPeerConnectionConstraints =
|
||||
_defaultPeerConnectionConstraints;
|
||||
@synthesize isLoopback = _isLoopback;
|
||||
@synthesize isAudioOnly = _isAudioOnly;
|
||||
@synthesize shouldMakeAecDump = _shouldMakeAecDump;
|
||||
@synthesize shouldUseLevelControl = _shouldUseLevelControl;
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithDelegate:nil];
|
||||
@ -214,17 +211,11 @@ static int const kKbpsMultiplier = 1000;
|
||||
|
||||
- (void)connectToRoomWithId:(NSString *)roomId
|
||||
settings:(ARDSettingsModel *)settings
|
||||
isLoopback:(BOOL)isLoopback
|
||||
isAudioOnly:(BOOL)isAudioOnly
|
||||
shouldMakeAecDump:(BOOL)shouldMakeAecDump
|
||||
shouldUseLevelControl:(BOOL)shouldUseLevelControl {
|
||||
isLoopback:(BOOL)isLoopback {
|
||||
NSParameterAssert(roomId.length);
|
||||
NSParameterAssert(_state == kARDAppClientStateDisconnected);
|
||||
_settings = settings;
|
||||
_isLoopback = isLoopback;
|
||||
_isAudioOnly = isAudioOnly;
|
||||
_shouldMakeAecDump = shouldMakeAecDump;
|
||||
_shouldUseLevelControl = shouldUseLevelControl;
|
||||
self.state = kARDAppClientStateConnecting;
|
||||
|
||||
#if defined(WEBRTC_IOS)
|
||||
@ -569,7 +560,7 @@ static int const kKbpsMultiplier = 1000;
|
||||
}
|
||||
|
||||
// Start aecdump diagnostic recording.
|
||||
if (_shouldMakeAecDump) {
|
||||
if ([_settings currentCreateAecDumpSettingFromStore]) {
|
||||
NSString *filePath = [self documentsFilePathForFileName:@"webrtc-audio.aecdump"];
|
||||
if (![_factory startAecDumpWithFilePath:filePath
|
||||
maxSizeInBytes:kARDAppClientAecDumpMaxSizeInBytes]) {
|
||||
@ -719,7 +710,7 @@ static int const kKbpsMultiplier = 1000;
|
||||
// support or emulation (http://goo.gl/rHAnC1) so don't bother
|
||||
// trying to open a local stream.
|
||||
#if !TARGET_IPHONE_SIMULATOR
|
||||
if (!_isAudioOnly) {
|
||||
if (![_settings currentAudioOnlySettingFromStore]) {
|
||||
RTCVideoSource *source = [_factory videoSource];
|
||||
RTCCameraVideoCapturer *capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:source];
|
||||
[_delegate appClient:self didCreateLocalCapturer:capturer];
|
||||
@ -758,8 +749,9 @@ static int const kKbpsMultiplier = 1000;
|
||||
#pragma mark - Defaults
|
||||
|
||||
- (RTCMediaConstraints *)defaultMediaAudioConstraints {
|
||||
NSString *valueLevelControl = _shouldUseLevelControl ?
|
||||
kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse;
|
||||
NSString *valueLevelControl = [_settings currentUseLevelControllerSettingFromStore] ?
|
||||
kRTCMediaConstraintsValueTrue :
|
||||
kRTCMediaConstraintsValueFalse;
|
||||
NSDictionary *mandatoryConstraints = @{ kRTCMediaConstraintsLevelControl : valueLevelControl };
|
||||
RTCMediaConstraints *constraints =
|
||||
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Model class for user defined settings.
|
||||
*
|
||||
@ -79,5 +80,55 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (void)storeMaxBitrateSetting:(nullable NSNumber *)bitrate;
|
||||
|
||||
/**
|
||||
* Returns current audio only setting from store if present or default (NO) otherwise.
|
||||
*/
|
||||
- (BOOL)currentAudioOnlySettingFromStore;
|
||||
|
||||
/**
|
||||
* Stores the provided audio only setting into the store.
|
||||
*
|
||||
* @param setting the boolean value to be stored.
|
||||
*/
|
||||
- (void)storeAudioOnlySetting:(BOOL)audioOnly;
|
||||
|
||||
/**
|
||||
* Returns current create AecDump setting from store if present or default (NO) otherwise.
|
||||
*/
|
||||
- (BOOL)currentCreateAecDumpSettingFromStore;
|
||||
|
||||
/**
|
||||
* Stores the provided create AecDump setting into the store.
|
||||
*
|
||||
* @param setting the boolean value to be stored.
|
||||
*/
|
||||
- (void)storeCreateAecDumpSetting:(BOOL)createAecDump;
|
||||
|
||||
/**
|
||||
* Returns current setting whether to use level controller from store if present or default (NO)
|
||||
* otherwise.
|
||||
*/
|
||||
- (BOOL)currentUseLevelControllerSettingFromStore;
|
||||
|
||||
/**
|
||||
* Stores the provided use level controller setting into the store.
|
||||
*
|
||||
* @param setting the boolean value to be stored.
|
||||
*/
|
||||
- (void)storeUseLevelControllerSetting:(BOOL)useLevelController;
|
||||
|
||||
/**
|
||||
* Returns current setting whether to use manual audio config from store if present or default (YES)
|
||||
* otherwise.
|
||||
*/
|
||||
- (BOOL)currentUseManualAudioConfigSettingFromStore;
|
||||
|
||||
/**
|
||||
* Stores the provided use manual audio config setting into the store.
|
||||
*
|
||||
* @param setting the boolean value to be stored.
|
||||
*/
|
||||
- (void)storeUseManualAudioConfigSetting:(BOOL)useManualAudioConfig;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -56,13 +56,8 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
}
|
||||
|
||||
- (NSString *)currentVideoResolutionSettingFromStore {
|
||||
NSString *resolution = [[self settingsStore] videoResolution];
|
||||
if (!resolution) {
|
||||
resolution = [self defaultVideoResolutionSetting];
|
||||
// To ensure consistency add the default to the store.
|
||||
[[self settingsStore] setVideoResolution:resolution];
|
||||
}
|
||||
return resolution;
|
||||
[self registerStoreDefaults];
|
||||
return [[self settingsStore] videoResolution];
|
||||
}
|
||||
|
||||
- (BOOL)storeVideoResolutionSetting:(NSString *)resolution {
|
||||
@ -78,12 +73,8 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
}
|
||||
|
||||
- (NSString *)currentVideoCodecSettingFromStore {
|
||||
NSString *videoCodec = [[self settingsStore] videoCodec];
|
||||
if (!videoCodec) {
|
||||
videoCodec = [self defaultVideoCodecSetting];
|
||||
[[self settingsStore] setVideoCodec:videoCodec];
|
||||
}
|
||||
return videoCodec;
|
||||
[self registerStoreDefaults];
|
||||
return [[self settingsStore] videoCodec];
|
||||
}
|
||||
|
||||
- (BOOL)storeVideoCodecSetting:(NSString *)videoCodec {
|
||||
@ -95,6 +86,7 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
}
|
||||
|
||||
- (nullable NSNumber *)currentMaxBitrateSettingFromStore {
|
||||
[self registerStoreDefaults];
|
||||
return [[self settingsStore] maxBitrate];
|
||||
}
|
||||
|
||||
@ -102,11 +94,44 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
[[self settingsStore] setMaxBitrate:bitrate];
|
||||
}
|
||||
|
||||
- (BOOL)currentAudioOnlySettingFromStore {
|
||||
return [[self settingsStore] audioOnly];
|
||||
}
|
||||
|
||||
- (void)storeAudioOnlySetting:(BOOL)audioOnly {
|
||||
[[self settingsStore] setAudioOnly:audioOnly];
|
||||
}
|
||||
|
||||
- (BOOL)currentCreateAecDumpSettingFromStore {
|
||||
return [[self settingsStore] createAecDump];
|
||||
}
|
||||
|
||||
- (void)storeCreateAecDumpSetting:(BOOL)createAecDump {
|
||||
[[self settingsStore] setCreateAecDump:createAecDump];
|
||||
}
|
||||
|
||||
- (BOOL)currentUseLevelControllerSettingFromStore {
|
||||
return [[self settingsStore] useLevelController];
|
||||
}
|
||||
|
||||
- (void)storeUseLevelControllerSetting:(BOOL)useLevelController {
|
||||
[[self settingsStore] setUseLevelController:useLevelController];
|
||||
}
|
||||
|
||||
- (BOOL)currentUseManualAudioConfigSettingFromStore {
|
||||
return [[self settingsStore] useManualAudioConfig];
|
||||
}
|
||||
|
||||
- (void)storeUseManualAudioConfigSetting:(BOOL)useManualAudioConfig {
|
||||
[[self settingsStore] setUseManualAudioConfig:useManualAudioConfig];
|
||||
}
|
||||
|
||||
#pragma mark - Testable
|
||||
|
||||
- (ARDSettingsStore *)settingsStore {
|
||||
if (!_settingsStore) {
|
||||
_settingsStore = [[ARDSettingsStore alloc] init];
|
||||
[self registerStoreDefaults];
|
||||
}
|
||||
return _settingsStore;
|
||||
}
|
||||
@ -128,6 +153,10 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
return [self availableVideoResolutions][0];
|
||||
}
|
||||
|
||||
- (NSString *)defaultVideoCodecSetting {
|
||||
return videoCodecsStaticValues()[0];
|
||||
}
|
||||
|
||||
- (int)videoResolutionComponentAtIndex:(int)index inString:(NSString *)resolution {
|
||||
if (index != 0 && index != 1) {
|
||||
return 0;
|
||||
@ -139,8 +168,14 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
return components[index].intValue;
|
||||
}
|
||||
|
||||
- (NSString *)defaultVideoCodecSetting {
|
||||
return videoCodecsStaticValues()[0];
|
||||
- (void)registerStoreDefaults {
|
||||
[ARDSettingsStore setDefaultsForVideoResolution:[self defaultVideoResolutionSetting]
|
||||
videoCodec:[self defaultVideoCodecSetting]
|
||||
bitrate:nil
|
||||
audioOnly:NO
|
||||
createAecDump:NO
|
||||
useLevelController:NO
|
||||
useManualAudioConfig:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -19,6 +19,18 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface ARDSettingsStore : NSObject
|
||||
|
||||
/**
|
||||
* Set fallback values in case the setting has not been written by the user.
|
||||
* @param dictionary of values to store
|
||||
*/
|
||||
+ (void)setDefaultsForVideoResolution:(NSString *)videoResolution
|
||||
videoCodec:(NSString *)videoCodec
|
||||
bitrate:(nullable NSNumber *)bitrate
|
||||
audioOnly:(BOOL)audioOnly
|
||||
createAecDump:(BOOL)createAecDump
|
||||
useLevelController:(BOOL)useLevelController
|
||||
useManualAudioConfig:(BOOL)useManualAudioConfig;
|
||||
|
||||
@property(nonatomic) NSString *videoResolution;
|
||||
@property(nonatomic) NSString *videoCodec;
|
||||
|
||||
@ -33,5 +45,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (void)setMaxBitrate:(nullable NSNumber *)value;
|
||||
|
||||
@property(nonatomic) BOOL audioOnly;
|
||||
@property(nonatomic) BOOL createAecDump;
|
||||
@property(nonatomic) BOOL useLevelController;
|
||||
@property(nonatomic) BOOL useManualAudioConfig;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -13,6 +13,10 @@
|
||||
static NSString *const kVideoResolutionKey = @"rtc_video_resolution_key";
|
||||
static NSString *const kVideoCodecKey = @"rtc_video_codec_key";
|
||||
static NSString *const kBitrateKey = @"rtc_max_bitrate_key";
|
||||
static NSString *const kAudioOnlyKey = @"rtc_audio_only_key";
|
||||
static NSString *const kCreateAecDumpKey = @"rtc_create_aec_dump_key";
|
||||
static NSString *const kUseLevelControllerKey = @"rtc_use_level_controller_key";
|
||||
static NSString *const kUseManualAudioConfigKey = @"rtc_use_manual_audio_config_key";
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@interface ARDSettingsStore () {
|
||||
@ -23,6 +27,27 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation ARDSettingsStore
|
||||
|
||||
+ (void)setDefaultsForVideoResolution:(NSString *)videoResolution
|
||||
videoCodec:(NSString *)videoCodec
|
||||
bitrate:(nullable NSNumber *)bitrate
|
||||
audioOnly:(BOOL)audioOnly
|
||||
createAecDump:(BOOL)createAecDump
|
||||
useLevelController:(BOOL)useLevelController
|
||||
useManualAudioConfig:(BOOL)useManualAudioConfig {
|
||||
NSMutableDictionary<NSString *, id> *defaultsDictionary = [@{
|
||||
kVideoResolutionKey : videoResolution,
|
||||
kVideoCodecKey : videoCodec,
|
||||
kAudioOnlyKey : @(audioOnly),
|
||||
kCreateAecDumpKey : @(createAecDump),
|
||||
kUseLevelControllerKey : @(useLevelController),
|
||||
kUseManualAudioConfigKey : @(useManualAudioConfig)
|
||||
} mutableCopy];
|
||||
if (bitrate) {
|
||||
[defaultsDictionary setObject:bitrate forKey:kBitrateKey];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary];
|
||||
}
|
||||
|
||||
- (NSUserDefaults *)storage {
|
||||
if (!_storage) {
|
||||
_storage = [NSUserDefaults standardUserDefaults];
|
||||
@ -57,5 +82,41 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[self.storage synchronize];
|
||||
}
|
||||
|
||||
- (BOOL)audioOnly {
|
||||
return [self.storage boolForKey:kAudioOnlyKey];
|
||||
}
|
||||
|
||||
- (void)setAudioOnly:(BOOL)audioOnly {
|
||||
[self.storage setBool:audioOnly forKey:kAudioOnlyKey];
|
||||
[self.storage synchronize];
|
||||
}
|
||||
|
||||
- (BOOL)createAecDump {
|
||||
return [self.storage boolForKey:kCreateAecDumpKey];
|
||||
}
|
||||
|
||||
- (void)setCreateAecDump:(BOOL)createAecDump {
|
||||
[self.storage setBool:createAecDump forKey:kCreateAecDumpKey];
|
||||
[self.storage synchronize];
|
||||
}
|
||||
|
||||
- (BOOL)useLevelController {
|
||||
return [self.storage boolForKey:kUseLevelControllerKey];
|
||||
}
|
||||
|
||||
- (void)setUseLevelController:(BOOL)useLevelController {
|
||||
[self.storage setBool:useLevelController forKey:kUseLevelControllerKey];
|
||||
[self.storage synchronize];
|
||||
}
|
||||
|
||||
- (BOOL)useManualAudioConfig {
|
||||
return [self.storage boolForKey:kUseManualAudioConfigKey];
|
||||
}
|
||||
|
||||
- (void)setUseManualAudioConfig:(BOOL)useManualAudioConfig {
|
||||
[self.storage setBool:useManualAudioConfig forKey:kUseManualAudioConfigKey];
|
||||
[self.storage synchronize];
|
||||
}
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -14,14 +14,7 @@
|
||||
|
||||
@protocol ARDMainViewDelegate <NSObject>
|
||||
|
||||
- (void)mainView:(ARDMainView *)mainView
|
||||
didInputRoom:(NSString *)room
|
||||
isLoopback:(BOOL)isLoopback
|
||||
isAudioOnly:(BOOL)isAudioOnly
|
||||
shouldMakeAecDump:(BOOL)shouldMakeAecDump
|
||||
shouldUseLevelControl:(BOOL)shouldUseLevelControl
|
||||
useManualAudio:(BOOL)useManualAudio;
|
||||
|
||||
- (void)mainView:(ARDMainView *)mainView didInputRoom:(NSString *)room isLoopback:(BOOL)isLoopback;
|
||||
- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView;
|
||||
|
||||
@end
|
||||
|
||||
@ -74,16 +74,8 @@ static CGFloat const kCallControlMargin = 8;
|
||||
@implementation ARDMainView {
|
||||
ARDRoomTextField *_roomText;
|
||||
UILabel *_callOptionsLabel;
|
||||
UISwitch *_audioOnlySwitch;
|
||||
UILabel *_audioOnlyLabel;
|
||||
UISwitch *_aecdumpSwitch;
|
||||
UILabel *_aecdumpLabel;
|
||||
UISwitch *_levelControlSwitch;
|
||||
UILabel *_levelControlLabel;
|
||||
UISwitch *_loopbackSwitch;
|
||||
UILabel *_loopbackLabel;
|
||||
UISwitch *_useManualAudioSwitch;
|
||||
UILabel *_useManualAudioLabel;
|
||||
UIButton *_startCallButton;
|
||||
UIButton *_audioLoopButton;
|
||||
}
|
||||
@ -106,17 +98,6 @@ static CGFloat const kCallControlMargin = 8;
|
||||
[_callOptionsLabel sizeToFit];
|
||||
[self addSubview:_callOptionsLabel];
|
||||
|
||||
_audioOnlySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||
[_audioOnlySwitch sizeToFit];
|
||||
[self addSubview:_audioOnlySwitch];
|
||||
|
||||
_audioOnlyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_audioOnlyLabel.text = @"Audio only";
|
||||
_audioOnlyLabel.font = controlFont;
|
||||
_audioOnlyLabel.textColor = controlFontColor;
|
||||
[_audioOnlyLabel sizeToFit];
|
||||
[self addSubview:_audioOnlyLabel];
|
||||
|
||||
_loopbackSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||
[_loopbackSwitch sizeToFit];
|
||||
[self addSubview:_loopbackSwitch];
|
||||
@ -128,40 +109,6 @@ static CGFloat const kCallControlMargin = 8;
|
||||
[_loopbackLabel sizeToFit];
|
||||
[self addSubview:_loopbackLabel];
|
||||
|
||||
_aecdumpSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||
[_aecdumpSwitch sizeToFit];
|
||||
[self addSubview:_aecdumpSwitch];
|
||||
|
||||
_aecdumpLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_aecdumpLabel.text = @"Create AecDump";
|
||||
_aecdumpLabel.font = controlFont;
|
||||
_aecdumpLabel.textColor = controlFontColor;
|
||||
[_aecdumpLabel sizeToFit];
|
||||
[self addSubview:_aecdumpLabel];
|
||||
|
||||
_levelControlSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||
[_levelControlSwitch sizeToFit];
|
||||
[self addSubview:_levelControlSwitch];
|
||||
|
||||
_levelControlLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_levelControlLabel.text = @"Use level controller";
|
||||
_levelControlLabel.font = controlFont;
|
||||
_levelControlLabel.textColor = controlFontColor;
|
||||
[_levelControlLabel sizeToFit];
|
||||
[self addSubview:_levelControlLabel];
|
||||
|
||||
_useManualAudioSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||
[_useManualAudioSwitch sizeToFit];
|
||||
_useManualAudioSwitch.on = YES;
|
||||
[self addSubview:_useManualAudioSwitch];
|
||||
|
||||
_useManualAudioLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_useManualAudioLabel.text = @"Use manual audio config";
|
||||
_useManualAudioLabel.font = controlFont;
|
||||
_useManualAudioLabel.textColor = controlFontColor;
|
||||
[_useManualAudioLabel sizeToFit];
|
||||
[self addSubview:_useManualAudioLabel];
|
||||
|
||||
_startCallButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[_startCallButton setTitle:@"Start call"
|
||||
forState:UIControlStateNormal];
|
||||
@ -208,20 +155,7 @@ static CGFloat const kCallControlMargin = 8;
|
||||
_callOptionsLabel.frame.size.width,
|
||||
_callOptionsLabel.frame.size.height);
|
||||
|
||||
CGFloat audioOnlyTop =
|
||||
CGRectGetMaxY(_callOptionsLabel.frame) + kCallControlMargin * 2;
|
||||
CGRect audioOnlyRect = CGRectMake(kCallControlMargin * 3,
|
||||
audioOnlyTop,
|
||||
_audioOnlySwitch.frame.size.width,
|
||||
_audioOnlySwitch.frame.size.height);
|
||||
_audioOnlySwitch.frame = audioOnlyRect;
|
||||
CGFloat audioOnlyLabelCenterX = CGRectGetMaxX(audioOnlyRect) +
|
||||
kCallControlMargin + _audioOnlyLabel.frame.size.width / 2;
|
||||
_audioOnlyLabel.center = CGPointMake(audioOnlyLabelCenterX,
|
||||
CGRectGetMidY(audioOnlyRect));
|
||||
|
||||
CGFloat loopbackModeTop =
|
||||
CGRectGetMaxY(_audioOnlySwitch.frame) + kCallControlMargin;
|
||||
CGFloat loopbackModeTop = CGRectGetMaxY(_callOptionsLabel.frame) + kCallControlMargin * 2;
|
||||
CGRect loopbackModeRect = CGRectMake(kCallControlMargin * 3,
|
||||
loopbackModeTop,
|
||||
_loopbackSwitch.frame.size.width,
|
||||
@ -232,46 +166,7 @@ static CGFloat const kCallControlMargin = 8;
|
||||
_loopbackLabel.center = CGPointMake(loopbackModeLabelCenterX,
|
||||
CGRectGetMidY(loopbackModeRect));
|
||||
|
||||
CGFloat aecdumpModeTop =
|
||||
CGRectGetMaxY(_loopbackSwitch.frame) + kCallControlMargin;
|
||||
CGRect aecdumpModeRect = CGRectMake(kCallControlMargin * 3,
|
||||
aecdumpModeTop,
|
||||
_aecdumpSwitch.frame.size.width,
|
||||
_aecdumpSwitch.frame.size.height);
|
||||
_aecdumpSwitch.frame = aecdumpModeRect;
|
||||
CGFloat aecdumpModeLabelCenterX = CGRectGetMaxX(aecdumpModeRect) +
|
||||
kCallControlMargin + _aecdumpLabel.frame.size.width / 2;
|
||||
_aecdumpLabel.center = CGPointMake(aecdumpModeLabelCenterX,
|
||||
CGRectGetMidY(aecdumpModeRect));
|
||||
|
||||
CGFloat levelControlModeTop =
|
||||
CGRectGetMaxY(_aecdumpSwitch.frame) + kCallControlMargin;
|
||||
CGRect levelControlModeRect = CGRectMake(kCallControlMargin * 3,
|
||||
levelControlModeTop,
|
||||
_levelControlSwitch.frame.size.width,
|
||||
_levelControlSwitch.frame.size.height);
|
||||
_levelControlSwitch.frame = levelControlModeRect;
|
||||
CGFloat levelControlModeLabelCenterX = CGRectGetMaxX(levelControlModeRect) +
|
||||
kCallControlMargin + _levelControlLabel.frame.size.width / 2;
|
||||
_levelControlLabel.center = CGPointMake(levelControlModeLabelCenterX,
|
||||
CGRectGetMidY(levelControlModeRect));
|
||||
|
||||
CGFloat useManualAudioTop =
|
||||
CGRectGetMaxY(_levelControlSwitch.frame) + kCallControlMargin;
|
||||
CGRect useManualAudioRect =
|
||||
CGRectMake(kCallControlMargin * 3,
|
||||
useManualAudioTop,
|
||||
_useManualAudioSwitch.frame.size.width,
|
||||
_useManualAudioSwitch.frame.size.height);
|
||||
_useManualAudioSwitch.frame = useManualAudioRect;
|
||||
CGFloat useManualAudioLabelCenterX = CGRectGetMaxX(useManualAudioRect) +
|
||||
kCallControlMargin + _useManualAudioLabel.frame.size.width / 2;
|
||||
_useManualAudioLabel.center =
|
||||
CGPointMake(useManualAudioLabelCenterX,
|
||||
CGRectGetMidY(useManualAudioRect));
|
||||
|
||||
CGFloat audioLoopTop =
|
||||
CGRectGetMaxY(useManualAudioRect) + kCallControlMargin * 3;
|
||||
CGFloat audioLoopTop = CGRectGetMaxY(loopbackModeRect) + kCallControlMargin * 3;
|
||||
_audioLoopButton.frame = CGRectMake(kCallControlMargin,
|
||||
audioLoopTop,
|
||||
_audioLoopButton.frame.size.width,
|
||||
@ -304,13 +199,7 @@ static CGFloat const kCallControlMargin = 8;
|
||||
}
|
||||
|
||||
- (void)onStartCall:(id)sender {
|
||||
[_delegate mainView:self
|
||||
didInputRoom:_roomText.roomText
|
||||
isLoopback:_loopbackSwitch.isOn
|
||||
isAudioOnly:_audioOnlySwitch.isOn
|
||||
shouldMakeAecDump:_aecdumpSwitch.isOn
|
||||
shouldUseLevelControl:_levelControlSwitch.isOn
|
||||
useManualAudio:_useManualAudioSwitch.isOn];
|
||||
[_delegate mainView:self didInputRoom:_roomText.roomText isLoopback:_loopbackSwitch.isOn];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -44,13 +44,7 @@ static NSString *const loopbackLaunchProcessArgument = @"loopback";
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
if ([[[NSProcessInfo processInfo] arguments] containsObject:loopbackLaunchProcessArgument]) {
|
||||
[self mainView:nil
|
||||
didInputRoom:@""
|
||||
isLoopback:YES
|
||||
isAudioOnly:NO
|
||||
shouldMakeAecDump:NO
|
||||
shouldUseLevelControl:NO
|
||||
useManualAudio:NO];
|
||||
[self mainView:nil didInputRoom:@"" isLoopback:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,13 +85,7 @@ static NSString *const loopbackLaunchProcessArgument = @"loopback";
|
||||
|
||||
#pragma mark - ARDMainViewDelegate
|
||||
|
||||
- (void)mainView:(ARDMainView *)mainView
|
||||
didInputRoom:(NSString *)room
|
||||
isLoopback:(BOOL)isLoopback
|
||||
isAudioOnly:(BOOL)isAudioOnly
|
||||
shouldMakeAecDump:(BOOL)shouldMakeAecDump
|
||||
shouldUseLevelControl:(BOOL)shouldUseLevelControl
|
||||
useManualAudio:(BOOL)useManualAudio {
|
||||
- (void)mainView:(ARDMainView *)mainView didInputRoom:(NSString *)room isLoopback:(BOOL)isLoopback {
|
||||
if (!room.length) {
|
||||
if (isLoopback) {
|
||||
// If this is a loopback call, allow a generated room name.
|
||||
@ -132,17 +120,16 @@ static NSString *const loopbackLaunchProcessArgument = @"loopback";
|
||||
return;
|
||||
}
|
||||
|
||||
ARDSettingsModel *settingsModel = [[ARDSettingsModel alloc] init];
|
||||
|
||||
RTCAudioSession *session = [RTCAudioSession sharedInstance];
|
||||
session.useManualAudio = useManualAudio;
|
||||
session.useManualAudio = [settingsModel currentUseManualAudioConfigSettingFromStore];
|
||||
session.isAudioEnabled = NO;
|
||||
|
||||
// Kick off the video call.
|
||||
ARDVideoCallViewController *videoCallViewController =
|
||||
[[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
|
||||
isLoopback:isLoopback
|
||||
isAudioOnly:isAudioOnly
|
||||
shouldMakeAecDump:shouldMakeAecDump
|
||||
shouldUseLevelControl:shouldUseLevelControl
|
||||
delegate:self];
|
||||
videoCallViewController.modalTransitionStyle =
|
||||
UIModalTransitionStyleCrossDissolve;
|
||||
|
||||
@ -14,11 +14,19 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
ARDSettingsSectionVideoResolution = 0,
|
||||
ARDSettingsSectionAudioSettings = 0,
|
||||
ARDSettingsSectionVideoResolution,
|
||||
ARDSettingsSectionVideoCodec,
|
||||
ARDSettingsSectionBitRate,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(int, ARDAudioSettingsOptions) {
|
||||
ARDAudioSettingsAudioOnly = 0,
|
||||
ARDAudioSettingsCreateAecDump,
|
||||
ARDAudioSettingsUseLevelController,
|
||||
ARDAudioSettingsUseManualAudioConfig,
|
||||
};
|
||||
|
||||
@interface ARDSettingsViewController () <UITextFieldDelegate> {
|
||||
ARDSettingsModel *_settingsModel;
|
||||
}
|
||||
@ -46,22 +54,16 @@ typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
[self addCheckmarkInSection:ARDSettingsSectionVideoResolution
|
||||
withArray:[self videoResolutionArray]
|
||||
selecting:[_settingsModel currentVideoResolutionSettingFromStore]];
|
||||
[self addCheckmarkInSection:ARDSettingsSectionVideoCodec
|
||||
withArray:[self videoCodecArray]
|
||||
selecting:[_settingsModel currentVideoCodecSettingFromStore]];
|
||||
}
|
||||
|
||||
#pragma mark - Data source
|
||||
|
||||
- (NSArray<NSString *> *)videoResolutionArray {
|
||||
return _settingsModel.availableVideoResolutions;
|
||||
return [_settingsModel availableVideoResolutions];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)videoCodecArray {
|
||||
return _settingsModel.availableVideoCodecs;
|
||||
return [_settingsModel availableVideoCodecs];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@ -74,16 +76,6 @@ typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
self.navigationItem.leftBarButtonItem = barItem;
|
||||
}
|
||||
|
||||
- (void)addCheckmarkInSection:(int)section
|
||||
withArray:(NSArray<NSString*>*) array
|
||||
selecting:(NSString*)selection {
|
||||
NSUInteger indexOfSelection = [array indexOfObject:selection];
|
||||
NSIndexPath *pathToBeDecorated = [NSIndexPath indexPathForRow:indexOfSelection
|
||||
inSection:section];
|
||||
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:pathToBeDecorated];
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
}
|
||||
|
||||
#pragma mark - Dismissal of view controller
|
||||
|
||||
- (void)dismissModally:(id)sender {
|
||||
@ -93,11 +85,13 @@ typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
switch (section) {
|
||||
case ARDSettingsSectionAudioSettings:
|
||||
return 4;
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
return self.videoResolutionArray.count;
|
||||
case ARDSettingsSectionVideoCodec:
|
||||
@ -133,6 +127,8 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (nullable NSString *)tableView:(UITableView *)tableView
|
||||
titleForHeaderInSection:(NSInteger)section {
|
||||
switch (section) {
|
||||
case ARDSettingsSectionAudioSettings:
|
||||
return @"Audio";
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
return @"Video resolution";
|
||||
case ARDSettingsSectionVideoCodec:
|
||||
@ -147,6 +143,9 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
switch (indexPath.section) {
|
||||
case ARDSettingsSectionAudioSettings:
|
||||
return [self audioSettingsTableViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
return [self videoResolutionTableViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
|
||||
@ -184,7 +183,14 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:dequeueIdentifier];
|
||||
}
|
||||
cell.textLabel.text = self.videoResolutionArray[indexPath.row];
|
||||
NSString *resolution = self.videoResolutionArray[indexPath.row];
|
||||
cell.textLabel.text = resolution;
|
||||
if ([resolution isEqualToString:[_settingsModel currentVideoResolutionSettingFromStore]]) {
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
} else {
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@ -208,7 +214,13 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:dequeueIdentifier];
|
||||
}
|
||||
cell.textLabel.text = self.videoCodecArray[indexPath.row];
|
||||
NSString *codec = self.videoCodecArray[indexPath.row];
|
||||
cell.textLabel.text = codec;
|
||||
if ([codec isEqualToString:[_settingsModel currentVideoCodecSettingFromStore]]) {
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
} else {
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
@ -275,5 +287,83 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
[_settingsModel storeMaxBitrateSetting:bitrateNumber];
|
||||
}
|
||||
|
||||
#pragma mark - Table view delegate(Audio settings)
|
||||
|
||||
- (UITableViewCell *)audioSettingsTableViewCellForTableView:(UITableView *)tableView
|
||||
atIndexPath:(NSIndexPath *)indexPath {
|
||||
NSString *dequeueIdentifier = @"ARDSettingsAudioSettingsCellIdentifier";
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:dequeueIdentifier];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||
switchView.tag = indexPath.row;
|
||||
[switchView addTarget:self
|
||||
action:@selector(audioSettingSwitchChanged:)
|
||||
forControlEvents:UIControlEventValueChanged];
|
||||
cell.accessoryView = switchView;
|
||||
}
|
||||
|
||||
cell.textLabel.text = [self labelForAudioSettingAtIndexPathRow:indexPath.row];
|
||||
UISwitch *switchView = (UISwitch *)cell.accessoryView;
|
||||
switchView.on = [self valueForAudioSettingAtIndexPathRow:indexPath.row];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (NSString *)labelForAudioSettingAtIndexPathRow:(NSInteger)setting {
|
||||
switch (setting) {
|
||||
case ARDAudioSettingsAudioOnly:
|
||||
return @"Audio only";
|
||||
case ARDAudioSettingsCreateAecDump:
|
||||
return @"Create AecDump";
|
||||
case ARDAudioSettingsUseLevelController:
|
||||
return @"Use level controller";
|
||||
case ARDAudioSettingsUseManualAudioConfig:
|
||||
return @"Use manual audio config";
|
||||
default:
|
||||
return @"";
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)valueForAudioSettingAtIndexPathRow:(NSInteger)setting {
|
||||
switch (setting) {
|
||||
case ARDAudioSettingsAudioOnly:
|
||||
return [_settingsModel currentAudioOnlySettingFromStore];
|
||||
case ARDAudioSettingsCreateAecDump:
|
||||
return [_settingsModel currentCreateAecDumpSettingFromStore];
|
||||
case ARDAudioSettingsUseLevelController:
|
||||
return [_settingsModel currentUseLevelControllerSettingFromStore];
|
||||
case ARDAudioSettingsUseManualAudioConfig:
|
||||
return [_settingsModel currentUseManualAudioConfigSettingFromStore];
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)audioSettingSwitchChanged:(UISwitch *)sender {
|
||||
switch (sender.tag) {
|
||||
case ARDAudioSettingsAudioOnly: {
|
||||
[_settingsModel storeAudioOnlySetting:sender.isOn];
|
||||
break;
|
||||
}
|
||||
case ARDAudioSettingsCreateAecDump: {
|
||||
[_settingsModel storeCreateAecDumpSetting:sender.isOn];
|
||||
break;
|
||||
}
|
||||
case ARDAudioSettingsUseLevelController: {
|
||||
[_settingsModel storeUseLevelControllerSetting:sender.isOn];
|
||||
break;
|
||||
}
|
||||
case ARDAudioSettingsUseManualAudioConfig: {
|
||||
[_settingsModel storeUseManualAudioConfigSetting:sender.isOn];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -23,9 +23,6 @@
|
||||
|
||||
- (instancetype)initForRoom:(NSString *)room
|
||||
isLoopback:(BOOL)isLoopback
|
||||
isAudioOnly:(BOOL)isAudioOnly
|
||||
shouldMakeAecDump:(BOOL)shouldMakeAecDump
|
||||
shouldUseLevelControl:(BOOL)shouldUseLevelControl
|
||||
delegate:(id<ARDVideoCallViewControllerDelegate>)delegate;
|
||||
|
||||
@end
|
||||
|
||||
@ -40,21 +40,13 @@
|
||||
|
||||
- (instancetype)initForRoom:(NSString *)room
|
||||
isLoopback:(BOOL)isLoopback
|
||||
isAudioOnly:(BOOL)isAudioOnly
|
||||
shouldMakeAecDump:(BOOL)shouldMakeAecDump
|
||||
shouldUseLevelControl:(BOOL)shouldUseLevelControl
|
||||
delegate:(id<ARDVideoCallViewControllerDelegate>)delegate {
|
||||
if (self = [super init]) {
|
||||
ARDSettingsModel *settingsModel = [[ARDSettingsModel alloc] init];
|
||||
_delegate = delegate;
|
||||
|
||||
_client = [[ARDAppClient alloc] initWithDelegate:self];
|
||||
[_client connectToRoomWithId:room
|
||||
settings:settingsModel
|
||||
isLoopback:isLoopback
|
||||
isAudioOnly:isAudioOnly
|
||||
shouldMakeAecDump:shouldMakeAecDump
|
||||
shouldUseLevelControl:shouldUseLevelControl];
|
||||
[_client connectToRoomWithId:room settings:settingsModel isLoopback:isLoopback];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -402,10 +402,7 @@ static NSUInteger const kBottomViewHeight = 200;
|
||||
ARDAppClient* client = [[ARDAppClient alloc] initWithDelegate:self];
|
||||
[client connectToRoomWithId:roomId
|
||||
settings:[[ARDSettingsModel alloc] init] // Use default settings.
|
||||
isLoopback:isLoopback
|
||||
isAudioOnly:NO
|
||||
shouldMakeAecDump:NO
|
||||
shouldUseLevelControl:NO];
|
||||
isLoopback:isLoopback];
|
||||
_client = client;
|
||||
}
|
||||
|
||||
|
||||
@ -116,6 +116,15 @@
|
||||
return mockTURNClient;
|
||||
}
|
||||
|
||||
- (id)mockSettingsModel {
|
||||
ARDSettingsModel *model = [[ARDSettingsModel alloc] init];
|
||||
id partialMock = [OCMockObject partialMockForObject:model];
|
||||
[[[partialMock stub] andReturn:@[ @"640x480", @"960x540", @"1280x720" ]]
|
||||
availableVideoResolutions];
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
- (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId
|
||||
clientId:(NSString *)clientId
|
||||
isInitiator:(BOOL)isInitiator
|
||||
@ -209,18 +218,8 @@
|
||||
weakAnswerer = answerer;
|
||||
|
||||
// Kick off connection.
|
||||
[caller connectToRoomWithId:roomId
|
||||
settings:[[ARDSettingsModel alloc] init]
|
||||
isLoopback:NO
|
||||
isAudioOnly:NO
|
||||
shouldMakeAecDump:NO
|
||||
shouldUseLevelControl:NO];
|
||||
[answerer connectToRoomWithId:roomId
|
||||
settings:[[ARDSettingsModel alloc] init]
|
||||
isLoopback:NO
|
||||
isAudioOnly:NO
|
||||
shouldMakeAecDump:NO
|
||||
shouldUseLevelControl:NO];
|
||||
[caller connectToRoomWithId:roomId settings:[self mockSettingsModel] isLoopback:NO];
|
||||
[answerer connectToRoomWithId:roomId settings:[self mockSettingsModel] isLoopback:NO];
|
||||
[self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
|
||||
if (error) {
|
||||
XCTFail(@"Expectation failed with error %@.", error);
|
||||
@ -253,11 +252,8 @@
|
||||
|
||||
// Kick off connection.
|
||||
[caller connectToRoomWithId:roomId
|
||||
settings:[[ARDSettingsModel alloc] init]
|
||||
isLoopback:NO
|
||||
isAudioOnly:NO
|
||||
shouldMakeAecDump:NO
|
||||
shouldUseLevelControl:NO];
|
||||
settings:[self mockSettingsModel]
|
||||
isLoopback:NO];
|
||||
[self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
|
||||
if (error) {
|
||||
XCTFail("Expectation timed out with error: %@.", error);
|
||||
|
||||
@ -25,9 +25,8 @@
|
||||
|
||||
@implementation ARDSettingsModelTests
|
||||
|
||||
- (id)setupMockStoreWithVideoResolution:(NSString *)videoResolution {
|
||||
- (id)setupMockStore {
|
||||
id storeMock = [OCMockObject mockForClass:[ARDSettingsStore class]];
|
||||
[([[storeMock stub] andReturn:videoResolution])videoResolution];
|
||||
|
||||
id partialMock = [OCMockObject partialMockForObject:_model];
|
||||
[[[partialMock stub] andReturn:storeMock] settingsStore];
|
||||
@ -41,39 +40,57 @@
|
||||
_model = [[ARDSettingsModel alloc] init];
|
||||
}
|
||||
|
||||
- (void)testDefaultMediaFromStore {
|
||||
id storeMock = [self setupMockStoreWithVideoResolution:nil];
|
||||
[[storeMock expect] setVideoResolution:@"640x480"];
|
||||
|
||||
- (void)testRetrievingSetting {
|
||||
id storeMock = [self setupMockStore];
|
||||
[[[storeMock expect] andReturn:@"640x480"] videoResolution];
|
||||
NSString *string = [_model currentVideoResolutionSettingFromStore];
|
||||
|
||||
XCTAssertEqualObjects(string, @"640x480");
|
||||
[storeMock verify];
|
||||
}
|
||||
|
||||
- (void)testStoringInvalidConstraintReturnsNo {
|
||||
__unused id storeMock = [self setupMockStoreWithVideoResolution:@"960x480"];
|
||||
id storeMock = [self setupMockStore];
|
||||
[([[storeMock stub] andReturn:@"960x480"])videoResolution];
|
||||
XCTAssertFalse([_model storeVideoResolutionSetting:@"960x480"]);
|
||||
}
|
||||
|
||||
- (void)testWidthConstraintFromStore {
|
||||
[self setupMockStoreWithVideoResolution:@"1270x480"];
|
||||
id storeMock = [self setupMockStore];
|
||||
[([[storeMock stub] andReturn:@"1270x480"])videoResolution];
|
||||
int width = [_model currentVideoResolutionWidthFromStore];
|
||||
|
||||
XCTAssertEqual(width, 1270);
|
||||
}
|
||||
|
||||
- (void)testHeightConstraintFromStore {
|
||||
[self setupMockStoreWithVideoResolution:@"960x540"];
|
||||
id storeMock = [self setupMockStore];
|
||||
[([[storeMock stub] andReturn:@"960x540"])videoResolution];
|
||||
int height = [_model currentVideoResolutionHeightFromStore];
|
||||
|
||||
XCTAssertEqual(height, 540);
|
||||
}
|
||||
|
||||
- (void)testConstraintComponentIsNilWhenInvalidConstraintString {
|
||||
[self setupMockStoreWithVideoResolution:@"invalid"];
|
||||
id storeMock = [self setupMockStore];
|
||||
[([[storeMock stub] andReturn:@"invalid"])videoResolution];
|
||||
int width = [_model currentVideoResolutionWidthFromStore];
|
||||
|
||||
XCTAssertEqual(width, 0);
|
||||
}
|
||||
|
||||
- (void)testStoringAudioSetting {
|
||||
id storeMock = [self setupMockStore];
|
||||
[[storeMock expect] setAudioOnly:YES];
|
||||
|
||||
[_model storeAudioOnlySetting:YES];
|
||||
[storeMock verify];
|
||||
}
|
||||
|
||||
- (void)testReturningDefaultCallOption {
|
||||
id storeMock = [self setupMockStore];
|
||||
[[[storeMock stub] andReturnValue:@YES] useManualAudioConfig];
|
||||
|
||||
XCTAssertTrue([_model currentUseManualAudioConfigSettingFromStore]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user