Loopback and audio only mode.

Adds a loopback button that will connect to itself by simulating another client connection to the web socket server.

Adds an audio only mode switch.

BUG=

Review URL: https://codereview.webrtc.org/1334003002

Cr-Commit-Position: refs/heads/master@{#10153}
diff --git a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
index e53222e..33e00ed 100644
--- a/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
+++ b/webrtc/examples/objc/AppRTCDemo/ARDAppClient.m
@@ -99,6 +99,7 @@
 @synthesize delegate = _delegate;
 @synthesize roomServerClient = _roomServerClient;
 @synthesize channel = _channel;
+@synthesize loopbackChannel = _loopbackChannel;
 @synthesize turnClient = _turnClient;
 @synthesize peerConnection = _peerConnection;
 @synthesize factory = _factory;
@@ -113,6 +114,8 @@
 @synthesize webSocketRestURL = _websocketRestURL;
 @synthesize defaultPeerConnectionConstraints =
     _defaultPeerConnectionConstraints;
+@synthesize isLoopback = _isLoopback;
+@synthesize isAudioOnly = _isAudioOnly;
 
 - (instancetype)init {
   if (self = [super init]) {
@@ -198,9 +201,12 @@
 }
 
 - (void)connectToRoomWithId:(NSString *)roomId
-                    options:(NSDictionary *)options {
+                 isLoopback:(BOOL)isLoopback
+                isAudioOnly:(BOOL)isAudioOnly {
   NSParameterAssert(roomId.length);
   NSParameterAssert(_state == kARDAppClientStateDisconnected);
+  _isLoopback = isLoopback;
+  _isAudioOnly = isAudioOnly;
   self.state = kARDAppClientStateConnecting;
 
   // Request TURN.
@@ -219,6 +225,7 @@
 
   // Join room on room server.
   [_roomServerClient joinRoomWithRoomId:roomId
+                             isLoopback:isLoopback
       completionHandler:^(ARDJoinResponse *response, NSError *error) {
     ARDAppClient *strongSelf = weakSelf;
     if (error) {
@@ -579,14 +586,17 @@
   // TODO(tkchin): local video capture for OSX. See
   // https://code.google.com/p/webrtc/issues/detail?id=3417.
 #if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE
-  RTCMediaConstraints *mediaConstraints = [self defaultMediaStreamConstraints];
-  RTCAVFoundationVideoSource *source =
-      [[RTCAVFoundationVideoSource alloc] initWithFactory:_factory
-                                              constraints:mediaConstraints];
-  localVideoTrack =
-      [[RTCVideoTrack alloc] initWithFactory:_factory
-                                      source:source
-                                     trackId:@"ARDAMSv0"];
+  if (!_isAudioOnly) {
+    RTCMediaConstraints *mediaConstraints =
+        [self defaultMediaStreamConstraints];
+    RTCAVFoundationVideoSource *source =
+        [[RTCAVFoundationVideoSource alloc] initWithFactory:_factory
+                                                constraints:mediaConstraints];
+    localVideoTrack =
+        [[RTCVideoTrack alloc] initWithFactory:_factory
+                                        source:source
+                                       trackId:@"ARDAMSv0"];
+  }
 #endif
   return localVideoTrack;
 }
@@ -603,8 +613,16 @@
         [[ARDWebSocketChannel alloc] initWithURL:_websocketURL
                                          restURL:_websocketRestURL
                                         delegate:self];
+    if (_isLoopback) {
+      _loopbackChannel =
+          [[ARDLoopbackWebSocketChannel alloc] initWithURL:_websocketURL
+                                                   restURL:_websocketRestURL];
+    }
   }
   [_channel registerForRoomId:_roomId clientId:_clientId];
+  if (_isLoopback) {
+    [_loopbackChannel registerForRoomId:_roomId clientId:@"LOOPBACK_CLIENT_ID"];
+  }
 }
 
 #pragma mark - Defaults
@@ -637,8 +655,9 @@
   if (_defaultPeerConnectionConstraints) {
     return _defaultPeerConnectionConstraints;
   }
+  NSString *value = _isLoopback ? @"false" : @"true";
   NSArray *optionalConstraints = @[
-      [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:@"true"]
+      [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:value]
   ];
   RTCMediaConstraints* constraints =
       [[RTCMediaConstraints alloc]