APM: Add build flag to allow building WebRTC without APM

This CL adds a build flag to allow building the non-test parts
of WebRTC without the audio processing module.
The CL also ensures that the WebRTC code correctly handles
the case when no APM is available.

Bug: webrtc:5298
Change-Id: I5c8b5d1f7115e5cce2af4c2b5ff701fa1c54e49e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/171509
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31133}
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index 69f94fa..46207aa 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -116,6 +116,7 @@
   visibility = [ "*" ]
   configs += [ ":apm_debug_dump" ]
   sources = [
+    "audio_processing_builder_impl.cc",
     "audio_processing_impl.cc",
     "audio_processing_impl.h",
     "common.h",
@@ -169,6 +170,7 @@
     "../../rtc_base:deprecation",
     "../../rtc_base:gtest_prod",
     "../../rtc_base:ignore_wundef",
+    "../../rtc_base:refcount",
     "../../rtc_base:safe_minmax",
     "../../rtc_base:sanitizer",
     "../../rtc_base/system:rtc_export",
@@ -556,41 +558,6 @@
     }  # audioproc_f_impl
   }
 
-  rtc_library("audioproc_test_utils") {
-    visibility = [ "*" ]
-    testonly = true
-    sources = [
-      "test/audio_buffer_tools.cc",
-      "test/audio_buffer_tools.h",
-      "test/bitexactness_tools.cc",
-      "test/bitexactness_tools.h",
-      "test/performance_timer.cc",
-      "test/performance_timer.h",
-      "test/simulator_buffers.cc",
-      "test/simulator_buffers.h",
-      "test/test_utils.cc",
-      "test/test_utils.h",
-    ]
-
-    deps = [
-      ":api",
-      ":audio_buffer",
-      ":audio_processing",
-      "../../api:array_view",
-      "../../api/audio:audio_frame_api",
-      "../../common_audio",
-      "../../rtc_base:checks",
-      "../../rtc_base:rtc_base_approved",
-      "../../rtc_base/system:arch",
-      "../../system_wrappers",
-      "../../test:fileutils",
-      "../../test:test_support",
-      "../audio_coding:neteq_input_audio_tools",
-      "//testing/gtest",
-      "//third_party/abseil-cpp/absl/types:optional",
-    ]
-  }
-
   if (rtc_enable_protobuf) {
     proto_library("audioproc_unittest_proto") {
       sources = [ "test/unittest.proto" ]
@@ -629,3 +596,42 @@
     }
   }
 }
+
+rtc_library("audioproc_test_utils") {
+  visibility = [ "*" ]
+  testonly = true
+  sources = [
+    "test/audio_buffer_tools.cc",
+    "test/audio_buffer_tools.h",
+    "test/audio_processing_builder_for_testing.cc",
+    "test/audio_processing_builder_for_testing.h",
+    "test/bitexactness_tools.cc",
+    "test/bitexactness_tools.h",
+    "test/performance_timer.cc",
+    "test/performance_timer.h",
+    "test/simulator_buffers.cc",
+    "test/simulator_buffers.h",
+    "test/test_utils.cc",
+    "test/test_utils.h",
+  ]
+
+  configs += [ ":apm_debug_dump" ]
+
+  deps = [
+    ":api",
+    ":audio_buffer",
+    ":audio_processing",
+    "../../api:array_view",
+    "../../api/audio:audio_frame_api",
+    "../../common_audio",
+    "../../rtc_base:checks",
+    "../../rtc_base:rtc_base_approved",
+    "../../rtc_base/system:arch",
+    "../../system_wrappers",
+    "../../test:fileutils",
+    "../../test:test_support",
+    "../audio_coding:neteq_input_audio_tools",
+    "//testing/gtest",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
diff --git a/modules/audio_processing/aec_dump/BUILD.gn b/modules/audio_processing/aec_dump/BUILD.gn
index 46f0022..7ba3bc0 100644
--- a/modules/audio_processing/aec_dump/BUILD.gn
+++ b/modules/audio_processing/aec_dump/BUILD.gn
@@ -20,31 +20,35 @@
   ]
 }
 
-rtc_library("mock_aec_dump") {
-  testonly = true
-  sources = [
-    "mock_aec_dump.cc",
-    "mock_aec_dump.h",
-  ]
+if (rtc_include_tests) {
+  rtc_library("mock_aec_dump") {
+    testonly = true
+    sources = [
+      "mock_aec_dump.cc",
+      "mock_aec_dump.h",
+    ]
 
-  deps = [
-    "../",
-    "../../../test:test_support",
-  ]
-}
+    deps = [
+      "..:audioproc_test_utils",
+      "../",
+      "../../../test:test_support",
+    ]
+  }
 
-rtc_library("mock_aec_dump_unittests") {
-  testonly = true
-  configs += [ "..:apm_debug_dump" ]
-  sources = [ "aec_dump_integration_test.cc" ]
+  rtc_library("mock_aec_dump_unittests") {
+    testonly = true
+    configs += [ "..:apm_debug_dump" ]
+    sources = [ "aec_dump_integration_test.cc" ]
 
-  deps = [
-    ":mock_aec_dump",
-    "..:api",
-    "../",
-    "../../../rtc_base:rtc_base_approved",
-    "//testing/gtest",
-  ]
+    deps = [
+      ":mock_aec_dump",
+      "..:api",
+      "..:audioproc_test_utils",
+      "../",
+      "../../../rtc_base:rtc_base_approved",
+      "//testing/gtest",
+    ]
+  }
 }
 
 if (rtc_enable_protobuf) {
@@ -75,20 +79,22 @@
     deps += [ "../:audioproc_debug_proto" ]
   }
 
-  rtc_library("aec_dump_unittests") {
-    testonly = true
-    defines = []
-    deps = [
-      ":aec_dump",
-      ":aec_dump_impl",
-      "..:audioproc_debug_proto",
-      "../",
-      "../../../rtc_base:task_queue_for_test",
-      "../../../test:fileutils",
-      "../../../test:test_support",
-      "//testing/gtest",
-    ]
-    sources = [ "aec_dump_unittest.cc" ]
+  if (rtc_include_tests) {
+    rtc_library("aec_dump_unittests") {
+      testonly = true
+      defines = []
+      deps = [
+        ":aec_dump",
+        ":aec_dump_impl",
+        "..:audioproc_debug_proto",
+        "../",
+        "../../../rtc_base:task_queue_for_test",
+        "../../../test:fileutils",
+        "../../../test:test_support",
+        "//testing/gtest",
+      ]
+      sources = [ "aec_dump_unittest.cc" ]
+    }
   }
 }
 
diff --git a/modules/audio_processing/aec_dump/aec_dump_integration_test.cc b/modules/audio_processing/aec_dump/aec_dump_integration_test.cc
index 6d6b466..83268b5 100644
--- a/modules/audio_processing/aec_dump/aec_dump_integration_test.cc
+++ b/modules/audio_processing/aec_dump/aec_dump_integration_test.cc
@@ -15,6 +15,7 @@
 #include "modules/audio_processing/aec_dump/mock_aec_dump.h"
 #include "modules/audio_processing/audio_processing_impl.h"
 #include "modules/audio_processing/include/audio_processing.h"
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 
 using ::testing::_;
 using ::testing::AtLeast;
@@ -25,7 +26,7 @@
 std::unique_ptr<webrtc::AudioProcessing> CreateAudioProcessing() {
   webrtc::Config config;
   std::unique_ptr<webrtc::AudioProcessing> apm(
-      webrtc::AudioProcessingBuilder().Create(config));
+      webrtc::AudioProcessingBuilderForTesting().Create(config));
   RTC_DCHECK(apm);
   return apm;
 }
diff --git a/modules/audio_processing/audio_processing_builder_impl.cc b/modules/audio_processing/audio_processing_builder_impl.cc
new file mode 100644
index 0000000..e89bbec
--- /dev/null
+++ b/modules/audio_processing/audio_processing_builder_impl.cc
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/audio_processing/include/audio_processing.h"
+
+#include <memory>
+
+#include "modules/audio_processing/audio_processing_impl.h"
+#include "rtc_base/ref_counted_object.h"
+
+namespace webrtc {
+
+AudioProcessingBuilder::AudioProcessingBuilder() = default;
+AudioProcessingBuilder::~AudioProcessingBuilder() = default;
+
+AudioProcessing* AudioProcessingBuilder::Create() {
+  webrtc::Config config;
+  return Create(config);
+}
+
+AudioProcessing* AudioProcessingBuilder::Create(const webrtc::Config& config) {
+#ifdef WEBRTC_EXCLUDE_AUDIO_PROCESSING_MODULE
+
+  // Implementation returning a null pointer for using when the APM is excluded
+  // from the build..
+  return nullptr;
+
+#else
+
+  // Standard implementation.
+  AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
+      config, std::move(capture_post_processing_),
+      std::move(render_pre_processing_), std::move(echo_control_factory_),
+      std::move(echo_detector_), std::move(capture_analyzer_));
+  if (apm->Initialize() != AudioProcessing::kNoError) {
+    delete apm;
+    apm = nullptr;
+  }
+  return apm;
+
+#endif
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index 34e6425..bdef059 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -229,56 +229,6 @@
          noise_suppressor_enabled_;
 }
 
-AudioProcessingBuilder::AudioProcessingBuilder() = default;
-AudioProcessingBuilder::~AudioProcessingBuilder() = default;
-
-AudioProcessingBuilder& AudioProcessingBuilder::SetCapturePostProcessing(
-    std::unique_ptr<CustomProcessing> capture_post_processing) {
-  capture_post_processing_ = std::move(capture_post_processing);
-  return *this;
-}
-
-AudioProcessingBuilder& AudioProcessingBuilder::SetRenderPreProcessing(
-    std::unique_ptr<CustomProcessing> render_pre_processing) {
-  render_pre_processing_ = std::move(render_pre_processing);
-  return *this;
-}
-
-AudioProcessingBuilder& AudioProcessingBuilder::SetCaptureAnalyzer(
-    std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
-  capture_analyzer_ = std::move(capture_analyzer);
-  return *this;
-}
-
-AudioProcessingBuilder& AudioProcessingBuilder::SetEchoControlFactory(
-    std::unique_ptr<EchoControlFactory> echo_control_factory) {
-  echo_control_factory_ = std::move(echo_control_factory);
-  return *this;
-}
-
-AudioProcessingBuilder& AudioProcessingBuilder::SetEchoDetector(
-    rtc::scoped_refptr<EchoDetector> echo_detector) {
-  echo_detector_ = std::move(echo_detector);
-  return *this;
-}
-
-AudioProcessing* AudioProcessingBuilder::Create() {
-  webrtc::Config config;
-  return Create(config);
-}
-
-AudioProcessing* AudioProcessingBuilder::Create(const webrtc::Config& config) {
-  AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
-      config, std::move(capture_post_processing_),
-      std::move(render_pre_processing_), std::move(echo_control_factory_),
-      std::move(echo_detector_), std::move(capture_analyzer_));
-  if (apm->Initialize() != AudioProcessing::kNoError) {
-    delete apm;
-    apm = nullptr;
-  }
-  return apm;
-}
-
 AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
     : AudioProcessingImpl(config,
                           /*capture_post_processor=*/nullptr,
diff --git a/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
index f1e049d..5005394 100644
--- a/modules/audio_processing/audio_processing_impl_locking_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
@@ -14,6 +14,7 @@
 
 #include "api/array_view.h"
 #include "modules/audio_processing/audio_processing_impl.h"
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 #include "modules/audio_processing/test/test_utils.h"
 #include "rtc_base/critical_section.h"
 #include "rtc_base/event.h"
@@ -496,7 +497,7 @@
                     this,
                     "stats",
                     rtc::kNormalPriority),
-      apm_(AudioProcessingBuilder().Create()),
+      apm_(AudioProcessingBuilderForTesting().Create()),
       render_thread_state_(kMaxFrameSize,
                            &rand_gen_,
                            &render_call_event_,
diff --git a/modules/audio_processing/audio_processing_impl_unittest.cc b/modules/audio_processing/audio_processing_impl_unittest.cc
index a441e2f..3c5458d 100644
--- a/modules/audio_processing/audio_processing_impl_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_unittest.cc
@@ -15,6 +15,7 @@
 
 #include "api/scoped_refptr.h"
 #include "modules/audio_processing/include/audio_processing.h"
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 #include "modules/audio_processing/test/echo_control_mock.h"
 #include "modules/audio_processing/test/test_utils.h"
 #include "rtc_base/checks.h"
@@ -167,7 +168,8 @@
 }
 
 TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
-  std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
+  std::unique_ptr<AudioProcessing> apm(
+      AudioProcessingBuilderForTesting().Create());
   webrtc::AudioProcessing::Config apm_config;
   apm_config.pre_amplifier.enabled = true;
   apm_config.pre_amplifier.fixed_gain_factor = 1.f;
@@ -205,7 +207,7 @@
   const auto* echo_control_factory_ptr = echo_control_factory.get();
 
   std::unique_ptr<AudioProcessing> apm(
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetEchoControlFactory(std::move(echo_control_factory))
           .Create());
   // Disable AGC.
@@ -248,7 +250,7 @@
   const auto* echo_control_factory_ptr = echo_control_factory.get();
 
   std::unique_ptr<AudioProcessing> apm(
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetEchoControlFactory(std::move(echo_control_factory))
           .Create());
   webrtc::AudioProcessing::Config apm_config;
@@ -294,7 +296,7 @@
   const auto* echo_control_factory_ptr = echo_control_factory.get();
 
   std::unique_ptr<AudioProcessing> apm(
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetEchoControlFactory(std::move(echo_control_factory))
           .Create());
   // Disable AGC.
@@ -353,7 +355,7 @@
       new TestRenderPreProcessor());
   // Create APM injecting the test echo detector and render pre-processor.
   std::unique_ptr<AudioProcessing> apm(
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetEchoDetector(test_echo_detector)
           .SetRenderPreProcessing(std::move(test_render_pre_processor))
           .Create());
diff --git a/modules/audio_processing/audio_processing_performance_unittest.cc b/modules/audio_processing/audio_processing_performance_unittest.cc
index 2ed6f17..206812b 100644
--- a/modules/audio_processing/audio_processing_performance_unittest.cc
+++ b/modules/audio_processing/audio_processing_performance_unittest.cc
@@ -15,6 +15,7 @@
 
 #include "api/array_view.h"
 #include "modules/audio_processing/audio_processing_impl.h"
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 #include "modules/audio_processing/test/test_utils.h"
 #include "rtc_base/atomic_ops.h"
 #include "rtc_base/event.h"
@@ -486,28 +487,28 @@
     int num_capture_channels = 1;
     switch (simulation_config_.simulation_settings) {
       case SettingsType::kDefaultApmMobile: {
-        apm_.reset(AudioProcessingBuilder().Create());
+        apm_.reset(AudioProcessingBuilderForTesting().Create());
         ASSERT_TRUE(!!apm_);
         set_default_mobile_apm_runtime_settings(apm_.get());
         break;
       }
       case SettingsType::kDefaultApmDesktop: {
         Config config;
-        apm_.reset(AudioProcessingBuilder().Create(config));
+        apm_.reset(AudioProcessingBuilderForTesting().Create(config));
         ASSERT_TRUE(!!apm_);
         set_default_desktop_apm_runtime_settings(apm_.get());
         apm_->SetExtraOptions(config);
         break;
       }
       case SettingsType::kAllSubmodulesTurnedOff: {
-        apm_.reset(AudioProcessingBuilder().Create());
+        apm_.reset(AudioProcessingBuilderForTesting().Create());
         ASSERT_TRUE(!!apm_);
         turn_off_default_apm_runtime_settings(apm_.get());
         break;
       }
       case SettingsType::kDefaultApmDesktopWithoutDelayAgnostic: {
         Config config;
-        apm_.reset(AudioProcessingBuilder().Create(config));
+        apm_.reset(AudioProcessingBuilderForTesting().Create(config));
         ASSERT_TRUE(!!apm_);
         set_default_desktop_apm_runtime_settings(apm_.get());
         apm_->SetExtraOptions(config);
@@ -515,7 +516,7 @@
       }
       case SettingsType::kDefaultApmDesktopWithoutExtendedFilter: {
         Config config;
-        apm_.reset(AudioProcessingBuilder().Create(config));
+        apm_.reset(AudioProcessingBuilderForTesting().Create(config));
         ASSERT_TRUE(!!apm_);
         set_default_desktop_apm_runtime_settings(apm_.get());
         apm_->SetExtraOptions(config);
diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc
index cdca7c3..90413a8 100644
--- a/modules/audio_processing/audio_processing_unittest.cc
+++ b/modules/audio_processing/audio_processing_unittest.cc
@@ -28,6 +28,7 @@
 #include "modules/audio_processing/audio_processing_impl.h"
 #include "modules/audio_processing/common.h"
 #include "modules/audio_processing/include/mock_audio_processing.h"
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 #include "modules/audio_processing/test/protobuf_utils.h"
 #include "modules/audio_processing/test/test_utils.h"
 #include "rtc_base/arraysize.h"
@@ -426,7 +427,7 @@
       far_file_(NULL),
       near_file_(NULL),
       out_file_(NULL) {
-  apm_.reset(AudioProcessingBuilder().Create());
+  apm_.reset(AudioProcessingBuilderForTesting().Create());
   AudioProcessing::Config apm_config = apm_->GetConfig();
   apm_config.gain_controller1.analog_gain_controller.enabled = false;
   apm_config.pipeline.maximum_internal_processing_rate = 48000;
@@ -1176,7 +1177,7 @@
   auto src_channels = &src[0];
   auto dest_channels = &dest[0];
 
-  apm_.reset(AudioProcessingBuilder().Create());
+  apm_.reset(AudioProcessingBuilderForTesting().Create());
   EXPECT_NOERR(apm_->ProcessStream(&src_channels, StreamConfig(sample_rate, 1),
                                    StreamConfig(sample_rate, 1),
                                    &dest_channels));
@@ -1637,7 +1638,7 @@
     if (test->num_input_channels() != test->num_output_channels())
       continue;
 
-    apm_.reset(AudioProcessingBuilder().Create());
+    apm_.reset(AudioProcessingBuilderForTesting().Create());
     AudioProcessing::Config apm_config = apm_->GetConfig();
     apm_config.gain_controller1.analog_gain_controller.enabled = false;
     apm_->ApplyConfig(apm_config);
@@ -1806,7 +1807,8 @@
       {AudioProcessing::kStereoAndKeyboard, AudioProcessing::kStereo},
   };
 
-  std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
+  std::unique_ptr<AudioProcessing> ap(
+      AudioProcessingBuilderForTesting().Create());
   // Enable one component just to ensure some processing takes place.
   AudioProcessing::Config config;
   config.noise_suppression.enabled = true;
@@ -1932,7 +1934,8 @@
                             size_t num_reverse_input_channels,
                             size_t num_reverse_output_channels,
                             const std::string& output_file_prefix) {
-    std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
+    std::unique_ptr<AudioProcessing> ap(
+        AudioProcessingBuilderForTesting().Create());
     AudioProcessing::Config apm_config = ap->GetConfig();
     apm_config.gain_controller1.analog_gain_controller.enabled = false;
     ap->ApplyConfig(apm_config);
@@ -2316,7 +2319,8 @@
     rtc::ArrayView<const int> sample_rates_hz,
     rtc::ArrayView<const int> render_channel_counts,
     rtc::ArrayView<const int> capture_channel_counts) {
-  std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
+  std::unique_ptr<AudioProcessing> apm(
+      AudioProcessingBuilderForTesting().Create());
   webrtc::AudioProcessing::Config apm_config;
   apm_config.echo_canceller.enabled = true;
   apm->ApplyConfig(apm_config);
@@ -2455,7 +2459,7 @@
   auto mock_post_processor =
       std::unique_ptr<CustomProcessing>(mock_post_processor_ptr);
   rtc::scoped_refptr<AudioProcessing> apm =
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetCapturePostProcessing(std::move(mock_post_processor))
           .Create();
 
@@ -2477,7 +2481,7 @@
   auto mock_pre_processor =
       std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
   rtc::scoped_refptr<AudioProcessing> apm =
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetRenderPreProcessing(std::move(mock_pre_processor))
           .Create();
 
@@ -2499,7 +2503,7 @@
   auto mock_capture_analyzer =
       std::unique_ptr<CustomAudioAnalyzer>(mock_capture_analyzer_ptr);
   rtc::scoped_refptr<AudioProcessing> apm =
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetCaptureAnalyzer(std::move(mock_capture_analyzer))
           .Create();
 
@@ -2520,7 +2524,7 @@
   auto mock_pre_processor =
       std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
   rtc::scoped_refptr<AudioProcessing> apm =
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetRenderPreProcessing(std::move(mock_pre_processor))
           .Create();
   apm->SetRuntimeSetting(
@@ -2565,7 +2569,7 @@
       new MyEchoControlFactory());
 
   rtc::scoped_refptr<AudioProcessing> apm =
-      AudioProcessingBuilder()
+      AudioProcessingBuilderForTesting()
           .SetEchoControlFactory(std::move(echo_control_factory))
           .Create(webrtc_config);
 
@@ -2589,7 +2593,7 @@
 std::unique_ptr<AudioProcessing> CreateApm(bool mobile_aec) {
   Config old_config;
   std::unique_ptr<AudioProcessing> apm(
-      AudioProcessingBuilder().Create(old_config));
+      AudioProcessingBuilderForTesting().Create(old_config));
   if (!apm) {
     return apm;
   }
@@ -2740,7 +2744,8 @@
     ptr[i] = 10000 * ((i % 3) - 1);
   }
 
-  std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
+  std::unique_ptr<AudioProcessing> apm(
+      AudioProcessingBuilderForTesting().Create());
   apm->Initialize(processing_config);
 
   // If not enabled, no metric should be reported.
@@ -2793,7 +2798,8 @@
     ptr[i] = 10000 * ((i % 3) - 1);
   }
 
-  std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
+  std::unique_ptr<AudioProcessing> apm(
+      AudioProcessingBuilderForTesting().Create());
   apm->Initialize(processing_config);
 
   // If not enabled, no metric should be reported.
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index 7daac86..9c2b09f 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -685,19 +685,34 @@
   ~AudioProcessingBuilder();
   // The AudioProcessingBuilder takes ownership of the echo_control_factory.
   AudioProcessingBuilder& SetEchoControlFactory(
-      std::unique_ptr<EchoControlFactory> echo_control_factory);
+      std::unique_ptr<EchoControlFactory> echo_control_factory) {
+    echo_control_factory_ = std::move(echo_control_factory);
+    return *this;
+  }
   // The AudioProcessingBuilder takes ownership of the capture_post_processing.
   AudioProcessingBuilder& SetCapturePostProcessing(
-      std::unique_ptr<CustomProcessing> capture_post_processing);
+      std::unique_ptr<CustomProcessing> capture_post_processing) {
+    capture_post_processing_ = std::move(capture_post_processing);
+    return *this;
+  }
   // The AudioProcessingBuilder takes ownership of the render_pre_processing.
   AudioProcessingBuilder& SetRenderPreProcessing(
-      std::unique_ptr<CustomProcessing> render_pre_processing);
+      std::unique_ptr<CustomProcessing> render_pre_processing) {
+    render_pre_processing_ = std::move(render_pre_processing);
+    return *this;
+  }
   // The AudioProcessingBuilder takes ownership of the echo_detector.
   AudioProcessingBuilder& SetEchoDetector(
-      rtc::scoped_refptr<EchoDetector> echo_detector);
+      rtc::scoped_refptr<EchoDetector> echo_detector) {
+    echo_detector_ = std::move(echo_detector);
+    return *this;
+  }
   // The AudioProcessingBuilder takes ownership of the capture_analyzer.
   AudioProcessingBuilder& SetCaptureAnalyzer(
-      std::unique_ptr<CustomAudioAnalyzer> capture_analyzer);
+      std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
+    capture_analyzer_ = std::move(capture_analyzer);
+    return *this;
+  }
   // This creates an APM instance using the previously set components. Calling
   // the Create function resets the AudioProcessingBuilder to its initial state.
   AudioProcessing* Create();
diff --git a/modules/audio_processing/test/audio_processing_builder_for_testing.cc b/modules/audio_processing/test/audio_processing_builder_for_testing.cc
new file mode 100644
index 0000000..26ed679
--- /dev/null
+++ b/modules/audio_processing/test/audio_processing_builder_for_testing.cc
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
+
+#include <memory>
+#include <utility>
+
+#include "modules/audio_processing/audio_processing_impl.h"
+#include "rtc_base/ref_counted_object.h"
+
+namespace webrtc {
+
+AudioProcessingBuilderForTesting::AudioProcessingBuilderForTesting() = default;
+AudioProcessingBuilderForTesting::~AudioProcessingBuilderForTesting() = default;
+
+#ifdef WEBRTC_EXCLUDE_AUDIO_PROCESSING_MODULE
+
+AudioProcessing* AudioProcessingBuilderForTesting::Create() {
+  webrtc::Config config;
+  return Create(config);
+}
+
+AudioProcessing* AudioProcessingBuilderForTesting::Create(
+    const webrtc::Config& config) {
+  AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
+      config, std::move(capture_post_processing_),
+      std::move(render_pre_processing_), std::move(echo_control_factory_),
+      std::move(echo_detector_), std::move(capture_analyzer_));
+  int error = apm->Initialize();
+  RTC_CHECK_EQ(error, AudioProcessing::kNoError);
+  return apm;
+}
+
+#else
+
+AudioProcessing* AudioProcessingBuilderForTesting::Create() {
+  AudioProcessingBuilder builder;
+  TransferOwnershipsToBuilder(&builder);
+  return builder.Create();
+}
+
+AudioProcessing* AudioProcessingBuilderForTesting::Create(
+    const webrtc::Config& config) {
+  AudioProcessingBuilder builder;
+  TransferOwnershipsToBuilder(&builder);
+  return builder.Create(config);
+}
+
+#endif
+
+void AudioProcessingBuilderForTesting::TransferOwnershipsToBuilder(
+    AudioProcessingBuilder* builder) {
+  builder->SetCapturePostProcessing(std::move(capture_post_processing_));
+  builder->SetRenderPreProcessing(std::move(render_pre_processing_));
+  builder->SetCaptureAnalyzer(std::move(capture_analyzer_));
+  builder->SetEchoControlFactory(std::move(echo_control_factory_));
+  builder->SetEchoDetector(std::move(echo_detector_));
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_processing/test/audio_processing_builder_for_testing.h b/modules/audio_processing/test/audio_processing_builder_for_testing.h
new file mode 100644
index 0000000..a245450
--- /dev/null
+++ b/modules/audio_processing/test/audio_processing_builder_for_testing.h
@@ -0,0 +1,81 @@
+/*
+ *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_BUILDER_FOR_TESTING_H_
+#define MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_BUILDER_FOR_TESTING_H_
+
+#include <list>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "modules/audio_processing/include/audio_processing.h"
+
+namespace webrtc {
+
+// Facilitates building of AudioProcessingImp for the tests.
+class AudioProcessingBuilderForTesting {
+ public:
+  AudioProcessingBuilderForTesting();
+  ~AudioProcessingBuilderForTesting();
+  // The AudioProcessingBuilderForTesting takes ownership of the
+  // echo_control_factory.
+  AudioProcessingBuilderForTesting& SetEchoControlFactory(
+      std::unique_ptr<EchoControlFactory> echo_control_factory) {
+    echo_control_factory_ = std::move(echo_control_factory);
+    return *this;
+  }
+  // The AudioProcessingBuilderForTesting takes ownership of the
+  // capture_post_processing.
+  AudioProcessingBuilderForTesting& SetCapturePostProcessing(
+      std::unique_ptr<CustomProcessing> capture_post_processing) {
+    capture_post_processing_ = std::move(capture_post_processing);
+    return *this;
+  }
+  // The AudioProcessingBuilderForTesting takes ownership of the
+  // render_pre_processing.
+  AudioProcessingBuilderForTesting& SetRenderPreProcessing(
+      std::unique_ptr<CustomProcessing> render_pre_processing) {
+    render_pre_processing_ = std::move(render_pre_processing);
+    return *this;
+  }
+  // The AudioProcessingBuilderForTesting takes ownership of the echo_detector.
+  AudioProcessingBuilderForTesting& SetEchoDetector(
+      rtc::scoped_refptr<EchoDetector> echo_detector) {
+    echo_detector_ = std::move(echo_detector);
+    return *this;
+  }
+  // The AudioProcessingBuilderForTesting takes ownership of the
+  // capture_analyzer.
+  AudioProcessingBuilderForTesting& SetCaptureAnalyzer(
+      std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
+    capture_analyzer_ = std::move(capture_analyzer);
+    return *this;
+  }
+  // This creates an APM instance using the previously set components. Calling
+  // the Create function resets the AudioProcessingBuilderForTesting to its
+  // initial state.
+  AudioProcessing* Create();
+  AudioProcessing* Create(const webrtc::Config& config);
+
+ private:
+  // Transfers the ownership to a non-testing builder.
+  void TransferOwnershipsToBuilder(AudioProcessingBuilder* builder);
+
+  std::unique_ptr<EchoControlFactory> echo_control_factory_;
+  std::unique_ptr<CustomProcessing> capture_post_processing_;
+  std::unique_ptr<CustomProcessing> render_pre_processing_;
+  rtc::scoped_refptr<EchoDetector> echo_detector_;
+  std::unique_ptr<CustomAudioAnalyzer> capture_analyzer_;
+};
+
+}  // namespace webrtc
+
+#endif  // MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_BUILDER_FOR_TESTING_H_
diff --git a/modules/audio_processing/test/debug_dump_replayer.cc b/modules/audio_processing/test/debug_dump_replayer.cc
index 26ca429..b8cccd1 100644
--- a/modules/audio_processing/test/debug_dump_replayer.cc
+++ b/modules/audio_processing/test/debug_dump_replayer.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_processing/test/debug_dump_replayer.h"
 
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 #include "modules/audio_processing/test/protobuf_utils.h"
 #include "modules/audio_processing/test/runtime_setting_util.h"
 #include "rtc_base/checks.h"
@@ -185,7 +186,7 @@
   // We only create APM once, since changes on these fields should not
   // happen in current implementation.
   if (!apm_.get()) {
-    apm_.reset(AudioProcessingBuilder().Create(config));
+    apm_.reset(AudioProcessingBuilderForTesting().Create(config));
   }
 }
 
diff --git a/modules/audio_processing/test/debug_dump_test.cc b/modules/audio_processing/test/debug_dump_test.cc
index 71478a9..2381d1e 100644
--- a/modules/audio_processing/test/debug_dump_test.cc
+++ b/modules/audio_processing/test/debug_dump_test.cc
@@ -17,6 +17,7 @@
 #include "api/audio/echo_canceller3_factory.h"
 #include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
 #include "modules/audio_processing/aec_dump/aec_dump_factory.h"
+#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
 #include "modules/audio_processing/test/debug_dump_replayer.h"
 #include "modules/audio_processing/test/test_utils.h"
 #include "rtc_base/task_queue_for_test.h"
@@ -141,7 +142,7 @@
       enable_pre_amplifier_(enable_pre_amplifier),
       worker_queue_("debug_dump_generator_worker_queue"),
       dump_file_name_(dump_file_name) {
-  AudioProcessingBuilder apm_builder;
+  AudioProcessingBuilderForTesting apm_builder;
   apm_.reset(apm_builder.Create(config));
 }