tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ARDSettingsViewController.m (12755B)


      1 /*
      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"
     12 #import "ARDSettingsModel.h"
     13 #import "RTCVideoCodecInfo+HumanReadable.h"
     14 
     15 NS_ASSUME_NONNULL_BEGIN
     16 
     17 typedef NS_ENUM(int, ARDSettingsSections) {
     18  ARDSettingsSectionAudioSettings = 0,
     19  ARDSettingsSectionVideoResolution,
     20  ARDSettingsSectionVideoCodec,
     21  ARDSettingsSectionBitRate,
     22 };
     23 
     24 typedef NS_ENUM(int, ARDAudioSettingsOptions) {
     25  ARDAudioSettingsAudioOnly = 0,
     26  ARDAudioSettingsCreateAecDump,
     27  ARDAudioSettingsUseManualAudioConfig,
     28 };
     29 
     30 @interface ARDSettingsViewController () <UITextFieldDelegate> {
     31  ARDSettingsModel *_settingsModel;
     32 }
     33 
     34 @end
     35 
     36 @implementation ARDSettingsViewController
     37 
     38 - (instancetype)initWithStyle:(UITableViewStyle)style
     39                settingsModel:(ARDSettingsModel *)settingsModel {
     40  self = [super initWithStyle:style];
     41  if (self) {
     42    _settingsModel = settingsModel;
     43  }
     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 
     55 - (void)viewWillAppear:(BOOL)animated {
     56  [super viewWillAppear:animated];
     57 }
     58 
     59 #pragma mark - Data source
     60 
     61 - (NSArray<NSString *> *)videoResolutionArray {
     62  return [_settingsModel availableVideoResolutions];
     63 }
     64 
     65 - (NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)videoCodecArray {
     66  return [_settingsModel availableVideoCodecs];
     67 }
     68 
     69 #pragma mark -
     70 
     71 - (void)addDoneBarButton {
     72  UIBarButtonItem *barItem = [[UIBarButtonItem alloc]
     73      initWithBarButtonSystemItem:UIBarButtonSystemItemDone
     74                           target:self
     75                           action:@selector(dismissModally:)];
     76  self.navigationItem.leftBarButtonItem = barItem;
     77 }
     78 
     79 #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 {
     88  return 4;
     89 }
     90 
     91 - (NSInteger)tableView:(UITableView *)tableView
     92    numberOfRowsInSection:(NSInteger)section {
     93  switch (section) {
     94    case ARDSettingsSectionAudioSettings:
     95      return 3;
     96    case ARDSettingsSectionVideoResolution:
     97      return self.videoResolutionArray.count;
     98    case ARDSettingsSectionVideoCodec:
     99      return self.videoCodecArray.count;
    100    default:
    101      return 1;
    102  }
    103 }
    104 
    105 #pragma mark - Table view delegate helpers
    106 
    107 - (void)removeAllAccessories:(UITableView *)tableView inSection:(int)section {
    108  for (int i = 0; i < [tableView numberOfRowsInSection:section]; i++) {
    109    NSIndexPath *rowPath = [NSIndexPath indexPathForRow:i inSection:section];
    110    UITableViewCell *cell = [tableView cellForRowAtIndexPath:rowPath];
    111    cell.accessoryType = UITableViewCellAccessoryNone;
    112  }
    113 }
    114 
    115 - (void)tableView:(UITableView *)tableView
    116    updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
    117                         inSection:(int)section {
    118  [self removeAllAccessories:tableView inSection:section];
    119  UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    120  cell.accessoryType = UITableViewCellAccessoryCheckmark;
    121  [tableView deselectRowAtIndexPath:indexPath animated:YES];
    122 }
    123 
    124 #pragma mark - Table view delegate
    125 
    126 - (nullable NSString *)tableView:(UITableView *)tableView
    127         titleForHeaderInSection:(NSInteger)section {
    128  switch (section) {
    129    case ARDSettingsSectionAudioSettings:
    130      return @"Audio";
    131    case ARDSettingsSectionVideoResolution:
    132      return @"Video resolution";
    133    case ARDSettingsSectionVideoCodec:
    134      return @"Video codec";
    135    case ARDSettingsSectionBitRate:
    136      return @"Maximum bitrate";
    137    default:
    138      return @"";
    139  }
    140 }
    141 
    142 - (UITableViewCell *)tableView:(UITableView *)tableView
    143         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    144  switch (indexPath.section) {
    145    case ARDSettingsSectionAudioSettings:
    146      return [self audioSettingsTableViewCellForTableView:tableView
    147                                              atIndexPath:indexPath];
    148 
    149    case ARDSettingsSectionVideoResolution:
    150      return [self videoResolutionTableViewCellForTableView:tableView
    151                                                atIndexPath:indexPath];
    152 
    153    case ARDSettingsSectionVideoCodec:
    154      return [self videoCodecTableViewCellForTableView:tableView
    155                                           atIndexPath:indexPath];
    156 
    157    case ARDSettingsSectionBitRate:
    158      return [self bitrateTableViewCellForTableView:tableView
    159                                        atIndexPath:indexPath];
    160 
    161    default:
    162      return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    163                                    reuseIdentifier:@"identifier"];
    164  }
    165 }
    166 
    167 - (void)tableView:(UITableView *)tableView
    168    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    169  switch (indexPath.section) {
    170    case ARDSettingsSectionVideoResolution:
    171      [self tableView:tableView disSelectVideoResolutionAtIndex:indexPath];
    172      break;
    173 
    174    case ARDSettingsSectionVideoCodec:
    175      [self tableView:tableView didSelectVideoCodecCellAtIndexPath:indexPath];
    176      break;
    177  }
    178 }
    179 
    180 #pragma mark - Table view delegate(Video Resolution)
    181 
    182 - (UITableViewCell *)
    183    videoResolutionTableViewCellForTableView:(UITableView *)tableView
    184                                 atIndexPath:(NSIndexPath *)indexPath {
    185  NSString *dequeueIdentifier = @"ARDSettingsVideoResolutionViewCellIdentifier";
    186  UITableViewCell *cell =
    187      [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
    188  if (!cell) {
    189    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    190                                  reuseIdentifier:dequeueIdentifier];
    191  }
    192  NSString *resolution = self.videoResolutionArray[indexPath.row];
    193  cell.textLabel.text = resolution;
    194  if ([resolution
    195          isEqualToString:[_settingsModel
    196                              currentVideoResolutionSettingFromStore]]) {
    197    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    198  } else {
    199    cell.accessoryType = UITableViewCellAccessoryNone;
    200  }
    201 
    202  return cell;
    203 }
    204 
    205 - (void)tableView:(UITableView *)tableView
    206    disSelectVideoResolutionAtIndex:(NSIndexPath *)indexPath {
    207  [self tableView:tableView
    208      updateListSelectionAtIndexPath:indexPath
    209                           inSection:ARDSettingsSectionVideoResolution];
    210 
    211  NSString *videoResolution = self.videoResolutionArray[indexPath.row];
    212  [_settingsModel storeVideoResolutionSetting:videoResolution];
    213 }
    214 
    215 #pragma mark - Table view delegate(Video Codec)
    216 
    217 - (UITableViewCell *)
    218    videoCodecTableViewCellForTableView:(UITableView *)tableView
    219                            atIndexPath:(NSIndexPath *)indexPath {
    220  NSString *dequeueIdentifier = @"ARDSettingsVideoCodecCellIdentifier";
    221  UITableViewCell *cell =
    222      [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
    223  if (!cell) {
    224    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    225                                  reuseIdentifier:dequeueIdentifier];
    226  }
    227  RTC_OBJC_TYPE(RTCVideoCodecInfo) *codec = self.videoCodecArray[indexPath.row];
    228  cell.textLabel.text = [codec humanReadableDescription];
    229  if ([codec isEqualToCodecInfo:[_settingsModel
    230                                    currentVideoCodecSettingFromStore]]) {
    231    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    232  } else {
    233    cell.accessoryType = UITableViewCellAccessoryNone;
    234  }
    235 
    236  return cell;
    237 }
    238 
    239 - (void)tableView:(UITableView *)tableView
    240    didSelectVideoCodecCellAtIndexPath:(NSIndexPath *)indexPath {
    241  [self tableView:tableView
    242      updateListSelectionAtIndexPath:indexPath
    243                           inSection:ARDSettingsSectionVideoCodec];
    244 
    245  RTC_OBJC_TYPE(RTCVideoCodecInfo) *videoCodec =
    246      self.videoCodecArray[indexPath.row];
    247  [_settingsModel storeVideoCodecSetting:videoCodec];
    248 }
    249 
    250 #pragma mark - Table view delegate(Bitrate)
    251 
    252 - (UITableViewCell *)bitrateTableViewCellForTableView:(UITableView *)tableView
    253                                          atIndexPath:(NSIndexPath *)indexPath {
    254  NSString *dequeueIdentifier = @"ARDSettingsBitrateCellIdentifier";
    255  UITableViewCell *cell =
    256      [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
    257  if (!cell) {
    258    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    259                                  reuseIdentifier:dequeueIdentifier];
    260 
    261    UITextField *textField = [[UITextField alloc]
    262        initWithFrame:CGRectMake(10,
    263                                 0,
    264                                 cell.bounds.size.width - 20,
    265                                 cell.bounds.size.height)];
    266    NSString *currentMaxBitrate =
    267        [_settingsModel currentMaxBitrateSettingFromStore].stringValue;
    268    textField.text = currentMaxBitrate;
    269    textField.placeholder = @"Enter max bit rate (kbps)";
    270    textField.keyboardType = UIKeyboardTypeNumberPad;
    271    textField.delegate = self;
    272 
    273    // Numerical keyboards have no return button, we need to add one manually.
    274    UIToolbar *numberToolbar = [[UIToolbar alloc]
    275        initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
    276    numberToolbar.items = @[
    277      [[UIBarButtonItem alloc]
    278          initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
    279                               target:nil
    280                               action:nil],
    281      [[UIBarButtonItem alloc]
    282          initWithTitle:@"Apply"
    283                  style:UIBarButtonItemStyleDone
    284                 target:self
    285                 action:@selector(numberTextFieldDidEndEditing:)]
    286    ];
    287    [numberToolbar sizeToFit];
    288 
    289    textField.inputAccessoryView = numberToolbar;
    290    [cell addSubview:textField];
    291  }
    292  return cell;
    293 }
    294 
    295 - (void)numberTextFieldDidEndEditing:(id)sender {
    296  [self.view endEditing:YES];
    297 }
    298 
    299 - (void)textFieldDidEndEditing:(UITextField *)textField {
    300  NSNumber *bitrateNumber = nil;
    301 
    302  if (textField.text.length != 0) {
    303    bitrateNumber = [NSNumber numberWithInteger:textField.text.intValue];
    304  }
    305 
    306  [_settingsModel storeMaxBitrateSetting:bitrateNumber];
    307 }
    308 
    309 #pragma mark - Table view delegate(Audio settings)
    310 
    311 - (UITableViewCell *)
    312    audioSettingsTableViewCellForTableView:(UITableView *)tableView
    313                               atIndexPath:(NSIndexPath *)indexPath {
    314  NSString *dequeueIdentifier = @"ARDSettingsAudioSettingsCellIdentifier";
    315  UITableViewCell *cell =
    316      [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
    317  if (!cell) {
    318    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    319                                  reuseIdentifier:dequeueIdentifier];
    320    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    321    UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
    322    switchView.tag = indexPath.row;
    323    [switchView addTarget:self
    324                   action:@selector(audioSettingSwitchChanged:)
    325         forControlEvents:UIControlEventValueChanged];
    326    cell.accessoryView = switchView;
    327  }
    328 
    329  cell.textLabel.text = [self labelForAudioSettingAtIndexPathRow:indexPath.row];
    330  UISwitch *switchView = (UISwitch *)cell.accessoryView;
    331  switchView.on = [self valueForAudioSettingAtIndexPathRow:indexPath.row];
    332 
    333  return cell;
    334 }
    335 
    336 - (NSString *)labelForAudioSettingAtIndexPathRow:(NSInteger)setting {
    337  switch (setting) {
    338    case ARDAudioSettingsAudioOnly:
    339      return @"Audio only";
    340    case ARDAudioSettingsCreateAecDump:
    341      return @"Create AecDump";
    342    case ARDAudioSettingsUseManualAudioConfig:
    343      return @"Use manual audio config";
    344    default:
    345      return @"";
    346  }
    347 }
    348 
    349 - (BOOL)valueForAudioSettingAtIndexPathRow:(NSInteger)setting {
    350  switch (setting) {
    351    case ARDAudioSettingsAudioOnly:
    352      return [_settingsModel currentAudioOnlySettingFromStore];
    353    case ARDAudioSettingsCreateAecDump:
    354      return [_settingsModel currentCreateAecDumpSettingFromStore];
    355    case ARDAudioSettingsUseManualAudioConfig:
    356      return [_settingsModel currentUseManualAudioConfigSettingFromStore];
    357    default:
    358      return NO;
    359  }
    360 }
    361 
    362 - (void)audioSettingSwitchChanged:(UISwitch *)sender {
    363  switch (sender.tag) {
    364    case ARDAudioSettingsAudioOnly: {
    365      [_settingsModel storeAudioOnlySetting:sender.isOn];
    366      break;
    367    }
    368    case ARDAudioSettingsCreateAecDump: {
    369      [_settingsModel storeCreateAecDumpSetting:sender.isOn];
    370      break;
    371    }
    372    case ARDAudioSettingsUseManualAudioConfig: {
    373      [_settingsModel storeUseManualAudioConfigSetting:sender.isOn];
    374      break;
    375    }
    376    default:
    377      break;
    378  }
    379 }
    380 
    381 @end
    382 NS_ASSUME_NONNULL_END