blob: f2fea15c09493f0816429cc892a17542a18be1ac [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,
Anders Carlssone1500582017-06-15 16:05:13 +020027 ARDAudioSettingsUseManualAudioConfig,
28};
29
denicija9af2b602016-11-17 00:43:43 -080030@interface ARDSettingsViewController () <UITextFieldDelegate> {
denicija2256e042016-11-09 06:26:18 -080031 ARDSettingsModel *_settingsModel;
denicijad17d5362016-11-02 02:56:09 -070032}
33
34@end
35
36@implementation ARDSettingsViewController
37
38- (instancetype)initWithStyle:(UITableViewStyle)style
denicija2256e042016-11-09 06:26:18 -080039 settingsModel:(ARDSettingsModel *)settingsModel {
denicijad17d5362016-11-02 02:56:09 -070040 self = [super initWithStyle:style];
41 if (self) {
denicija2256e042016-11-09 06:26:18 -080042 _settingsModel = settingsModel;
denicijad17d5362016-11-02 02:56:09 -070043 }
44 return self;
45}
46
47#pragma mark - View lifecycle
48
49- (void)viewDidLoad {
50 [super viewDidLoad];
51 self.title = @"Settings";
52 [self addDoneBarButton];
53}
54
sakal68b5df92017-03-17 09:01:59 -070055- (void)viewWillAppear:(BOOL)animated {
56 [super viewWillAppear:animated];
sakal68b5df92017-03-17 09:01:59 -070057}
58
denicijad17d5362016-11-02 02:56:09 -070059#pragma mark - Data source
60
sakalc522e752017-04-05 12:17:48 -070061- (NSArray<NSString *> *)videoResolutionArray {
Anders Carlssone1500582017-06-15 16:05:13 +020062 return [_settingsModel availableVideoResolutions];
denicijad17d5362016-11-02 02:56:09 -070063}
64
Anders Carlsson6bf43d22017-10-16 13:51:43 +020065- (NSArray<RTCVideoCodecInfo *> *)videoCodecArray {
Anders Carlssone1500582017-06-15 16:05:13 +020066 return [_settingsModel availableVideoCodecs];
sakal68b5df92017-03-17 09:01:59 -070067}
68
denicijad17d5362016-11-02 02:56:09 -070069#pragma mark -
70
71- (void)addDoneBarButton {
72 UIBarButtonItem *barItem =
73 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
74 target:self
75 action:@selector(dismissModally:)];
76 self.navigationItem.leftBarButtonItem = barItem;
77}
78
denicijad17d5362016-11-02 02:56:09 -070079#pragma mark - Dismissal of view controller
80
81- (void)dismissModally:(id)sender {
82 [self dismissViewControllerAnimated:YES completion:nil];
83}
84
85#pragma mark - Table view data source
86
87- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
Anders Carlssone1500582017-06-15 16:05:13 +020088 return 4;
denicijad17d5362016-11-02 02:56:09 -070089}
90
denicija40532a12016-11-08 04:00:53 -080091- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
sakal68b5df92017-03-17 09:01:59 -070092 switch (section) {
Anders Carlssone1500582017-06-15 16:05:13 +020093 case ARDSettingsSectionAudioSettings:
Sam Zackrisson9e981f02018-02-28 16:20:58 +010094 return 3;
sakalc522e752017-04-05 12:17:48 -070095 case ARDSettingsSectionVideoResolution:
96 return self.videoResolutionArray.count;
sakal68b5df92017-03-17 09:01:59 -070097 case ARDSettingsSectionVideoCodec:
98 return self.videoCodecArray.count;
99 default:
100 return 1;
denicijab04b5c22016-11-09 04:28:46 -0800101 }
denicija3babb992016-11-07 07:23:56 -0800102}
103
sakal68b5df92017-03-17 09:01:59 -0700104#pragma mark - Table view delegate helpers
denicija40532a12016-11-08 04:00:53 -0800105
sakal68b5df92017-03-17 09:01:59 -0700106- (void)removeAllAccessories:(UITableView *)tableView
107 inSection:(int)section
108{
109 for (int i = 0; i < [tableView numberOfRowsInSection:section]; i++) {
110 NSIndexPath *rowPath = [NSIndexPath indexPathForRow:i inSection:section];
111 UITableViewCell *cell = [tableView cellForRowAtIndexPath:rowPath];
112 cell.accessoryType = UITableViewCellAccessoryNone;
113 }
denicijab04b5c22016-11-09 04:28:46 -0800114}
115
sakal68b5df92017-03-17 09:01:59 -0700116- (void)tableView:(UITableView *)tableView
117updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
118 inSection:(int)section {
119 [self removeAllAccessories:tableView inSection:section];
120 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
121 cell.accessoryType = UITableViewCellAccessoryCheckmark;
122 [tableView deselectRowAtIndexPath:indexPath animated:YES];
denicijab04b5c22016-11-09 04:28:46 -0800123}
124
125#pragma mark - Table view delegate
126
denicijad17d5362016-11-02 02:56:09 -0700127- (nullable NSString *)tableView:(UITableView *)tableView
128 titleForHeaderInSection:(NSInteger)section {
sakal68b5df92017-03-17 09:01:59 -0700129 switch (section) {
Anders Carlssone1500582017-06-15 16:05:13 +0200130 case ARDSettingsSectionAudioSettings:
131 return @"Audio";
sakalc522e752017-04-05 12:17:48 -0700132 case ARDSettingsSectionVideoResolution:
133 return @"Video resolution";
sakal68b5df92017-03-17 09:01:59 -0700134 case ARDSettingsSectionVideoCodec:
135 return @"Video codec";
136 case ARDSettingsSectionBitRate:
137 return @"Maximum bitrate";
138 default:
139 return @"";
denicijad17d5362016-11-02 02:56:09 -0700140 }
denicijad17d5362016-11-02 02:56:09 -0700141}
142
143- (UITableViewCell *)tableView:(UITableView *)tableView
144 cellForRowAtIndexPath:(NSIndexPath *)indexPath {
sakal68b5df92017-03-17 09:01:59 -0700145 switch (indexPath.section) {
Anders Carlssone1500582017-06-15 16:05:13 +0200146 case ARDSettingsSectionAudioSettings:
147 return [self audioSettingsTableViewCellForTableView:tableView atIndexPath:indexPath];
148
sakalc522e752017-04-05 12:17:48 -0700149 case ARDSettingsSectionVideoResolution:
150 return [self videoResolutionTableViewCellForTableView:tableView atIndexPath:indexPath];
denicijab04b5c22016-11-09 04:28:46 -0800151
sakal68b5df92017-03-17 09:01:59 -0700152 case ARDSettingsSectionVideoCodec:
153 return [self videoCodecTableViewCellForTableView:tableView atIndexPath:indexPath];
denicijab04b5c22016-11-09 04:28:46 -0800154
sakal68b5df92017-03-17 09:01:59 -0700155 case ARDSettingsSectionBitRate:
156 return [self bitrateTableViewCellForTableView:tableView atIndexPath:indexPath];
denicijad17d5362016-11-02 02:56:09 -0700157
sakal68b5df92017-03-17 09:01:59 -0700158 default:
159 return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
160 reuseIdentifier:@"identifier"];
denicijad17d5362016-11-02 02:56:09 -0700161 }
denicijad17d5362016-11-02 02:56:09 -0700162}
163
164- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
sakal68b5df92017-03-17 09:01:59 -0700165 switch (indexPath.section) {
sakalc522e752017-04-05 12:17:48 -0700166 case ARDSettingsSectionVideoResolution:
167 [self tableView:tableView disSelectVideoResolutionAtIndex:indexPath];
sakal68b5df92017-03-17 09:01:59 -0700168 break;
169
170 case ARDSettingsSectionVideoCodec:
171 [self tableView:tableView didSelectVideoCodecCellAtIndexPath:indexPath];
172 break;
denicijad17d5362016-11-02 02:56:09 -0700173 }
174}
175
sakalc522e752017-04-05 12:17:48 -0700176#pragma mark - Table view delegate(Video Resolution)
denicijad17d5362016-11-02 02:56:09 -0700177
sakalc522e752017-04-05 12:17:48 -0700178- (UITableViewCell *)videoResolutionTableViewCellForTableView:(UITableView *)tableView
179 atIndexPath:(NSIndexPath *)indexPath {
180 NSString *dequeueIdentifier = @"ARDSettingsVideoResolutionViewCellIdentifier";
denicijad17d5362016-11-02 02:56:09 -0700181 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
182 if (!cell) {
183 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
184 reuseIdentifier:dequeueIdentifier];
185 }
Anders Carlssone1500582017-06-15 16:05:13 +0200186 NSString *resolution = self.videoResolutionArray[indexPath.row];
187 cell.textLabel.text = resolution;
188 if ([resolution isEqualToString:[_settingsModel currentVideoResolutionSettingFromStore]]) {
189 cell.accessoryType = UITableViewCellAccessoryCheckmark;
190 } else {
191 cell.accessoryType = UITableViewCellAccessoryNone;
192 }
193
denicijad17d5362016-11-02 02:56:09 -0700194 return cell;
195}
196
197- (void)tableView:(UITableView *)tableView
sakalc522e752017-04-05 12:17:48 -0700198 disSelectVideoResolutionAtIndex:(NSIndexPath *)indexPath {
sakal68b5df92017-03-17 09:01:59 -0700199 [self tableView:tableView
sakalc522e752017-04-05 12:17:48 -0700200 updateListSelectionAtIndexPath:indexPath
201 inSection:ARDSettingsSectionVideoResolution];
denicijad17d5362016-11-02 02:56:09 -0700202
sakalc522e752017-04-05 12:17:48 -0700203 NSString *videoResolution = self.videoResolutionArray[indexPath.row];
204 [_settingsModel storeVideoResolutionSetting:videoResolution];
denicijad17d5362016-11-02 02:56:09 -0700205}
206
sakal68b5df92017-03-17 09:01:59 -0700207#pragma mark - Table view delegate(Video Codec)
208
209- (UITableViewCell *)videoCodecTableViewCellForTableView:(UITableView *)tableView
210 atIndexPath:(NSIndexPath *)indexPath {
211 NSString *dequeueIdentifier = @"ARDSettingsVideoCodecCellIdentifier";
212 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
213 if (!cell) {
214 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
215 reuseIdentifier:dequeueIdentifier];
216 }
Anders Carlsson6bf43d22017-10-16 13:51:43 +0200217 RTCVideoCodecInfo *codec = self.videoCodecArray[indexPath.row];
218 cell.textLabel.text = [codec humanReadableDescription];
219 if ([codec isEqualToCodecInfo:[_settingsModel currentVideoCodecSettingFromStore]]) {
Anders Carlssone1500582017-06-15 16:05:13 +0200220 cell.accessoryType = UITableViewCellAccessoryCheckmark;
221 } else {
222 cell.accessoryType = UITableViewCellAccessoryNone;
223 }
sakal68b5df92017-03-17 09:01:59 -0700224
225 return cell;
226}
227
228- (void)tableView:(UITableView *)tableView
229 didSelectVideoCodecCellAtIndexPath:(NSIndexPath *)indexPath {
230 [self tableView:tableView
231 updateListSelectionAtIndexPath:indexPath
232 inSection:ARDSettingsSectionVideoCodec];
233
Anders Carlsson6bf43d22017-10-16 13:51:43 +0200234 RTCVideoCodecInfo *videoCodec = self.videoCodecArray[indexPath.row];
sakal68b5df92017-03-17 09:01:59 -0700235 [_settingsModel storeVideoCodecSetting:videoCodec];
denicijad17d5362016-11-02 02:56:09 -0700236}
237
denicijab04b5c22016-11-09 04:28:46 -0800238#pragma mark - Table view delegate(Bitrate)
239
240- (UITableViewCell *)bitrateTableViewCellForTableView:(UITableView *)tableView
241 atIndexPath:(NSIndexPath *)indexPath {
242 NSString *dequeueIdentifier = @"ARDSettingsBitrateCellIdentifier";
243 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
244 if (!cell) {
245 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
246 reuseIdentifier:dequeueIdentifier];
247
248 UITextField *textField = [[UITextField alloc]
249 initWithFrame:CGRectMake(10, 0, cell.bounds.size.width - 20, cell.bounds.size.height)];
denicija9af2b602016-11-17 00:43:43 -0800250 NSString *currentMaxBitrate = [_settingsModel currentMaxBitrateSettingFromStore].stringValue;
251 textField.text = currentMaxBitrate;
denicijab04b5c22016-11-09 04:28:46 -0800252 textField.placeholder = @"Enter max bit rate (kbps)";
253 textField.keyboardType = UIKeyboardTypeNumberPad;
denicija9af2b602016-11-17 00:43:43 -0800254 textField.delegate = self;
denicijab04b5c22016-11-09 04:28:46 -0800255
256 // Numerical keyboards have no return button, we need to add one manually.
257 UIToolbar *numberToolbar =
258 [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
259 numberToolbar.items = @[
260 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
261 target:nil
262 action:nil],
263 [[UIBarButtonItem alloc] initWithTitle:@"Apply"
264 style:UIBarButtonItemStyleDone
265 target:self
266 action:@selector(numberTextFieldDidEndEditing:)]
267 ];
268 [numberToolbar sizeToFit];
269
270 textField.inputAccessoryView = numberToolbar;
271 [cell addSubview:textField];
272 }
273 return cell;
274}
275
276- (void)numberTextFieldDidEndEditing:(id)sender {
277 [self.view endEditing:YES];
278}
279
denicija9af2b602016-11-17 00:43:43 -0800280- (void)textFieldDidEndEditing:(UITextField *)textField {
281 NSNumber *bitrateNumber = nil;
282
283 if (textField.text.length != 0) {
284 bitrateNumber = [NSNumber numberWithInteger:textField.text.intValue];
285 }
286
287 [_settingsModel storeMaxBitrateSetting:bitrateNumber];
288}
289
Anders Carlssone1500582017-06-15 16:05:13 +0200290#pragma mark - Table view delegate(Audio settings)
291
292- (UITableViewCell *)audioSettingsTableViewCellForTableView:(UITableView *)tableView
293 atIndexPath:(NSIndexPath *)indexPath {
294 NSString *dequeueIdentifier = @"ARDSettingsAudioSettingsCellIdentifier";
295 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
296 if (!cell) {
297 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
298 reuseIdentifier:dequeueIdentifier];
299 cell.selectionStyle = UITableViewCellSelectionStyleNone;
300 UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
301 switchView.tag = indexPath.row;
302 [switchView addTarget:self
303 action:@selector(audioSettingSwitchChanged:)
304 forControlEvents:UIControlEventValueChanged];
305 cell.accessoryView = switchView;
306 }
307
308 cell.textLabel.text = [self labelForAudioSettingAtIndexPathRow:indexPath.row];
309 UISwitch *switchView = (UISwitch *)cell.accessoryView;
310 switchView.on = [self valueForAudioSettingAtIndexPathRow:indexPath.row];
311
312 return cell;
313}
314
315- (NSString *)labelForAudioSettingAtIndexPathRow:(NSInteger)setting {
316 switch (setting) {
317 case ARDAudioSettingsAudioOnly:
318 return @"Audio only";
319 case ARDAudioSettingsCreateAecDump:
320 return @"Create AecDump";
Anders Carlssone1500582017-06-15 16:05:13 +0200321 case ARDAudioSettingsUseManualAudioConfig:
322 return @"Use manual audio config";
323 default:
324 return @"";
325 }
326}
327
328- (BOOL)valueForAudioSettingAtIndexPathRow:(NSInteger)setting {
329 switch (setting) {
330 case ARDAudioSettingsAudioOnly:
331 return [_settingsModel currentAudioOnlySettingFromStore];
332 case ARDAudioSettingsCreateAecDump:
333 return [_settingsModel currentCreateAecDumpSettingFromStore];
Anders Carlssone1500582017-06-15 16:05:13 +0200334 case ARDAudioSettingsUseManualAudioConfig:
335 return [_settingsModel currentUseManualAudioConfigSettingFromStore];
336 default:
337 return NO;
338 }
339}
340
341- (void)audioSettingSwitchChanged:(UISwitch *)sender {
342 switch (sender.tag) {
343 case ARDAudioSettingsAudioOnly: {
344 [_settingsModel storeAudioOnlySetting:sender.isOn];
345 break;
346 }
347 case ARDAudioSettingsCreateAecDump: {
348 [_settingsModel storeCreateAecDumpSetting:sender.isOn];
349 break;
350 }
Anders Carlssone1500582017-06-15 16:05:13 +0200351 case ARDAudioSettingsUseManualAudioConfig: {
352 [_settingsModel storeUseManualAudioConfigSetting:sender.isOn];
353 break;
354 }
355 default:
356 break;
357 }
358}
359
denicijad17d5362016-11-02 02:56:09 -0700360@end
361NS_ASSUME_NONNULL_END