Move ADM initialization into WebRtcVoiceEngine

Bug: webrtc:4690
Change-Id: I3b8950fdb13835964c5bf41162731eff5048bf1a
Reviewed-on: https://webrtc-review.googlesource.com/23820
Commit-Queue: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20823}
diff --git a/media/engine/adm_helpers.cc b/media/engine/adm_helpers.cc
index b973ce6..119cc64 100644
--- a/media/engine/adm_helpers.cc
+++ b/media/engine/adm_helpers.cc
@@ -32,94 +32,50 @@
 #define AUDIO_DEVICE_ID (0u)
 #endif  // defined(WEBRTC_WIN)
 
-void SetRecordingDevice(AudioDeviceModule* adm) {
+void Init(AudioDeviceModule* adm) {
   RTC_DCHECK(adm);
 
-  // Save recording status and stop recording.
-  const bool was_recording = adm->Recording();
-  if (was_recording && adm->StopRecording() != 0) {
-    RTC_LOG(LS_ERROR) << "Unable to stop recording.";
-    return;
-  }
+  RTC_CHECK_EQ(0, adm->Init()) << "Failed to initialize the ADM.";
 
-  // Set device to default.
-  if (adm->SetRecordingDevice(AUDIO_DEVICE_ID) != 0) {
-    RTC_LOG(LS_ERROR) << "Unable to set recording device.";
-    return;
-  }
-
-  // Init microphone, so user can do volume settings etc.
-  if (adm->InitMicrophone() != 0) {
-    RTC_LOG(LS_ERROR) << "Unable to access microphone.";
-  }
-
-  // Set number of channels
-  bool available = false;
-  if (adm->StereoRecordingIsAvailable(&available) != 0) {
-    RTC_LOG(LS_ERROR) << "Failed to query stereo recording.";
-  }
-  if (adm->SetStereoRecording(available) != 0) {
-    RTC_LOG(LS_ERROR) << "Failed to set stereo recording mode.";
-  }
-
-  // Restore recording if it was enabled already when calling this function.
-  if (was_recording) {
-    if (adm->InitRecording() != 0) {
-      RTC_LOG(LS_ERROR) << "Failed to initialize recording.";
+  // Playout device.
+  {
+    if (adm->SetPlayoutDevice(AUDIO_DEVICE_ID) != 0) {
+      RTC_LOG(LS_ERROR) << "Unable to set playout device.";
       return;
     }
-    if (adm->StartRecording() != 0) {
-      RTC_LOG(LS_ERROR) << "Failed to start recording.";
-      return;
+    if (adm->InitSpeaker() != 0) {
+      RTC_LOG(LS_ERROR) << "Unable to access speaker.";
+    }
+
+    // Set number of channels
+    bool available = false;
+    if (adm->StereoPlayoutIsAvailable(&available) != 0) {
+      RTC_LOG(LS_ERROR) << "Failed to query stereo playout.";
+    }
+    if (adm->SetStereoPlayout(available) != 0) {
+      RTC_LOG(LS_ERROR) << "Failed to set stereo playout mode.";
     }
   }
 
-  RTC_LOG(LS_INFO) << "Set recording device.";
+  // Recording device.
+  {
+    if (adm->SetRecordingDevice(AUDIO_DEVICE_ID) != 0) {
+      RTC_LOG(LS_ERROR) << "Unable to set recording device.";
+      return;
+    }
+    if (adm->InitMicrophone() != 0) {
+      RTC_LOG(LS_ERROR) << "Unable to access microphone.";
+    }
+
+    // Set number of channels
+    bool available = false;
+    if (adm->StereoRecordingIsAvailable(&available) != 0) {
+      RTC_LOG(LS_ERROR) << "Failed to query stereo recording.";
+    }
+    if (adm->SetStereoRecording(available) != 0) {
+      RTC_LOG(LS_ERROR) << "Failed to set stereo recording mode.";
+    }
+  }
 }
-
-void SetPlayoutDevice(AudioDeviceModule* adm) {
-  RTC_DCHECK(adm);
-
-  // Save playing status and stop playout.
-  const bool was_playing = adm->Playing();
-  if (was_playing && adm->StopPlayout() != 0) {
-    RTC_LOG(LS_ERROR) << "Unable to stop playout.";
-  }
-
-  // Set device.
-  if (adm->SetPlayoutDevice(AUDIO_DEVICE_ID) != 0) {
-    RTC_LOG(LS_ERROR) << "Unable to set playout device.";
-    return;
-  }
-
-  // Init speaker, so user can do volume settings etc.
-  if (adm->InitSpeaker() != 0) {
-    RTC_LOG(LS_ERROR) << "Unable to access speaker.";
-  }
-
-  // Set number of channels
-  bool available = false;
-  if (adm->StereoPlayoutIsAvailable(&available) != 0) {
-    RTC_LOG(LS_ERROR) << "Failed to query stereo playout.";
-  }
-  if (adm->SetStereoPlayout(available) != 0) {
-    RTC_LOG(LS_ERROR) << "Failed to set stereo playout mode.";
-  }
-
-  // Restore recording if it was enabled already when calling this function.
-  if (was_playing) {
-    if (adm->InitPlayout() != 0) {
-      RTC_LOG(LS_ERROR) << "Failed to initialize playout.";
-      return;
-    }
-    if (adm->StartPlayout() != 0) {
-      RTC_LOG(LS_ERROR) << "Failed to start playout.";
-      return;
-    }
-  }
-
-  RTC_LOG(LS_INFO) << "Set playout device.";
-}
-
 }  // namespace adm_helpers
 }  // namespace webrtc
diff --git a/media/engine/adm_helpers.h b/media/engine/adm_helpers.h
index d04db17..c6ea3a2 100644
--- a/media/engine/adm_helpers.h
+++ b/media/engine/adm_helpers.h
@@ -19,8 +19,7 @@
 
 namespace adm_helpers {
 
-void SetRecordingDevice(AudioDeviceModule* adm);
-void SetPlayoutDevice(AudioDeviceModule* adm);
+void Init(AudioDeviceModule* adm);
 
 }  // namespace adm_helpers
 }  // namespace webrtc
diff --git a/media/engine/fakewebrtcvoiceengine.h b/media/engine/fakewebrtcvoiceengine.h
index 55d3100..9c9a428 100644
--- a/media/engine/fakewebrtcvoiceengine.h
+++ b/media/engine/fakewebrtcvoiceengine.h
@@ -69,9 +69,6 @@
     inited_ = false;
     return 0;
   }
-  webrtc::AudioDeviceModule* audio_device_module() override {
-    return nullptr;
-  }
   webrtc::voe::TransmitMixer* transmit_mixer() override {
     return transmit_mixer_;
   }
diff --git a/media/engine/webrtcvoiceengine.cc b/media/engine/webrtcvoiceengine.cc
index 19619a3..9630bc4 100644
--- a/media/engine/webrtcvoiceengine.cc
+++ b/media/engine/webrtcvoiceengine.cc
@@ -28,6 +28,7 @@
 #include "media/engine/payload_type_mapper.h"
 #include "media/engine/webrtcmediaengine.h"
 #include "media/engine/webrtcvoe.h"
+#include "modules/audio_device/audio_device_impl.h"
 #include "modules/audio_mixer/audio_mixer_impl.h"
 #include "modules/audio_processing/aec_dump/aec_dump_factory.h"
 #include "modules/audio_processing/include/audio_processing.h"
@@ -251,6 +252,12 @@
   if (initialized_) {
     StopAecDump();
     voe_wrapper_->base()->Terminate();
+
+    // Stop AudioDevice.
+    adm()->StopPlayout();
+    adm()->StopRecording();
+    adm()->RegisterAudioCallback(nullptr);
+    adm()->Terminate();
   }
 }
 
@@ -283,15 +290,17 @@
 
   channel_config_.enable_voice_pacing = true;
 
-  RTC_CHECK_EQ(0,
-               voe_wrapper_->base()->Init(adm_.get(), apm(), decoder_factory_));
-
-  // No ADM supplied? Get the default one from VoE.
+#if defined(WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE)
+  // No ADM supplied? Create a default one.
   if (!adm_) {
-    adm_ = voe_wrapper_->base()->audio_device_module();
+    adm_ = webrtc::AudioDeviceModule::Create(
+        webrtc::AudioDeviceModule::kPlatformDefaultAudio);
   }
-  RTC_DCHECK(adm_);
+#endif  // WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE
+  RTC_CHECK(adm());
+  webrtc::adm_helpers::Init(adm());
 
+  RTC_CHECK_EQ(0, voe_wrapper_->base()->Init(adm(), apm(), decoder_factory_));
   transmit_mixer_ = voe_wrapper_->base()->transmit_mixer();
   RTC_DCHECK(transmit_mixer_);
 
@@ -324,15 +333,16 @@
 
   // Set default audio devices.
 #if !defined(WEBRTC_IOS)
-  webrtc::adm_helpers::SetRecordingDevice(adm_);
   apm()->Initialize();
-  webrtc::adm_helpers::SetPlayoutDevice(adm_);
 #endif  // !WEBRTC_IOS
 
   // May be null for VoE injected for testing.
   if (voe()->engine()) {
     audio_state_ = webrtc::AudioState::Create(
         MakeAudioStateConfig(voe(), audio_mixer_, apm_));
+
+    // Connect the ADM to our audio path.
+    adm()->RegisterAudioCallback(audio_state_->audio_transport());
   }
 
   initialized_ = true;
@@ -708,7 +718,7 @@
 webrtc::AudioDeviceModule* WebRtcVoiceEngine::adm() {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   RTC_DCHECK(adm_);
-  return adm_;
+  return adm_.get();
 }
 
 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() const {
diff --git a/media/engine/webrtcvoiceengine_unittest.cc b/media/engine/webrtcvoiceengine_unittest.cc
index ef56473..f178262 100644
--- a/media/engine/webrtcvoiceengine_unittest.cc
+++ b/media/engine/webrtcvoiceengine_unittest.cc
@@ -85,23 +85,10 @@
 
 void AdmSetupExpectations(webrtc::test::MockAudioDeviceModule* adm) {
   RTC_DCHECK(adm);
+
+  // Setup.
   EXPECT_CALL(*adm, AddRef()).Times(1);
-  EXPECT_CALL(*adm, Release())
-      .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
-#if !defined(WEBRTC_IOS)
-  EXPECT_CALL(*adm, Recording()).WillOnce(Return(false));
-#if defined(WEBRTC_WIN)
-  EXPECT_CALL(*adm, SetRecordingDevice(
-      testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
-          webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
-              .WillOnce(Return(0));
-#else
-  EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
-#endif  // #if defined(WEBRTC_WIN)
-  EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
-  EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
-  EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
-  EXPECT_CALL(*adm, Playing()).WillOnce(Return(false));
+  EXPECT_CALL(*adm, Init()).WillOnce(Return(0));
 #if defined(WEBRTC_WIN)
   EXPECT_CALL(*adm, SetPlayoutDevice(
       testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
@@ -113,11 +100,29 @@
   EXPECT_CALL(*adm, InitSpeaker()).WillOnce(Return(0));
   EXPECT_CALL(*adm, StereoPlayoutIsAvailable(testing::_)).WillOnce(Return(0));
   EXPECT_CALL(*adm, SetStereoPlayout(false)).WillOnce(Return(0));
-#endif  // #if !defined(WEBRTC_IOS)
+#if defined(WEBRTC_WIN)
+  EXPECT_CALL(*adm, SetRecordingDevice(
+      testing::Matcher<webrtc::AudioDeviceModule::WindowsDeviceType>(
+          webrtc::AudioDeviceModule::kDefaultCommunicationDevice)))
+              .WillOnce(Return(0));
+#else
+  EXPECT_CALL(*adm, SetRecordingDevice(0)).WillOnce(Return(0));
+#endif  // #if defined(WEBRTC_WIN)
+  EXPECT_CALL(*adm, InitMicrophone()).WillOnce(Return(0));
+  EXPECT_CALL(*adm, StereoRecordingIsAvailable(testing::_)).WillOnce(Return(0));
+  EXPECT_CALL(*adm, SetStereoRecording(false)).WillOnce(Return(0));
   EXPECT_CALL(*adm, BuiltInAECIsAvailable()).WillOnce(Return(false));
   EXPECT_CALL(*adm, BuiltInAGCIsAvailable()).WillOnce(Return(false));
   EXPECT_CALL(*adm, BuiltInNSIsAvailable()).WillOnce(Return(false));
   EXPECT_CALL(*adm, SetAGC(true)).WillOnce(Return(0));
+
+  // Teardown.
+  EXPECT_CALL(*adm, StopPlayout()).WillOnce(Return(0));
+  EXPECT_CALL(*adm, StopRecording()).WillOnce(Return(0));
+  EXPECT_CALL(*adm, RegisterAudioCallback(nullptr)).WillOnce(Return(0));
+  EXPECT_CALL(*adm, Terminate()).WillOnce(Return(0));
+  EXPECT_CALL(*adm, Release())
+      .WillOnce(Return(rtc::RefCountReleaseStatus::kDroppedLastRef));
 }
 }  // namespace