Provide isAudioEnabled flag to control audio unit.

- Also removes async invoker usage in favor of thread posting

BUG=

Review-Url: https://codereview.webrtc.org/1945563003
Cr-Commit-Position: refs/heads/master@{#12651}
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h
index d3a583d..a783ca1 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.h
@@ -15,10 +15,10 @@
 @protocol ARDMainViewDelegate <NSObject>
 
 - (void)mainView:(ARDMainView *)mainView
-             didInputRoom:(NSString *)room
-               isLoopback:(BOOL)isLoopback
-              isAudioOnly:(BOOL)isAudioOnly
-   shouldDelayAudioConfig:(BOOL)shouldDelayAudioConfig;
+      didInputRoom:(NSString *)room
+        isLoopback:(BOOL)isLoopback
+       isAudioOnly:(BOOL)isAudioOnly
+    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 b264763..e7e0f94 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.m
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainView.m
@@ -122,8 +122,8 @@
   UILabel *_audioOnlyLabel;
   UISwitch *_loopbackSwitch;
   UILabel *_loopbackLabel;
-  UISwitch *_audioConfigDelaySwitch;
-  UILabel *_audioConfigDelayLabel;
+  UISwitch *_useManualAudioSwitch;
+  UILabel *_useManualAudioLabel;
   UIButton *_startCallButton;
   UIButton *_audioLoopButton;
 }
@@ -175,17 +175,17 @@
     [_loopbackLabel sizeToFit];
     [self addSubview:_loopbackLabel];
 
-    _audioConfigDelaySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
-    [_audioConfigDelaySwitch sizeToFit];
-    _audioConfigDelaySwitch.on = YES;
-    [self addSubview:_audioConfigDelaySwitch];
+    _useManualAudioSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
+    [_useManualAudioSwitch sizeToFit];
+    _useManualAudioSwitch.on = YES;
+    [self addSubview:_useManualAudioSwitch];
 
-    _audioConfigDelayLabel = [[UILabel alloc] initWithFrame:CGRectZero];
-    _audioConfigDelayLabel.text = @"Delay audio config";
-    _audioConfigDelayLabel.font = controlFont;
-    _audioConfigDelayLabel.textColor = controlFontColor;
-    [_audioConfigDelayLabel sizeToFit];
-    [self addSubview:_audioConfigDelayLabel];
+    _useManualAudioLabel = [[UILabel alloc] initWithFrame:CGRectZero];
+    _useManualAudioLabel.text = @"Use manual audio config";
+    _useManualAudioLabel.font = controlFont;
+    _useManualAudioLabel.textColor = controlFontColor;
+    [_useManualAudioLabel sizeToFit];
+    [self addSubview:_useManualAudioLabel];
 
     _startCallButton = [UIButton buttonWithType:UIButtonTypeSystem];
     _startCallButton.backgroundColor = [UIColor blueColor];
@@ -275,22 +275,22 @@
   _loopbackLabel.center = CGPointMake(loopbackModeLabelCenterX,
                                       CGRectGetMidY(loopbackModeRect));
 
-  CGFloat audioConfigDelayTop =
+  CGFloat useManualAudioTop =
       CGRectGetMaxY(_loopbackSwitch.frame) + kCallControlMargin;
-  CGRect audioConfigDelayRect =
+  CGRect useManualAudioRect =
       CGRectMake(kCallControlMargin * 3,
-                 audioConfigDelayTop,
-                 _audioConfigDelaySwitch.frame.size.width,
-                 _audioConfigDelaySwitch.frame.size.height);
-  _audioConfigDelaySwitch.frame = audioConfigDelayRect;
-  CGFloat audioConfigDelayLabelCenterX = CGRectGetMaxX(audioConfigDelayRect) +
-      kCallControlMargin + _audioConfigDelayLabel.frame.size.width / 2;
-  _audioConfigDelayLabel.center =
-      CGPointMake(audioConfigDelayLabelCenterX,
-                  CGRectGetMidY(audioConfigDelayRect));
+                 useManualAudioTop,
+                 _useManualAudioSwitch.frame.size.width,
+                 _useManualAudioSwitch.frame.size.height);
+  _useManualAudioSwitch.frame = useManualAudioRect;
+  CGFloat useManualAudioLabelCenterX = CGRectGetMaxX(useManualAudioRect) +
+      kCallControlMargin + _useManualAudioLabel.frame.size.width / 2;
+  _useManualAudioLabel.center =
+      CGPointMake(useManualAudioLabelCenterX,
+                  CGRectGetMidY(useManualAudioRect));
 
   CGFloat audioLoopTop =
-     CGRectGetMaxY(audioConfigDelayRect) + kCallControlMargin * 3;
+     CGRectGetMaxY(useManualAudioRect) + kCallControlMargin * 3;
   _audioLoopButton.frame = CGRectMake(kCallControlMargin,
                                       audioLoopTop,
                                       _audioLoopButton.frame.size.width,
@@ -335,7 +335,7 @@
                 didInputRoom:room
                   isLoopback:_loopbackSwitch.isOn
                  isAudioOnly:_audioOnlySwitch.isOn
-      shouldDelayAudioConfig:_audioConfigDelaySwitch.isOn];
+              useManualAudio:_useManualAudioSwitch.isOn];
 }
 
 @end
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m
index d11f092..a684ba3 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDMainViewController.m
@@ -23,13 +23,14 @@
 
 @interface ARDMainViewController () <
     ARDMainViewDelegate,
+    ARDVideoCallViewControllerDelegate,
     RTCAudioSessionDelegate>
 @end
 
 @implementation ARDMainViewController {
   ARDMainView *_mainView;
   AVAudioPlayer *_audioPlayer;
-  BOOL _shouldDelayAudioConfig;
+  BOOL _useManualAudio;
 }
 
 - (void)loadView {
@@ -37,17 +38,26 @@
   _mainView.delegate = self;
   self.view = _mainView;
 
-  [self setupAudioSession];
+  RTCAudioSessionConfiguration *webRTCConfig =
+      [RTCAudioSessionConfiguration webRTCConfiguration];
+  webRTCConfig.categoryOptions = webRTCConfig.categoryOptions |
+      AVAudioSessionCategoryOptionDefaultToSpeaker;
+  [RTCAudioSessionConfiguration setWebRTCConfiguration:webRTCConfig];
+
+  RTCAudioSession *session = [RTCAudioSession sharedInstance];
+  [session addDelegate:self];
+
+  [self configureAudioSession];
   [self setupAudioPlayer];
 }
 
 #pragma mark - ARDMainViewDelegate
 
 - (void)mainView:(ARDMainView *)mainView
-              didInputRoom:(NSString *)room
-                isLoopback:(BOOL)isLoopback
-               isAudioOnly:(BOOL)isAudioOnly
-    shouldDelayAudioConfig:(BOOL)shouldDelayAudioConfig {
+      didInputRoom:(NSString *)room
+        isLoopback:(BOOL)isLoopback
+       isAudioOnly:(BOOL)isAudioOnly
+    useManualAudio:(BOOL)useManualAudio {
   if (!room.length) {
     [self showAlertWithMessage:@"Missing room name."];
     return;
@@ -77,15 +87,16 @@
     return;
   }
 
-  _shouldDelayAudioConfig = shouldDelayAudioConfig;
   RTCAudioSession *session = [RTCAudioSession sharedInstance];
-  session.shouldDelayAudioConfiguration = _shouldDelayAudioConfig;
+  session.useManualAudio = useManualAudio;
+  session.isAudioEnabled = NO;
 
   // Kick off the video call.
   ARDVideoCallViewController *videoCallViewController =
       [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
                                            isLoopback:isLoopback
-                                          isAudioOnly:isAudioOnly];
+                                          isAudioOnly:isAudioOnly
+                                             delegate:self];
   videoCallViewController.modalTransitionStyle =
       UIModalTransitionStyleCrossDissolve;
   [self presentViewController:videoCallViewController
@@ -102,10 +113,22 @@
   mainView.isAudioLoopPlaying = _audioPlayer.playing;
 }
 
+#pragma mark - ARDVideoCallViewControllerDelegate
+
+- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController {
+  if (![viewController isBeingDismissed]) {
+    RTCLog(@"Dismissing VC");
+    [self dismissViewControllerAnimated:YES completion:^{
+      [self restartAudioPlayerIfNeeded];
+    }];
+  }
+  RTCAudioSession *session = [RTCAudioSession sharedInstance];
+  session.isAudioEnabled = NO;
+}
+
 #pragma mark - RTCAudioSessionDelegate
 
-- (void)audioSessionShouldConfigure:(RTCAudioSession *)session {
-  // Won't get called unless audio config is delayed.
+- (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session {
   // Stop playback on main queue and then configure WebRTC.
   [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
                                block:^{
@@ -113,35 +136,23 @@
       RTCLog(@"Stopping audio loop due to WebRTC start.");
       [_audioPlayer stop];
     }
-    // TODO(tkchin): Shouldn't lock on main queue. Figure out better way to
-    // check audio loop state.
-    [session lockForConfiguration];
-    [session configureWebRTCSession:nil];
-    [session unlockForConfiguration];
+    RTCLog(@"Setting isAudioEnabled to YES.");
+    session.isAudioEnabled = YES;
   }];
 }
 
-- (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session {
-  // Won't get called unless audio config is delayed.
-  [session lockForConfiguration];
-  [session unconfigureWebRTCSession:nil];
-  [session unlockForConfiguration];
-}
-
-- (void)audioSessionDidUnconfigure:(RTCAudioSession *)session {
+- (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session {
   // WebRTC is done with the audio session. Restart playback.
   [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
                                block:^{
-    if (_mainView.isAudioLoopPlaying) {
-      RTCLog(@"Starting audio loop due to WebRTC end.");
-      [_audioPlayer play];
-    }
+    RTCLog(@"audioSessionDidStopPlayOrRecord");
+    [self restartAudioPlayerIfNeeded];
   }];
 }
 
 #pragma mark - Private
 
-- (void)setupAudioSession {
+- (void)configureAudioSession {
   RTCAudioSessionConfiguration *configuration =
       [[RTCAudioSessionConfiguration alloc] init];
   configuration.category = AVAudioSessionCategoryAmbient;
@@ -149,10 +160,17 @@
   configuration.mode = AVAudioSessionModeDefault;
 
   RTCAudioSession *session = [RTCAudioSession sharedInstance];
-  [session addDelegate:self];
   [session lockForConfiguration];
+  BOOL hasSucceeded = NO;
   NSError *error = nil;
-  if (![session setConfiguration:configuration active:YES error:&error]) {
+  if (session.isActive) {
+    hasSucceeded = [session setConfiguration:configuration error:&error];
+  } else {
+    hasSucceeded = [session setConfiguration:configuration
+                                      active:YES
+                                       error:&error];
+  }
+  if (!hasSucceeded) {
     RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
   }
   [session unlockForConfiguration];
@@ -169,6 +187,14 @@
   [_audioPlayer prepareToPlay];
 }
 
+- (void)restartAudioPlayerIfNeeded {
+  if (_mainView.isAudioLoopPlaying && !self.presentedViewController) {
+    RTCLog(@"Starting audio loop due to WebRTC end.");
+    [self configureAudioSession];
+    [_audioPlayer play];
+  }
+}
+
 - (void)showAlertWithMessage:(NSString*)message {
   UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
                                                       message:message
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h
index 7dee2d8..f3a9554 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.h
@@ -10,10 +10,20 @@
 
 #import <UIKit/UIKit.h>
 
+@class ARDVideoCallViewController;
+@protocol ARDVideoCallViewControllerDelegate <NSObject>
+
+- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController;
+
+@end
+
 @interface ARDVideoCallViewController : UIViewController
 
+@property(nonatomic, weak) id<ARDVideoCallViewControllerDelegate> delegate;
+
 - (instancetype)initForRoom:(NSString *)room
                  isLoopback:(BOOL)isLoopback
-                isAudioOnly:(BOOL)isAudioOnly;
+                isAudioOnly:(BOOL)isAudioOnly
+                   delegate:(id<ARDVideoCallViewControllerDelegate>)delegate;
 
 @end
diff --git a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m
index 80bbb10..d35e1e6 100644
--- a/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m
+++ b/webrtc/examples/objc/AppRTCDemo/ios/ARDVideoCallViewController.m
@@ -34,11 +34,14 @@
 }
 
 @synthesize videoCallView = _videoCallView;
+@synthesize delegate = _delegate;
 
 - (instancetype)initForRoom:(NSString *)room
                  isLoopback:(BOOL)isLoopback
-                isAudioOnly:(BOOL)isAudioOnly {
+                isAudioOnly:(BOOL)isAudioOnly
+                   delegate:(id<ARDVideoCallViewControllerDelegate>)delegate {
   if (self = [super init]) {
+    _delegate = delegate;
     _client = [[ARDAppClient alloc] initWithDelegate:self];
     [_client connectToRoomWithId:room
                       isLoopback:isLoopback
@@ -177,10 +180,7 @@
   self.remoteVideoTrack = nil;
   self.localVideoTrack = nil;
   [_client disconnect];
-  if (![self isBeingDismissed]) {
-    [self.presentingViewController dismissViewControllerAnimated:YES
-                                                      completion:nil];
-  }
+  [_delegate viewControllerDidFinish:self];
 }
 
 - (void)switchCamera {