blob: 27aa757ff747ec2c3793e621a49a25df9e38ce41 [file] [log] [blame]
denicijad17d5362016-11-02 02:56:09 -07001/*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "ARDSettingsViewController.h"
denicija2256e042016-11-09 06:26:18 -080012#import "ARDSettingsModel.h"
Anders Carlsson6bf43d22017-10-16 13:51:43 +020013#import "RTCVideoCodecInfo+HumanReadable.h"
denicijad17d5362016-11-02 02:56:09 -070014
15NS_ASSUME_NONNULL_BEGIN
denicijab04b5c22016-11-09 04:28:46 -080016
17typedef NS_ENUM(int, ARDSettingsSections) {
Anders Carlssone1500582017-06-15 16:05:13 +020018 ARDSettingsSectionAudioSettings = 0,
19 ARDSettingsSectionVideoResolution,
sakal68b5df92017-03-17 09:01:59 -070020 ARDSettingsSectionVideoCodec,
21 ARDSettingsSectionBitRate,
denicijab04b5c22016-11-09 04:28:46 -080022};
23
Anders Carlssone1500582017-06-15 16:05:13 +020024typedef NS_ENUM(int, ARDAudioSettingsOptions) {
25 ARDAudioSettingsAudioOnly = 0,
26 ARDAudioSettingsCreateAecDump,
27 ARDAudioSettingsUseLevelController,
28 ARDAudioSettingsUseManualAudioConfig,
29};
30
denicija9af2b602016-11-17 00:43:43 -080031@interface ARDSettingsViewController () <UITextFieldDelegate> {
denicija2256e042016-11-09 06:26:18 -080032 ARDSettingsModel *_settingsModel;
denicijad17d5362016-11-02 02:56:09 -070033}
34
35@end
36
37@implementation ARDSettingsViewController
38
39- (instancetype)initWithStyle:(UITableViewStyle)style
denicija2256e042016-11-09 06:26:18 -080040 settingsModel:(ARDSettingsModel *)settingsModel {
denicijad17d5362016-11-02 02:56:09 -070041 self = [super initWithStyle:style];
42 if (self) {
denicija2256e042016-11-09 06:26:18 -080043 _settingsModel = settingsModel;
denicijad17d5362016-11-02 02:56:09 -070044 }
45 return self;
46}
47
48#pragma mark - View lifecycle
49
50- (void)viewDidLoad {
51 [super viewDidLoad];
52 self.title = @"Settings";
53 [self addDoneBarButton];
54}
55
sakal68b5df92017-03-17 09:01:59 -070056- (void)viewWillAppear:(BOOL)animated {
57 [super viewWillAppear:animated];
sakal68b5df92017-03-17 09:01:59 -070058}
59
denicijad17d5362016-11-02 02:56:09 -070060#pragma mark - Data source
61
sakalc522e752017-04-05 12:17:48 -070062- (NSArray<NSString *> *)videoResolutionArray {
Anders Carlssone1500582017-06-15 16:05:13 +020063 return [_settingsModel availableVideoResolutions];
denicijad17d5362016-11-02 02:56:09 -070064}
65
Anders Carlsson6bf43d22017-10-16 13:51:43 +020066- (NSArray<RTCVideoCodecInfo *> *)videoCodecArray {
Anders Carlssone1500582017-06-15 16:05:13 +020067 return [_settingsModel availableVideoCodecs];
sakal68b5df92017-03-17 09:01:59 -070068}
69
denicijad17d5362016-11-02 02:56:09 -070070#pragma mark -
71
72- (void)addDoneBarButton {
73 UIBarButtonItem *barItem =
74 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
75 target:self
76 action:@selector(dismissModally:)];
77 self.navigationItem.leftBarButtonItem = barItem;
78}
79
denicijad17d5362016-11-02 02:56:09 -070080#pragma mark - Dismissal of view controller
81
82- (void)dismissModally:(id)sender {
83 [self dismissViewControllerAnimated:YES completion:nil];
84}
85
86#pragma mark - Table view data source
87
88- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
Anders Carlssone1500582017-06-15 16:05:13 +020089 return 4;
denicijad17d5362016-11-02 02:56:09 -070090}
91
denicija40532a12016-11-08 04:00:53 -080092- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
sakal68b5df92017-03-17 09:01:59 -070093 switch (section) {
Anders Carlssone1500582017-06-15 16:05:13 +020094 case ARDSettingsSectionAudioSettings:
95 return 4;
sakalc522e752017-04-05 12:17:48 -070096 case ARDSettingsSectionVideoResolution:
97 return self.videoResolutionArray.count;
sakal68b5df92017-03-17 09:01:59 -070098 case ARDSettingsSectionVideoCodec:
99 return self.videoCodecArray.count;
100 default:
101 return 1;
denicijab04b5c22016-11-09 04:28:46 -0800102 }
denicija3babb992016-11-07 07:23:56 -0800103}
104
sakal68b5df92017-03-17 09:01:59 -0700105#pragma mark - Table view delegate helpers
denicija40532a12016-11-08 04:00:53 -0800106
sakal68b5df92017-03-17 09:01:59 -0700107- (void)removeAllAccessories:(UITableView *)tableView
108 inSection:(int)section
109{
110 for (int i = 0; i < [tableView numberOfRowsInSection:section]; i++) {
111 NSIndexPath *rowPath = [NSIndexPath indexPathForRow:i inSection:section];
112 UITableViewCell *cell = [tableView cellForRowAtIndexPath:rowPath];
113 cell.accessoryType = UITableViewCellAccessoryNone;
114 }
denicijab04b5c22016-11-09 04:28:46 -0800115}
116
sakal68b5df92017-03-17 09:01:59 -0700117- (void)tableView:(UITableView *)tableView
118updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
119 inSection:(int)section {
120 [self removeAllAccessories:tableView inSection:section];
121 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
122 cell.accessoryType = UITableViewCellAccessoryCheckmark;
123 [tableView deselectRowAtIndexPath:indexPath animated:YES];
denicijab04b5c22016-11-09 04:28:46 -0800124}
125
126#pragma mark - Table view delegate
127
denicijad17d5362016-11-02 02:56:09 -0700128- (nullable NSString *)tableView:(UITableView *)tableView
129 titleForHeaderInSection:(NSInteger)section {
sakal68b5df92017-03-17 09:01:59 -0700130 switch (section) {
Anders Carlssone1500582017-06-15 16:05:13 +0200131 case ARDSettingsSectionAudioSettings:
132 return @"Audio";
sakalc522e752017-04-05 12:17:48 -0700133 case ARDSettingsSectionVideoResolution:
134 return @"Video resolution";
sakal68b5df92017-03-17 09:01:59 -0700135 case ARDSettingsSectionVideoCodec:
136 return @"Video codec";
137 case ARDSettingsSectionBitRate:
138 return @"Maximum bitrate";
139 default:
140 return @"";
denicijad17d5362016-11-02 02:56:09 -0700141 }
denicijad17d5362016-11-02 02:56:09 -0700142}
143
144- (UITableViewCell *)tableView:(UITableView *)tableView
145 cellForRowAtIndexPath:(NSIndexPath *)indexPath {
sakal68b5df92017-03-17 09:01:59 -0700146 switch (indexPath.section) {
Anders Carlssone1500582017-06-15 16:05:13 +0200147 case ARDSettingsSectionAudioSettings:
148 return [self audioSettingsTableViewCellForTableView:tableView atIndexPath:indexPath];
149
sakalc522e752017-04-05 12:17:48 -0700150 case ARDSettingsSectionVideoResolution:
151 return [self videoResolutionTableViewCellForTableView:tableView atIndexPath:indexPath];
denicijab04b5c22016-11-09 04:28:46 -0800152
sakal68b5df92017-03-17 09:01:59 -0700153 case ARDSettingsSectionVideoCodec:
154 return [self videoCodecTableViewCellForTableView:tableView atIndexPath:indexPath];
denicijab04b5c22016-11-09 04:28:46 -0800155
sakal68b5df92017-03-17 09:01:59 -0700156 case ARDSettingsSectionBitRate:
157 return [self bitrateTableViewCellForTableView:tableView atIndexPath:indexPath];
denicijad17d5362016-11-02 02:56:09 -0700158
sakal68b5df92017-03-17 09:01:59 -0700159 default:
160 return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
161 reuseIdentifier:@"identifier"];
denicijad17d5362016-11-02 02:56:09 -0700162 }
denicijad17d5362016-11-02 02:56:09 -0700163}
164
165- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
sakal68b5df92017-03-17 09:01:59 -0700166 switch (indexPath.section) {
sakalc522e752017-04-05 12:17:48 -0700167 case ARDSettingsSectionVideoResolution:
168 [self tableView:tableView disSelectVideoResolutionAtIndex:indexPath];
sakal68b5df92017-03-17 09:01:59 -0700169 break;
170
171 case ARDSettingsSectionVideoCodec:
172 [self tableView:tableView didSelectVideoCodecCellAtIndexPath:indexPath];
173 break;
denicijad17d5362016-11-02 02:56:09 -0700174 }
175}
176
sakalc522e752017-04-05 12:17:48 -0700177#pragma mark - Table view delegate(Video Resolution)
denicijad17d5362016-11-02 02:56:09 -0700178
sakalc522e752017-04-05 12:17:48 -0700179- (UITableViewCell *)videoResolutionTableViewCellForTableView:(UITableView *)tableView
180 atIndexPath:(NSIndexPath *)indexPath {
181 NSString *dequeueIdentifier = @"ARDSettingsVideoResolutionViewCellIdentifier";
denicijad17d5362016-11-02 02:56:09 -0700182 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
183 if (!cell) {
184 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
185 reuseIdentifier:dequeueIdentifier];
186 }
Anders Carlssone1500582017-06-15 16:05:13 +0200187 NSString *resolution = self.videoResolutionArray[indexPath.row];
188 cell.textLabel.text = resolution;
189 if ([resolution isEqualToString:[_settingsModel currentVideoResolutionSettingFromStore]]) {
190 cell.accessoryType = UITableViewCellAccessoryCheckmark;
191 } else {
192 cell.accessoryType = UITableViewCellAccessoryNone;
193 }
194
denicijad17d5362016-11-02 02:56:09 -0700195 return cell;
196}
197
198- (void)tableView:(UITableView *)tableView
sakalc522e752017-04-05 12:17:48 -0700199 disSelectVideoResolutionAtIndex:(NSIndexPath *)indexPath {
sakal68b5df92017-03-17 09:01:59 -0700200 [self tableView:tableView
sakalc522e752017-04-05 12:17:48 -0700201 updateListSelectionAtIndexPath:indexPath
202 inSection:ARDSettingsSectionVideoResolution];
denicijad17d5362016-11-02 02:56:09 -0700203
sakalc522e752017-04-05 12:17:48 -0700204 NSString *videoResolution = self.videoResolutionArray[indexPath.row];
205 [_settingsModel storeVideoResolutionSetting:videoResolution];
denicijad17d5362016-11-02 02:56:09 -0700206}
207
sakal68b5df92017-03-17 09:01:59 -0700208#pragma mark - Table view delegate(Video Codec)
209
210- (UITableViewCell *)videoCodecTableViewCellForTableView:(UITableView *)tableView
211 atIndexPath:(NSIndexPath *)indexPath {
212 NSString *dequeueIdentifier = @"ARDSettingsVideoCodecCellIdentifier";
213 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
214 if (!cell) {
215 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
216 reuseIdentifier:dequeueIdentifier];
217 }
Anders Carlsson6bf43d22017-10-16 13:51:43 +0200218 RTCVideoCodecInfo *codec = self.videoCodecArray[indexPath.row];
219 cell.textLabel.text = [codec humanReadableDescription];
220 if ([codec isEqualToCodecInfo:[_settingsModel currentVideoCodecSettingFromStore]]) {
Anders Carlssone1500582017-06-15 16:05:13 +0200221 cell.accessoryType = UITableViewCellAccessoryCheckmark;
222 } else {
223 cell.accessoryType = UITableViewCellAccessoryNone;
224 }
sakal68b5df92017-03-17 09:01:59 -0700225
226 return cell;
227}
228
229- (void)tableView:(UITableView *)tableView
230 didSelectVideoCodecCellAtIndexPath:(NSIndexPath *)indexPath {
231 [self tableView:tableView
232 updateListSelectionAtIndexPath:indexPath
233 inSection:ARDSettingsSectionVideoCodec];
234
Anders Carlsson6bf43d22017-10-16 13:51:43 +0200235 RTCVideoCodecInfo *videoCodec = self.videoCodecArray[indexPath.row];
sakal68b5df92017-03-17 09:01:59 -0700236 [_settingsModel storeVideoCodecSetting:videoCodec];
denicijad17d5362016-11-02 02:56:09 -0700237}
238
denicijab04b5c22016-11-09 04:28:46 -0800239#pragma mark - Table view delegate(Bitrate)
240
241- (UITableViewCell *)bitrateTableViewCellForTableView:(UITableView *)tableView
242 atIndexPath:(NSIndexPath *)indexPath {
243 NSString *dequeueIdentifier = @"ARDSettingsBitrateCellIdentifier";
244 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
245 if (!cell) {
246 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
247 reuseIdentifier:dequeueIdentifier];
248
249 UITextField *textField = [[UITextField alloc]
250 initWithFrame:CGRectMake(10, 0, cell.bounds.size.width - 20, cell.bounds.size.height)];
denicija9af2b602016-11-17 00:43:43 -0800251 NSString *currentMaxBitrate = [_settingsModel currentMaxBitrateSettingFromStore].stringValue;
252 textField.text = currentMaxBitrate;
denicijab04b5c22016-11-09 04:28:46 -0800253 textField.placeholder = @"Enter max bit rate (kbps)";
254 textField.keyboardType = UIKeyboardTypeNumberPad;
denicija9af2b602016-11-17 00:43:43 -0800255 textField.delegate = self;
denicijab04b5c22016-11-09 04:28:46 -0800256
257 // Numerical keyboards have no return button, we need to add one manually.
258 UIToolbar *numberToolbar =
259 [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
260 numberToolbar.items = @[
261 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
262 target:nil
263 action:nil],
264 [[UIBarButtonItem alloc] initWithTitle:@"Apply"
265 style:UIBarButtonItemStyleDone
266 target:self
267 action:@selector(numberTextFieldDidEndEditing:)]
268 ];
269 [numberToolbar sizeToFit];
270
271 textField.inputAccessoryView = numberToolbar;
272 [cell addSubview:textField];
273 }
274 return cell;
275}
276
277- (void)numberTextFieldDidEndEditing:(id)sender {
278 [self.view endEditing:YES];
279}
280
denicija9af2b602016-11-17 00:43:43 -0800281- (void)textFieldDidEndEditing:(UITextField *)textField {
282 NSNumber *bitrateNumber = nil;
283
284 if (textField.text.length != 0) {
285 bitrateNumber = [NSNumber numberWithInteger:textField.text.intValue];
286 }
287
288 [_settingsModel storeMaxBitrateSetting:bitrateNumber];
289}
290
Anders Carlssone1500582017-06-15 16:05:13 +0200291#pragma mark - Table view delegate(Audio settings)
292
293- (UITableViewCell *)audioSettingsTableViewCellForTableView:(UITableView *)tableView
294 atIndexPath:(NSIndexPath *)indexPath {
295 NSString *dequeueIdentifier = @"ARDSettingsAudioSettingsCellIdentifier";
296 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
297 if (!cell) {
298 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
299 reuseIdentifier:dequeueIdentifier];
300 cell.selectionStyle = UITableViewCellSelectionStyleNone;
301 UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
302 switchView.tag = indexPath.row;
303 [switchView addTarget:self
304 action:@selector(audioSettingSwitchChanged:)
305 forControlEvents:UIControlEventValueChanged];
306 cell.accessoryView = switchView;
307 }
308
309 cell.textLabel.text = [self labelForAudioSettingAtIndexPathRow:indexPath.row];
310 UISwitch *switchView = (UISwitch *)cell.accessoryView;
311 switchView.on = [self valueForAudioSettingAtIndexPathRow:indexPath.row];
312
313 return cell;
314}
315
316- (NSString *)labelForAudioSettingAtIndexPathRow:(NSInteger)setting {
317 switch (setting) {
318 case ARDAudioSettingsAudioOnly:
319 return @"Audio only";
320 case ARDAudioSettingsCreateAecDump:
321 return @"Create AecDump";
322 case ARDAudioSettingsUseLevelController:
323 return @"Use level controller";
324 case ARDAudioSettingsUseManualAudioConfig:
325 return @"Use manual audio config";
326 default:
327 return @"";
328 }
329}
330
331- (BOOL)valueForAudioSettingAtIndexPathRow:(NSInteger)setting {
332 switch (setting) {
333 case ARDAudioSettingsAudioOnly:
334 return [_settingsModel currentAudioOnlySettingFromStore];
335 case ARDAudioSettingsCreateAecDump:
336 return [_settingsModel currentCreateAecDumpSettingFromStore];
337 case ARDAudioSettingsUseLevelController:
338 return [_settingsModel currentUseLevelControllerSettingFromStore];
339 case ARDAudioSettingsUseManualAudioConfig:
340 return [_settingsModel currentUseManualAudioConfigSettingFromStore];
341 default:
342 return NO;
343 }
344}
345
346- (void)audioSettingSwitchChanged:(UISwitch *)sender {
347 switch (sender.tag) {
348 case ARDAudioSettingsAudioOnly: {
349 [_settingsModel storeAudioOnlySetting:sender.isOn];
350 break;
351 }
352 case ARDAudioSettingsCreateAecDump: {
353 [_settingsModel storeCreateAecDumpSetting:sender.isOn];
354 break;
355 }
356 case ARDAudioSettingsUseLevelController: {
357 [_settingsModel storeUseLevelControllerSetting:sender.isOn];
358 break;
359 }
360 case ARDAudioSettingsUseManualAudioConfig: {
361 [_settingsModel storeUseManualAudioConfigSetting:sender.isOn];
362 break;
363 }
364 default:
365 break;
366 }
367}
368
denicijad17d5362016-11-02 02:56:09 -0700369@end
370NS_ASSUME_NONNULL_END