Added test dependency factory.

Bug: b/113654555
Change-Id: I6879d0e7dcbfbb04ad7a5179c4f4fbe8d31cf3d4
Reviewed-on: https://webrtc-review.googlesource.com/101601
Commit-Queue: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24855}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index a267894..007879b 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -139,6 +139,7 @@
     "test/video_quality_test_fixture.h",
   ]
   deps = [
+    ":fec_controller_api",
     ":libjingle_peerconnection_api",
     ":simulated_network_api",
     "../call:fake_network",
@@ -153,6 +154,23 @@
   }
 }
 
+rtc_source_set("test_dependency_factory") {
+  visibility = [ "*" ]
+  testonly = true
+  sources = [
+    "test/test_dependency_factory.cc",
+    "test/test_dependency_factory.h",
+  ]
+  deps = [
+    ":video_quality_test_fixture_api",
+    "../rtc_base:thread_checker",
+  ]
+  if (!build_with_chromium && is_clang) {
+    # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
+    suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
+  }
+}
+
 if (rtc_include_tests) {
   rtc_source_set("create_video_quality_test_fixture_api") {
     visibility = [ "*" ]
diff --git a/api/test/test_dependency_factory.cc b/api/test/test_dependency_factory.cc
new file mode 100644
index 0000000..3e59bc0
--- /dev/null
+++ b/api/test/test_dependency_factory.cc
@@ -0,0 +1,50 @@
+/*
+ *  Copyright (c) 2018 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 <memory>
+#include <utility>
+
+#include "api/test/test_dependency_factory.h"
+#include "rtc_base/thread_checker.h"
+
+namespace webrtc {
+
+// This checks everything in this file gets called on the same thread. It's
+// static because it needs to look at the static methods too.
+rtc::ThreadChecker* GetThreadChecker() {
+  static rtc::ThreadChecker checker;
+  return &checker;
+}
+
+std::unique_ptr<TestDependencyFactory> TestDependencyFactory::instance_ =
+    nullptr;
+
+const TestDependencyFactory& TestDependencyFactory::GetInstance() {
+  RTC_DCHECK(GetThreadChecker()->CalledOnValidThread());
+  if (instance_ == nullptr) {
+    instance_ = absl::make_unique<TestDependencyFactory>();
+  }
+  return *instance_;
+}
+
+void TestDependencyFactory::SetInstance(
+    std::unique_ptr<TestDependencyFactory> instance) {
+  RTC_DCHECK(GetThreadChecker()->CalledOnValidThread());
+  RTC_CHECK(instance_ == nullptr);
+  instance_ = std::move(instance);
+}
+
+std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
+TestDependencyFactory::CreateComponents() const {
+  RTC_DCHECK(GetThreadChecker()->CalledOnValidThread());
+  return nullptr;
+}
+
+}  // namespace webrtc
diff --git a/api/test/test_dependency_factory.h b/api/test/test_dependency_factory.h
new file mode 100644
index 0000000..ac2dd70
--- /dev/null
+++ b/api/test/test_dependency_factory.h
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2018 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 API_TEST_TEST_DEPENDENCY_FACTORY_H_
+#define API_TEST_TEST_DEPENDENCY_FACTORY_H_
+
+#include <memory>
+
+#include "api/test/video_quality_test_fixture.h"
+#include "rtc_base/thread_checker.h"
+
+namespace webrtc {
+
+// Override this class if to inject custom components into WebRTC tests.
+// Not all WebRTC tests get their components from here, so you need to make
+// sure the tests you want actually use this class.
+//
+// This class is not thread safe and you need to make call calls from the same
+// (test main) thread.
+class TestDependencyFactory {
+ public:
+  virtual ~TestDependencyFactory() = default;
+
+  // The singleton MUST be stateless since tests execute in any order. It must
+  // be set before tests start executing.
+  static const TestDependencyFactory& GetInstance();
+  static void SetInstance(std::unique_ptr<TestDependencyFactory> instance);
+
+  // Returns the component a test should use. Returning nullptr means that the
+  // test is free to use whatever defaults it wants. The injection components
+  // themselves can be mutable, but we need to make new ones for every test that
+  // executes so state doesn't spread between tests.
+  virtual std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
+  CreateComponents() const;
+
+ private:
+  static std::unique_ptr<TestDependencyFactory> instance_;
+};
+
+}  // namespace webrtc
+
+#endif  // API_TEST_TEST_DEPENDENCY_FACTORY_H_
diff --git a/api/test/video_quality_test_fixture.h b/api/test/video_quality_test_fixture.h
index 99451f9..5ec7713 100644
--- a/api/test/video_quality_test_fixture.h
+++ b/api/test/video_quality_test_fixture.h
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include "api/bitrate_constraints.h"
+#include "api/fec_controller.h"
 #include "api/mediatypes.h"
 #include "api/test/simulated_network.h"
 #include "api/video_codecs/video_encoder_config.h"
diff --git a/video/BUILD.gn b/video/BUILD.gn
index a01f6ec..cecdd38 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -207,6 +207,7 @@
     ]
     deps = [
       "../api:fec_controller_api",
+      "../api:test_dependency_factory",
       "../api:video_quality_test_fixture_api",
       "../call:fake_network",
       "../call:simulated_network",
@@ -252,6 +253,7 @@
     ]
     deps = [
       ":video_quality_test",
+      "../api:test_dependency_factory",
       "../media:rtc_vp9_profile",
       "../modules/pacing:pacing",
       "../modules/video_coding:webrtc_vp9",
diff --git a/video/full_stack_tests.cc b/video/full_stack_tests.cc
index 3262512..382440f 100644
--- a/video/full_stack_tests.cc
+++ b/video/full_stack_tests.cc
@@ -9,6 +9,7 @@
  */
 #include <stdio.h>
 
+#include "api/test/test_dependency_factory.h"
 #include "media/base/vp9_profile.h"
 #include "modules/video_coding/codecs/vp9/include/vp9.h"
 #include "rtc_base/experiments/alr_experiment.h"
@@ -63,7 +64,10 @@
 
 std::unique_ptr<VideoQualityTestFixtureInterface>
 CreateVideoQualityTestFixture() {
-  return absl::make_unique<VideoQualityTest>(nullptr);
+  // The components will normally be nullptr (= use defaults), but it's possible
+  // for external test runners to override the list of injected components.
+  auto components = TestDependencyFactory::GetInstance().CreateComponents();
+  return absl::make_unique<VideoQualityTest>(std::move(components));
 }
 
 // Takes the current active field trials set, and appends some new trials.