Update iOS AppRTCDemo to use level controller.

NOTRY=True
BUG=

Review-Url: https://codereview.webrtc.org/2294913003
Cr-Commit-Position: refs/heads/master@{#13977}
diff --git a/webrtc/examples/objc/AppRTCDemo/ARDAppClient+Internal.h b/webrtc/examples/objc/AppRTCDemo/ARDAppClient+Internal.h
index cdcac96..4a69899 100644
--- a/webrtc/examples/objc/AppRTCDemo/ARDAppClient+Internal.h
+++ b/webrtc/examples/objc/AppRTCDemo/ARDAppClient+Internal.h
@@ -45,6 +45,7 @@
 @property(nonatomic, readonly) BOOL isAudioOnly;
 @property(nonatomic, readonly) BOOL shouldMakeAecDump;
 @property(nonatomic, assign) BOOL isAecDumpActive;
+@property(nonatomic, readonly) BOOL shouldUseLevelControl;
 
 @property(nonatomic, strong)
     RTCMediaConstraints *defaultPeerConnectionConstraints;
diff --git a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.h b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.h
index 95e20d4..2186abe 100644
--- a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.h
+++ b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.h
@@ -65,10 +65,13 @@
 // 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
                  isLoopback:(BOOL)isLoopback
                 isAudioOnly:(BOOL)isAudioOnly
-          shouldMakeAecDump:(BOOL)shouldMakeAecDump;
+          shouldMakeAecDump:(BOOL)shouldMakeAecDump
+      shouldUseLevelControl:(BOOL)shouldUseLevelControl;
 
 // Disconnects from the AppRTC servers and any connected clients.
 - (void)disconnect;
diff --git a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
index a9dd8b1..ea86c5e 100644
--- a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
+++ b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
@@ -131,6 +131,7 @@
 @synthesize isAudioOnly = _isAudioOnly;
 @synthesize shouldMakeAecDump = _shouldMakeAecDump;
 @synthesize isAecDumpActive = _isAecDumpActive;
+@synthesize shouldUseLevelControl = _shouldUseLevelControl;
 
 - (instancetype)init {
   if (self = [super init]) {
@@ -223,12 +224,14 @@
 - (void)connectToRoomWithId:(NSString *)roomId
                  isLoopback:(BOOL)isLoopback
                 isAudioOnly:(BOOL)isAudioOnly
-          shouldMakeAecDump:(BOOL)shouldMakeAecDump {
+          shouldMakeAecDump:(BOOL)shouldMakeAecDump
+      shouldUseLevelControl:(BOOL)shouldUseLevelControl {
   NSParameterAssert(roomId.length);
   NSParameterAssert(_state == kARDAppClientStateDisconnected);
   _isLoopback = isLoopback;
   _isAudioOnly = isAudioOnly;
   _shouldMakeAecDump = shouldMakeAecDump;
+  _shouldUseLevelControl = shouldUseLevelControl;
   self.state = kARDAppClientStateConnecting;
 
 #if defined(WEBRTC_IOS)
@@ -689,10 +692,13 @@
 }
 
 - (RTCRtpSender *)createAudioSender {
+  RTCMediaConstraints *constraints = [self defaultMediaAudioConstraints];
+  RTCAudioSource *source = [_factory audioSourceWithConstraints:constraints];
+  RTCAudioTrack *track = [_factory audioTrackWithSource:source
+                                                trackId:kARDAudioTrackId];
   RTCRtpSender *sender =
       [_peerConnection senderWithKind:kRTCMediaStreamTrackKindAudio
                              streamId:kARDMediaStreamId];
-  RTCAudioTrack *track = [_factory audioTrackWithTrackId:kARDAudioTrackId];
   sender.track = track;
   return sender;
 }
@@ -744,6 +750,16 @@
 
 #pragma mark - Defaults
 
+ - (RTCMediaConstraints *)defaultMediaAudioConstraints {
+   NSString *valueLevelControl = _shouldUseLevelControl ?
+       kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse;
+   NSDictionary *mandatoryConstraints = @{ kRTCMediaConstraintsLevelControl : valueLevelControl };
+   RTCMediaConstraints* constraints =
+       [[RTCMediaConstraints alloc]  initWithMandatoryConstraints:mandatoryConstraints
+                                              optionalConstraints:nil];
+   return constraints;
+}
+
 - (RTCMediaConstraints *)defaultMediaStreamConstraints {
   RTCMediaConstraints* constraints =
       [[RTCMediaConstraints alloc]
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h
index e9f4991..81f9d00 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h
@@ -15,11 +15,12 @@
 @protocol ARDMainViewDelegate <NSObject>
 
 - (void)mainView:(ARDMainView *)mainView
-         didInputRoom:(NSString *)room
-           isLoopback:(BOOL)isLoopback
-          isAudioOnly:(BOOL)isAudioOnly
-    shouldMakeAecDump:(BOOL)shouldMakeAecDump
-       useManualAudio:(BOOL)useManualAudio;
+             didInputRoom:(NSString *)room
+               isLoopback:(BOOL)isLoopback
+              isAudioOnly:(BOOL)isAudioOnly
+        shouldMakeAecDump:(BOOL)shouldMakeAecDump
+    shouldUseLevelControl:(BOOL)shouldUseLevelControl
+           useManualAudio:(BOOL)useManualAudio;
 
 - (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView;
 
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.m b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.m
index 59b428a..d952204 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.m
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.m
@@ -121,6 +121,8 @@
   UILabel *_audioOnlyLabel;
   UISwitch *_aecdumpSwitch;
   UILabel *_aecdumpLabel;
+  UISwitch *_levelControlSwitch;
+  UILabel *_levelControlLabel;
   UISwitch *_loopbackSwitch;
   UILabel *_loopbackLabel;
   UISwitch *_useManualAudioSwitch;
@@ -187,6 +189,17 @@
     [_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;
@@ -299,9 +312,20 @@
   _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(_aecdumpSwitch.frame) + kCallControlMargin;
+      CGRectGetMaxY(_levelControlSwitch.frame) + kCallControlMargin;
   CGRect useManualAudioRect =
       CGRectMake(kCallControlMargin * 3,
                  useManualAudioTop,
@@ -361,6 +385,7 @@
                   isLoopback:_loopbackSwitch.isOn
                  isAudioOnly:_audioOnlySwitch.isOn
            shouldMakeAecDump:_aecdumpSwitch.isOn
+       shouldUseLevelControl:_levelControlSwitch.isOn
               useManualAudio:_useManualAudioSwitch.isOn];
 }
 
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m
index 21f00cb..e392168 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m
@@ -54,11 +54,12 @@
 #pragma mark - ARDMainViewDelegate
 
 - (void)mainView:(ARDMainView *)mainView
-         didInputRoom:(NSString *)room
-           isLoopback:(BOOL)isLoopback
-          isAudioOnly:(BOOL)isAudioOnly
-    shouldMakeAecDump:(BOOL)shouldMakeAecDump
-    useManualAudio:(BOOL)useManualAudio {
+             didInputRoom:(NSString *)room
+               isLoopback:(BOOL)isLoopback
+              isAudioOnly:(BOOL)isAudioOnly
+        shouldMakeAecDump:(BOOL)shouldMakeAecDump
+    shouldUseLevelControl:(BOOL)shouldUseLevelControl
+           useManualAudio:(BOOL)useManualAudio {
   if (!room.length) {
     [self showAlertWithMessage:@"Missing room name."];
     return;
@@ -98,6 +99,7 @@
                                            isLoopback:isLoopback
                                           isAudioOnly:isAudioOnly
                                     shouldMakeAecDump:shouldMakeAecDump
+                                shouldUseLevelControl:shouldUseLevelControl
                                              delegate:self];
   videoCallViewController.modalTransitionStyle =
       UIModalTransitionStyleCrossDissolve;
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h
index ffffd12..3ca2dc2 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h
@@ -25,6 +25,7 @@
                  isLoopback:(BOOL)isLoopback
                 isAudioOnly:(BOOL)isAudioOnly
           shouldMakeAecDump:(BOOL)shouldMakeAecDump
+      shouldUseLevelControl:(BOOL)shouldUseLevelControl
                    delegate:(id<ARDVideoCallViewControllerDelegate>)delegate;
 
 @end
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m
index bb49ca4..aa9ea21 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m
@@ -40,6 +40,7 @@
                  isLoopback:(BOOL)isLoopback
                 isAudioOnly:(BOOL)isAudioOnly
           shouldMakeAecDump:(BOOL)shouldMakeAecDump
+      shouldUseLevelControl:(BOOL)shouldUseLevelControl
                    delegate:(id<ARDVideoCallViewControllerDelegate>)delegate {
   if (self = [super init]) {
     _delegate = delegate;
@@ -47,7 +48,8 @@
     [_client connectToRoomWithId:room
                       isLoopback:isLoopback
                      isAudioOnly:isAudioOnly
-               shouldMakeAecDump:shouldMakeAecDump];
+               shouldMakeAecDump:shouldMakeAecDump
+           shouldUseLevelControl:shouldUseLevelControl];
   }
   return self;
 }
diff --git a/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m b/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m
index 0f4a54e..0f5bc38 100644
--- a/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m
+++ b/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m
@@ -284,7 +284,11 @@
         didEnterRoomId:(NSString*)roomId {
   [_client disconnect];
   ARDAppClient *client = [[ARDAppClient alloc] initWithDelegate:self];
-  [client connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO shouldMakeAecDump:NO];
+  [client connectToRoomWithId:roomId
+                   isLoopback:NO
+                  isAudioOnly:NO
+            shouldMakeAecDump:NO
+        shouldUseLevelControl:NO];
   _client = client;
 }
 
diff --git a/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm b/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm
index 355031e..c1fc08c 100644
--- a/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm
+++ b/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm
@@ -283,8 +283,16 @@
   weakAnswerer = answerer;
 
   // Kick off connection.
-  [caller connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO shouldMakeAecDump:NO];
-  [answerer connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO shouldMakeAecDump:NO];
+  [caller connectToRoomWithId:roomId
+                   isLoopback:NO
+                  isAudioOnly:NO
+            shouldMakeAecDump:NO
+        shouldUseLevelControl:NO];
+  [answerer connectToRoomWithId:roomId
+                     isLoopback:NO
+                    isAudioOnly:NO
+              shouldMakeAecDump:NO
+          shouldUseLevelControl:NO];
   [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
     if (error) {
       NSLog(@"Expectations error: %@", error);