Adds WebRtcKeyValueConfig interface

The WebRtcKeyValueConfig interface allows providing custom key value
configurations that changes per instance of GoogCcNetworkController.

Bug: webrtc:10009
Change-Id: I520fff030d1c3c755455ec8f67896fe8a6b4d970
Reviewed-on: https://webrtc-review.googlesource.com/c/116989
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26312}
diff --git a/api/transport/BUILD.gn b/api/transport/BUILD.gn
index aeb563e..683e1bc 100644
--- a/api/transport/BUILD.gn
+++ b/api/transport/BUILD.gn
@@ -35,6 +35,7 @@
   ]
 
   deps = [
+    ":webrtc_key_value_config",
     "../units:data_rate",
     "../units:data_size",
     "../units:time_delta",
@@ -43,6 +44,29 @@
   ]
 }
 
+rtc_source_set("webrtc_key_value_config") {
+  visibility = [ "*" ]
+  sources = [
+    "webrtc_key_value_config.h",
+  ]
+  deps = [
+    "//third_party/abseil-cpp/absl/strings",
+  ]
+}
+
+rtc_source_set("field_trial_based_config") {
+  visibility = [ "*" ]
+  sources = [
+    "field_trial_based_config.cc",
+    "field_trial_based_config.h",
+  ]
+  deps = [
+    ":webrtc_key_value_config",
+    "../../system_wrappers:field_trial",
+    "//third_party/abseil-cpp/absl/strings",
+  ]
+}
+
 rtc_static_library("goog_cc") {
   visibility = [ "*" ]
   sources = [
@@ -51,6 +75,7 @@
   ]
   deps = [
     ":network_control",
+    ":webrtc_key_value_config",
     "../../modules/congestion_controller/goog_cc",
     "//third_party/abseil-cpp/absl/memory",
   ]
diff --git a/api/transport/field_trial_based_config.cc b/api/transport/field_trial_based_config.cc
new file mode 100644
index 0000000..7e6764f
--- /dev/null
+++ b/api/transport/field_trial_based_config.cc
@@ -0,0 +1,17 @@
+/*
+ *  Copyright 2019 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 "api/transport/field_trial_based_config.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+std::string FieldTrialBasedConfig::Lookup(absl::string_view key) const {
+  return webrtc::field_trial::FindFullName(std::string(key));
+}
+}  // namespace webrtc
diff --git a/api/transport/field_trial_based_config.h b/api/transport/field_trial_based_config.h
new file mode 100644
index 0000000..e0989db
--- /dev/null
+++ b/api/transport/field_trial_based_config.h
@@ -0,0 +1,25 @@
+/*
+ *  Copyright 2019 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_TRANSPORT_FIELD_TRIAL_BASED_CONFIG_H_
+#define API_TRANSPORT_FIELD_TRIAL_BASED_CONFIG_H_
+
+#include <string>
+#include "absl/strings/string_view.h"
+#include "api/transport/webrtc_key_value_config.h"
+
+namespace webrtc {
+// Implementation using the field trial API fo the key value lookup.
+class FieldTrialBasedConfig : public WebRtcKeyValueConfig {
+ public:
+  std::string Lookup(absl::string_view key) const override;
+};
+}  // namespace webrtc
+
+#endif  // API_TRANSPORT_FIELD_TRIAL_BASED_CONFIG_H_
diff --git a/api/transport/network_control.h b/api/transport/network_control.h
index e68e209..53ac10e 100644
--- a/api/transport/network_control.h
+++ b/api/transport/network_control.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/transport/network_types.h"
+#include "api/transport/webrtc_key_value_config.h"
 
 namespace webrtc {
 
@@ -39,6 +40,10 @@
   // Initial stream specific configuration, these are changed at any later time
   // by calls to OnStreamsConfig.
   StreamsConfig stream_based_config;
+
+  // Optional override of configuration of WebRTC internals. Using nullptr here
+  // indicates that the field trial API will be used.
+  const WebRtcKeyValueConfig* key_value_config = nullptr;
 };
 
 // NetworkControllerInterface is implemented by network controllers. A network
diff --git a/api/transport/webrtc_key_value_config.h b/api/transport/webrtc_key_value_config.h
new file mode 100644
index 0000000..c6376a9
--- /dev/null
+++ b/api/transport/webrtc_key_value_config.h
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 2019 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_TRANSPORT_WEBRTC_KEY_VALUE_CONFIG_H_
+#define API_TRANSPORT_WEBRTC_KEY_VALUE_CONFIG_H_
+
+#include <string>
+#include "absl/strings/string_view.h"
+
+namespace webrtc {
+
+// An interface that provides a key-value mapping for configuring internal
+// details of WebRTC. Note that there's no guarantess that the meaning of a
+// particular key value mapping will be preserved over time and no announcements
+// will be made if they are changed. It's up to the library user to ensure that
+// the behavior does not break.
+class WebRtcKeyValueConfig {
+ public:
+  virtual ~WebRtcKeyValueConfig() = default;
+  // The configured value for the given key. Defaults to an empty string.
+  virtual std::string Lookup(absl::string_view key) const = 0;
+};
+}  // namespace webrtc
+
+#endif  // API_TRANSPORT_WEBRTC_KEY_VALUE_CONFIG_H_
diff --git a/modules/congestion_controller/BUILD.gn b/modules/congestion_controller/BUILD.gn
index 4cbe732..06b8669 100644
--- a/modules/congestion_controller/BUILD.gn
+++ b/modules/congestion_controller/BUILD.gn
@@ -37,7 +37,9 @@
     ":transport_feedback",
     "..:module_api",
     "../..:webrtc_common",
+    "../../api/transport:field_trial_based_config",
     "../../api/transport:network_control",
+    "../../api/transport:webrtc_key_value_config",
     "../../api/units:data_rate",
     "../../api/units:timestamp",
     "../../rtc_base:checks",
diff --git a/modules/congestion_controller/goog_cc/BUILD.gn b/modules/congestion_controller/goog_cc/BUILD.gn
index 039ea9a..9de1815 100644
--- a/modules/congestion_controller/goog_cc/BUILD.gn
+++ b/modules/congestion_controller/goog_cc/BUILD.gn
@@ -32,7 +32,9 @@
     ":pushback_controller",
     "../..:module_api",
     "../../..:webrtc_common",
+    "../../../api/transport:field_trial_based_config",
     "../../../api/transport:network_control",
+    "../../../api/transport:webrtc_key_value_config",
     "../../../api/units:data_rate",
     "../../../api/units:data_size",
     "../../../api/units:time_delta",
@@ -44,7 +46,6 @@
     "../../../rtc_base/experiments:alr_experiment",
     "../../../rtc_base/experiments:field_trial_parser",
     "../../../system_wrappers",
-    "../../../system_wrappers:field_trial",
     "../../bitrate_controller",
     "../../remote_bitrate_estimator",
     "../../rtp_rtcp:rtp_rtcp_format",
@@ -72,10 +73,10 @@
   ]
   deps = [
     "../../../api/transport:network_control",
+    "../../../api/transport:webrtc_key_value_config",
     "../../../api/units:data_size",
     "../../../rtc_base:checks",
     "../../../rtc_base:rtc_base_approved",
-    "../../../system_wrappers:field_trial",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
@@ -87,12 +88,12 @@
   ]
   deps = [
     "../../..:webrtc_common",
+    "../../../api/transport:webrtc_key_value_config",
     "../../../logging:rtc_event_log_api",
     "../../../logging:rtc_event_pacing",
     "../../../rtc_base:checks",
     "../../../rtc_base:rtc_base_approved",
     "../../../rtc_base/experiments:alr_experiment",
-    "../../../system_wrappers:field_trial",
     "../../pacing:interval_budget",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/types:optional",
@@ -115,6 +116,7 @@
   ]
 
   deps = [
+    "../../../api/transport:webrtc_key_value_config",
     "../../../api/units:data_rate",
     "../../../logging:rtc_event_bwe",
     "../../../logging:rtc_event_log_api",
@@ -123,7 +125,6 @@
     "../../../rtc_base:rtc_numerics",
     "../../../rtc_base:safe_minmax",
     "../../../rtc_base/experiments:field_trial_parser",
-    "../../../system_wrappers:field_trial",
     "../../remote_bitrate_estimator",
     "../../rtp_rtcp:rtp_rtcp_format",
     "//third_party/abseil-cpp/absl/memory",
@@ -143,12 +144,12 @@
     ":estimators",
     ":link_capacity_estimator",
     "../../../api/transport:network_control",
+    "../../../api/transport:webrtc_key_value_config",
     "../../../logging:rtc_event_bwe",
     "../../../logging:rtc_event_log_api",
     "../../../rtc_base:checks",
     "../../../rtc_base:rtc_base_approved",
     "../../../rtc_base/experiments:field_trial_parser",
-    "../../../system_wrappers:field_trial",
     "../../../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/types:optional",
@@ -165,12 +166,12 @@
   deps = [
     ":estimators",
     "../../../api/transport:network_control",
+    "../../../api/transport:webrtc_key_value_config",
     "../../../logging:rtc_event_bwe",
     "../../../logging:rtc_event_log_api",
     "../../../rtc_base:checks",
     "../../../rtc_base:rtc_base_approved",
     "../../../rtc_base/experiments:field_trial_parser",
-    "../../../system_wrappers:field_trial",
     "../../../system_wrappers:metrics",
     "../../pacing",
     "../../remote_bitrate_estimator",
@@ -188,6 +189,7 @@
 
   deps = [
     "../../../api/transport:network_control",
+    "../../../api/transport:webrtc_key_value_config",
     "../../../api/units:data_rate",
     "../../../api/units:time_delta",
     "../../../api/units:timestamp",
@@ -196,7 +198,6 @@
     "../../../rtc_base:checks",
     "../../../rtc_base:rtc_base_approved",
     "../../../rtc_base/system:unused",
-    "../../../system_wrappers:field_trial",
     "../../../system_wrappers:metrics",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
@@ -250,9 +251,11 @@
       ":goog_cc",
       ":probe_controller",
       ":pushback_controller",
+      "../../../api/transport:field_trial_based_config",
       "../../../api/transport:goog_cc",
       "../../../api/transport:network_control",
       "../../../api/transport:network_control_test",
+      "../../../api/transport:webrtc_key_value_config",
       "../../../api/units:data_rate",
       "../../../api/units:timestamp",
       "../../../logging:mocks",
@@ -261,7 +264,6 @@
       "../../../rtc_base:rtc_base_tests_utils",
       "../../../rtc_base/experiments:alr_experiment",
       "../../../system_wrappers",
-      "../../../system_wrappers:field_trial",
       "../../../test:field_trial",
       "../../../test:test_support",
       "../../../test/scenario",
@@ -291,12 +293,12 @@
       "../../../api/transport:goog_cc",
       "../../../api/transport:network_control",
       "../../../api/transport:network_control_test",
+      "../../../api/transport:webrtc_key_value_config",
       "../../../logging:mocks",
       "../../../rtc_base:checks",
       "../../../rtc_base:rtc_base_approved",
       "../../../rtc_base/experiments:alr_experiment",
       "../../../system_wrappers",
-      "../../../system_wrappers:field_trial",
       "../../../test:field_trial",
       "../../../test:test_support",
       "../../../test/scenario",
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc
index 939da4c..37be68d 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.cc
@@ -18,7 +18,6 @@
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
@@ -28,15 +27,20 @@
 }
 }  // namespace
 
-AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator()
-    : AcknowledgedBitrateEstimator(absl::make_unique<BitrateEstimator>()) {}
+AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator(
+    const WebRtcKeyValueConfig* key_value_config)
+    : AcknowledgedBitrateEstimator(
+          key_value_config,
+          absl::make_unique<BitrateEstimator>(key_value_config)) {}
 
 AcknowledgedBitrateEstimator::~AcknowledgedBitrateEstimator() {}
 
 AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator(
+    const WebRtcKeyValueConfig* key_value_config,
     std::unique_ptr<BitrateEstimator> bitrate_estimator)
     : account_for_unacknowledged_traffic_(
-          field_trial::IsEnabled("WebRTC-Bwe-AccountForUnacked")),
+          key_value_config->Lookup("WebRTC-Bwe-AccountForUnacked")
+              .find("Enabled") == 0),
       bitrate_estimator_(std::move(bitrate_estimator)) {}
 
 void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector(
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h
index 645c0b9..48f8057 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h
@@ -15,9 +15,9 @@
 #include <vector>
 
 #include "absl/types/optional.h"
-#include "modules/congestion_controller/goog_cc/bitrate_estimator.h"
-
+#include "api/transport/webrtc_key_value_config.h"
 #include "api/units/data_rate.h"
+#include "modules/congestion_controller/goog_cc/bitrate_estimator.h"
 
 namespace webrtc {
 
@@ -25,10 +25,12 @@
 
 class AcknowledgedBitrateEstimator {
  public:
-  explicit AcknowledgedBitrateEstimator(
+  AcknowledgedBitrateEstimator(
+      const WebRtcKeyValueConfig* key_value_config,
       std::unique_ptr<BitrateEstimator> bitrate_estimator);
 
-  AcknowledgedBitrateEstimator();
+  explicit AcknowledgedBitrateEstimator(
+      const WebRtcKeyValueConfig* key_value_config);
   ~AcknowledgedBitrateEstimator();
 
   void IncomingPacketFeedbackVector(
diff --git a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc
index cfb7618..3061730 100644
--- a/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc
+++ b/modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator_unittest.cc
@@ -13,6 +13,7 @@
 #include <utility>
 
 #include "absl/memory/memory.h"
+#include "api/transport/field_trial_based_config.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "rtc_base/fake_clock.h"
 #include "test/gmock.h"
@@ -34,23 +35,26 @@
 
 class MockBitrateEstimator : public BitrateEstimator {
  public:
+  using BitrateEstimator::BitrateEstimator;
   MOCK_METHOD2(Update, void(int64_t now_ms, int bytes));
   MOCK_CONST_METHOD0(bitrate_bps, absl::optional<uint32_t>());
   MOCK_METHOD0(ExpectFastRateChange, void());
 };
 
 struct AcknowledgedBitrateEstimatorTestStates {
+  FieldTrialBasedConfig field_trial_config;
   std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator;
   MockBitrateEstimator* mock_bitrate_estimator;
 };
 
 AcknowledgedBitrateEstimatorTestStates CreateTestStates() {
   AcknowledgedBitrateEstimatorTestStates states;
-  auto mock_bitrate_estimator = absl::make_unique<MockBitrateEstimator>();
+  auto mock_bitrate_estimator =
+      absl::make_unique<MockBitrateEstimator>(&states.field_trial_config);
   states.mock_bitrate_estimator = mock_bitrate_estimator.get();
   states.acknowledged_bitrate_estimator =
       absl::make_unique<AcknowledgedBitrateEstimator>(
-          std::move(mock_bitrate_estimator));
+          &states.field_trial_config, std::move(mock_bitrate_estimator));
   return states;
 }
 
diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.cc b/modules/congestion_controller/goog_cc/bitrate_estimator.cc
index 0a40392..b30ed42 100644
--- a/modules/congestion_controller/goog_cc/bitrate_estimator.cc
+++ b/modules/congestion_controller/goog_cc/bitrate_estimator.cc
@@ -16,7 +16,6 @@
 
 #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
@@ -27,9 +26,10 @@
 const char kBweInitialThroughputWindowExperiment[] =
     "WebRTC-BweInitialThroughputWindowExperiment";
 
-int ReadInitialThroughputWindowSizeMs() {
+int ReadInitialThroughputWindowSizeMs(
+    const WebRtcKeyValueConfig* key_value_config) {
   std::string experiment_string =
-      webrtc::field_trial::FindFullName(kBweInitialThroughputWindowExperiment);
+      key_value_config->Lookup(kBweInitialThroughputWindowExperiment);
   int initial_window_ms = kInitialRateWindowMs;
   int parsed_values =
       sscanf(experiment_string.c_str(), "Enabled-%d", &initial_window_ms);
@@ -51,15 +51,16 @@
 
 }  // namespace
 
-BitrateEstimator::BitrateEstimator()
+BitrateEstimator::BitrateEstimator(const WebRtcKeyValueConfig* key_value_config)
     : sum_(0),
       initial_window_ms_(kInitialRateWindowMs),
       current_window_ms_(0),
       prev_time_ms_(-1),
       bitrate_estimate_(-1.0f),
       bitrate_estimate_var_(50.0f) {
-  if (field_trial::IsEnabled(kBweInitialThroughputWindowExperiment)) {
-    initial_window_ms_ = ReadInitialThroughputWindowSizeMs();
+  if (key_value_config->Lookup(kBweInitialThroughputWindowExperiment)
+          .find("Enabled") == 0) {
+    initial_window_ms_ = ReadInitialThroughputWindowSizeMs(key_value_config);
   }
 }
 
diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.h b/modules/congestion_controller/goog_cc/bitrate_estimator.h
index d3df2b5..b921492 100644
--- a/modules/congestion_controller/goog_cc/bitrate_estimator.h
+++ b/modules/congestion_controller/goog_cc/bitrate_estimator.h
@@ -14,6 +14,7 @@
 #include <stdint.h>
 
 #include "absl/types/optional.h"
+#include "api/transport/webrtc_key_value_config.h"
 
 namespace webrtc {
 
@@ -24,7 +25,7 @@
 // unrelated to congestion.
 class BitrateEstimator {
  public:
-  BitrateEstimator();
+  explicit BitrateEstimator(const WebRtcKeyValueConfig* key_value_config);
   virtual ~BitrateEstimator();
   virtual void Update(int64_t now_ms, int bytes);
 
diff --git a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.cc b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.cc
index 7c681be..7d83b8c 100644
--- a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.cc
+++ b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.cc
@@ -15,7 +15,6 @@
 
 #include "modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h"
 #include "rtc_base/checks.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
@@ -29,10 +28,11 @@
 const uint32_t kDefaultMinPushbackTargetBitrateBps = 30000;
 
 bool ReadCongestionWindowPushbackExperimentParameter(
+    const WebRtcKeyValueConfig* key_value_config,
     uint32_t* min_pushback_target_bitrate_bps) {
   RTC_DCHECK(min_pushback_target_bitrate_bps);
   std::string experiment_string =
-      webrtc::field_trial::FindFullName(kCongestionPushbackExperiment);
+      key_value_config->Lookup(kCongestionPushbackExperiment);
   int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%" PRIu32,
                              min_pushback_target_bitrate_bps);
   if (parsed_values == 1) {
@@ -45,19 +45,23 @@
 
 }  // namespace
 
-CongestionWindowPushbackController::CongestionWindowPushbackController()
-    : add_pacing_(field_trial::IsEnabled(
-          "WebRTC-AddPacingToCongestionWindowPushback")) {
+CongestionWindowPushbackController::CongestionWindowPushbackController(
+    const WebRtcKeyValueConfig* key_value_config)
+    : add_pacing_(
+          key_value_config->Lookup("WebRTC-AddPacingToCongestionWindowPushback")
+              .find("Enabled") == 0) {
   if (!ReadCongestionWindowPushbackExperimentParameter(
-          &min_pushback_target_bitrate_bps_)) {
+          key_value_config, &min_pushback_target_bitrate_bps_)) {
     min_pushback_target_bitrate_bps_ = kDefaultMinPushbackTargetBitrateBps;
   }
 }
 
 CongestionWindowPushbackController::CongestionWindowPushbackController(
+    const WebRtcKeyValueConfig* key_value_config,
     uint32_t min_pushback_target_bitrate_bps)
     : add_pacing_(
-          field_trial::IsEnabled("WebRTC-AddPacingToCongestionWindowPushback")),
+          key_value_config->Lookup("WebRTC-AddPacingToCongestionWindowPushback")
+              .find("Enabled") == 0),
       min_pushback_target_bitrate_bps_(min_pushback_target_bitrate_bps) {}
 
 void CongestionWindowPushbackController::UpdateOutstandingData(
diff --git a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h
index c6b1023..9b64093 100644
--- a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h
+++ b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h
@@ -15,6 +15,7 @@
 #include <stdint.h>
 
 #include "absl/types/optional.h"
+#include "api/transport/webrtc_key_value_config.h"
 #include "api/units/data_size.h"
 
 namespace webrtc {
@@ -26,8 +27,10 @@
 // used to prevent video pause due to a full congestion window.
 class CongestionWindowPushbackController {
  public:
-  CongestionWindowPushbackController();
   explicit CongestionWindowPushbackController(
+      const WebRtcKeyValueConfig* key_value_config);
+  CongestionWindowPushbackController(
+      const WebRtcKeyValueConfig* key_value_config,
       uint32_t min_pushback_target_bitrate_bps);
   void UpdateOutstandingData(int64_t outstanding_bytes);
   void UpdatePacingQueue(int64_t pacing_bytes);
diff --git a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc
index 30617ee..9be5b21 100644
--- a/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc
+++ b/modules/congestion_controller/goog_cc/congestion_window_pushback_controller_unittest.cc
@@ -9,6 +9,7 @@
  */
 
 #include "modules/congestion_controller/goog_cc/congestion_window_pushback_controller.h"
+#include "api/transport/field_trial_based_config.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
@@ -18,7 +19,13 @@
 namespace test {
 
 class CongestionWindowPushbackControllerTest : public ::testing::Test {
+ public:
+  CongestionWindowPushbackControllerTest()
+      : cwnd_controller_(&field_trial_based_config_) {}
+
  protected:
+  FieldTrialBasedConfig field_trial_based_config_;
+
   CongestionWindowPushbackController cwnd_controller_;
 };
 
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
index 3c780dd..f287581 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
@@ -24,7 +24,6 @@
 #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
 #include "system_wrappers/include/metrics.h"
 
 namespace webrtc {
@@ -49,9 +48,10 @@
 const char kBweWindowSizeInPacketsExperiment[] =
     "WebRTC-BweWindowSizeInPackets";
 
-size_t ReadTrendlineFilterWindowSize() {
+size_t ReadTrendlineFilterWindowSize(
+    const WebRtcKeyValueConfig* key_value_config) {
   std::string experiment_string =
-      webrtc::field_trial::FindFullName(kBweWindowSizeInPacketsExperiment);
+      key_value_config->Lookup(kBweWindowSizeInPacketsExperiment);
   size_t window_size;
   int parsed_values =
       sscanf(experiment_string.c_str(), "Enabled-%zu", &window_size);
@@ -82,22 +82,25 @@
 
 DelayBasedBwe::Result::~Result() {}
 
-DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log)
+DelayBasedBwe::DelayBasedBwe(const WebRtcKeyValueConfig* key_value_config,
+                             RtcEventLog* event_log)
     : event_log_(event_log),
       inter_arrival_(),
       delay_detector_(),
       last_seen_packet_(Timestamp::MinusInfinity()),
       uma_recorded_(false),
       trendline_window_size_(
-          webrtc::field_trial::IsEnabled(kBweWindowSizeInPacketsExperiment)
-              ? ReadTrendlineFilterWindowSize()
+          key_value_config->Lookup(kBweWindowSizeInPacketsExperiment)
+                      .find("Enabled") == 0
+              ? ReadTrendlineFilterWindowSize(key_value_config)
               : kDefaultTrendlineWindowSize),
       trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff),
       trendline_threshold_gain_(kDefaultTrendlineThresholdGain),
       prev_bitrate_(DataRate::Zero()),
       prev_state_(BandwidthUsage::kBwNormal),
       alr_limited_backoff_enabled_(
-          field_trial::IsEnabled("WebRTC-Bwe-AlrLimitedBackoff")) {
+          key_value_config->Lookup("WebRTC-Bwe-AlrLimitedBackoff")
+              .find("Enabled") == 0) {
   RTC_LOG(LS_INFO)
       << "Using Trendline filter for delay change estimation with window size "
       << trendline_window_size_;
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.h b/modules/congestion_controller/goog_cc/delay_based_bwe.h
index ba9289c..c891afc 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.h
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.h
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/transport/webrtc_key_value_config.h"
 #include "modules/congestion_controller/goog_cc/delay_increase_detector_interface.h"
 #include "modules/congestion_controller/goog_cc/probe_bitrate_estimator.h"
 #include "modules/remote_bitrate_estimator/aimd_rate_control.h"
@@ -42,7 +43,8 @@
     bool backoff_in_alr;
   };
 
-  explicit DelayBasedBwe(RtcEventLog* event_log);
+  explicit DelayBasedBwe(const WebRtcKeyValueConfig* key_value_config,
+                         RtcEventLog* event_log);
   virtual ~DelayBasedBwe();
 
   Result IncomingPacketFeedbackVector(
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
index 006acf7..c057656 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
@@ -152,9 +152,10 @@
     : field_trial(),
       clock_(100000000),
       acknowledged_bitrate_estimator_(
-          absl::make_unique<AcknowledgedBitrateEstimator>()),
+          absl::make_unique<AcknowledgedBitrateEstimator>(
+              &field_trial_config_)),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
-      bitrate_estimator_(new DelayBasedBwe(nullptr)),
+      bitrate_estimator_(new DelayBasedBwe(&field_trial_config_, nullptr)),
       stream_generator_(new test::StreamGenerator(1e6,  // Capacity.
                                                   clock_.TimeInMicroseconds())),
       arrival_time_offset_ms_(0),
@@ -165,9 +166,10 @@
           absl::make_unique<test::ScopedFieldTrials>(field_trial_string)),
       clock_(100000000),
       acknowledged_bitrate_estimator_(
-          absl::make_unique<AcknowledgedBitrateEstimator>()),
+          absl::make_unique<AcknowledgedBitrateEstimator>(
+              &field_trial_config_)),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
-      bitrate_estimator_(new DelayBasedBwe(nullptr)),
+      bitrate_estimator_(new DelayBasedBwe(&field_trial_config_, nullptr)),
       stream_generator_(new test::StreamGenerator(1e6,  // Capacity.
                                                   clock_.TimeInMicroseconds())),
       arrival_time_offset_ms_(0),
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.h b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.h
index 4d8a00c..84831d9 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.h
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.h
@@ -17,6 +17,7 @@
 #include <string>
 #include <vector>
 
+#include "api/transport/field_trial_based_config.h"
 #include "api/transport/network_types.h"
 #include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
 #include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
@@ -167,6 +168,7 @@
                               int64_t receiver_clock_offset_change_ms);
 
   static const uint32_t kDefaultSsrc;
+  FieldTrialBasedConfig field_trial_config_;
 
   std::unique_ptr<test::ScopedFieldTrials>
       field_trial;        // Must be initialized first.
diff --git a/modules/congestion_controller/goog_cc/delay_based_rate_controller.cc b/modules/congestion_controller/goog_cc/delay_based_rate_controller.cc
index 7b768b8..3f0ff45 100644
--- a/modules/congestion_controller/goog_cc/delay_based_rate_controller.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_rate_controller.cc
@@ -14,7 +14,6 @@
 
 #include "absl/memory/memory.h"
 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 namespace {
@@ -25,7 +24,8 @@
 
 }  // namespace
 
-DelayBasedRateControllerConfig::DelayBasedRateControllerConfig()
+DelayBasedRateControllerConfig::DelayBasedRateControllerConfig(
+    const WebRtcKeyValueConfig* key_value_config)
     : enabled("Enabled"),
       no_ack_backoff_fraction("no_ack_frac", 0.8),
       no_ack_backoff_interval("no_ack_int", TimeDelta::ms(1000)),
@@ -44,14 +44,16 @@
        &increase_rate, &stop_increase_after, &min_increase_interval,
        &first_period_increase_rate, &linear_increase_threshold,
        &reference_duration_offset},
-      field_trial::FindFullName("WebRTC-Bwe-DelayBasedRateController"));
+      key_value_config->Lookup("WebRTC-Bwe-DelayBasedRateController"));
 }
 DelayBasedRateControllerConfig::~DelayBasedRateControllerConfig() = default;
 
 DelayBasedRateController::DelayBasedRateController(
+    const WebRtcKeyValueConfig* key_value_config,
     RtcEventLog* event_log,
     TargetRateConstraints constraints)
-    : event_log_(event_log),
+    : conf_(key_value_config),
+      event_log_(event_log),
       overuse_detector_(new TrendlineEstimator(kDefaultTrendlineWindowSize,
                                                kDefaultTrendlineSmoothingCoeff,
                                                kDefaultTrendlineThresholdGain)),
diff --git a/modules/congestion_controller/goog_cc/delay_based_rate_controller.h b/modules/congestion_controller/goog_cc/delay_based_rate_controller.h
index 2580c21..21932d2 100644
--- a/modules/congestion_controller/goog_cc/delay_based_rate_controller.h
+++ b/modules/congestion_controller/goog_cc/delay_based_rate_controller.h
@@ -14,6 +14,7 @@
 
 #include "absl/types/optional.h"
 #include "api/transport/network_types.h"
+#include "api/transport/webrtc_key_value_config.h"
 #include "logging/rtc_event_log/rtc_event_log.h"
 #include "modules/congestion_controller/goog_cc/link_capacity_estimator.h"
 #include "modules/congestion_controller/goog_cc/packet_grouping.h"
@@ -35,7 +36,8 @@
   FieldTrialParameter<TimeDelta> min_increase_interval;
   FieldTrialParameter<DataRate> linear_increase_threshold;
   FieldTrialParameter<TimeDelta> reference_duration_offset;
-  DelayBasedRateControllerConfig();
+  explicit DelayBasedRateControllerConfig(
+      const WebRtcKeyValueConfig* key_value_config);
   ~DelayBasedRateControllerConfig();
 };
 
@@ -43,7 +45,8 @@
 // fixed increase interval and an RTT dependent increase rate.
 class DelayBasedRateController {
  public:
-  DelayBasedRateController(RtcEventLog* event_log,
+  DelayBasedRateController(const WebRtcKeyValueConfig* key_value_config,
+                           RtcEventLog* event_log,
                            TargetRateConstraints constraints);
   ~DelayBasedRateController();
   void OnRouteChange();
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
index b996e34..6fd621f 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -29,7 +29,6 @@
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 namespace {
@@ -52,28 +51,27 @@
 // overshoots from the encoder.
 const float kDefaultPaceMultiplier = 2.5f;
 
-bool IsCongestionWindowPushbackExperimentEnabled() {
-  return webrtc::field_trial::IsEnabled(kCongestionPushbackExperiment) &&
-         webrtc::field_trial::IsEnabled(kCwndExperiment);
-}
-
 std::unique_ptr<CongestionWindowPushbackController>
-MaybeInitalizeCongestionWindowPushbackController() {
-  return IsCongestionWindowPushbackExperimentEnabled()
-             ? absl::make_unique<CongestionWindowPushbackController>()
-             : nullptr;
+MaybeCreateCongestionWindowPushbackController(
+    const WebRtcKeyValueConfig* const key_value_config) {
+  if (key_value_config->Lookup(kCongestionPushbackExperiment).find("Enabled") ==
+          0 &&
+      key_value_config->Lookup(kCwndExperiment).find("Enabled") == 0)
+    return absl::make_unique<CongestionWindowPushbackController>(
+        key_value_config);
+  return nullptr;
 }
 
-bool CwndExperimentEnabled() {
-  std::string experiment_string =
-      webrtc::field_trial::FindFullName(kCwndExperiment);
+bool CwndExperimentEnabled(const WebRtcKeyValueConfig* const key_value_config) {
+  std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
   // The experiment is enabled iff the field trial string begins with "Enabled".
   return experiment_string.find("Enabled") == 0;
 }
-bool ReadCwndExperimentParameter(int64_t* accepted_queue_ms) {
+bool ReadCwndExperimentParameter(
+    const WebRtcKeyValueConfig* const key_value_config,
+    int64_t* accepted_queue_ms) {
   RTC_DCHECK(accepted_queue_ms);
-  std::string experiment_string =
-      webrtc::field_trial::FindFullName(kCwndExperiment);
+  std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
   int parsed_values =
       sscanf(experiment_string.c_str(), "Enabled-%" PRId64, accepted_queue_ms);
   if (parsed_values == 1) {
@@ -130,32 +128,39 @@
 GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
                                                  NetworkControllerConfig config,
                                                  bool feedback_only)
-    : event_log_(event_log),
+    : key_value_config_(config.key_value_config ? config.key_value_config
+                                                : &trial_based_config_),
+      event_log_(event_log),
       packet_feedback_only_(feedback_only),
       safe_reset_on_route_change_("Enabled"),
       safe_reset_acknowledged_rate_("ack"),
       use_stable_bandwidth_estimate_(
-          field_trial::IsEnabled("WebRTC-Bwe-StableBandwidthEstimate")),
+          key_value_config_->Lookup("WebRTC-Bwe-StableBandwidthEstimate")
+              .find("Enabled") == 0),
       fall_back_to_probe_rate_(
-          field_trial::IsEnabled("WebRTC-Bwe-ProbeRateFallback")),
-      probe_controller_(new ProbeController()),
+          key_value_config_->Lookup("WebRTC-Bwe-ProbeRateFallback")
+              .find("Enabled") == 0),
+      probe_controller_(new ProbeController(key_value_config_)),
       congestion_window_pushback_controller_(
-          MaybeInitalizeCongestionWindowPushbackController()),
+          MaybeCreateCongestionWindowPushbackController(key_value_config_)),
       bandwidth_estimation_(
           absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
       alr_detector_(absl::make_unique<AlrDetector>()),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log)),
       use_new_delay_based_controller_(
-          field_trial::IsEnabled("WebRTC-Bwe-DelayBasedRateController")),
+          key_value_config_->Lookup("WebRTC-Bwe-DelayBasedRateController")
+              .find("Enabled") == 0),
       delay_based_bwe_(use_new_delay_based_controller_
                            ? nullptr
-                           : new DelayBasedBwe(event_log_)),
+                           : new DelayBasedBwe(key_value_config_, event_log_)),
       delay_based_controller_(
           use_new_delay_based_controller_
-              ? new DelayBasedRateController(event_log_, config.constraints)
+              ? new DelayBasedRateController(key_value_config_,
+                                             event_log_,
+                                             config.constraints)
               : nullptr),
       acknowledged_bitrate_estimator_(
-          absl::make_unique<AcknowledgedBitrateEstimator>()),
+          absl::make_unique<AcknowledgedBitrateEstimator>(key_value_config_)),
       initial_config_(config),
       last_raw_target_rate_(*config.constraints.starting_rate),
       last_pushback_target_rate_(last_raw_target_rate_),
@@ -166,16 +171,16 @@
       max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
           DataRate::Zero())),
       max_total_allocated_bitrate_(DataRate::Zero()),
-      in_cwnd_experiment_(CwndExperimentEnabled()),
+      in_cwnd_experiment_(CwndExperimentEnabled(key_value_config_)),
       accepted_queue_ms_(kDefaultAcceptedQueueMs) {
   RTC_DCHECK(config.constraints.at_time.IsFinite());
   ParseFieldTrial(
       {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
-      field_trial::FindFullName("WebRTC-Bwe-SafeResetOnRouteChange"));
+      key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange"));
   if (delay_based_bwe_)
     delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrate());
   if (in_cwnd_experiment_ &&
-      !ReadCwndExperimentParameter(&accepted_queue_ms_)) {
+      !ReadCwndExperimentParameter(key_value_config_, &accepted_queue_ms_)) {
     RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
                            "from field trial string. Experiment disabled.";
     in_cwnd_experiment_ = false;
@@ -221,10 +226,11 @@
     }
   }
 
-  acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
+  acknowledged_bitrate_estimator_.reset(
+      new AcknowledgedBitrateEstimator(key_value_config_));
   probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
   if (delay_based_bwe_) {
-    delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
+    delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_));
     if (msg.constraints.starting_rate)
       delay_based_bwe_->SetStartBitrate(*msg.constraints.starting_rate);
     // TODO(srte): Use original values instead of converted.
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
index c188d11..7d65689 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
@@ -17,8 +17,10 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/transport/field_trial_based_config.h"
 #include "api/transport/network_control.h"
 #include "api/transport/network_types.h"
+#include "api/transport/webrtc_key_value_config.h"
 #include "api/units/data_rate.h"
 #include "api/units/data_size.h"
 #include "api/units/timestamp.h"
@@ -67,7 +69,9 @@
   void MaybeTriggerOnNetworkChanged(NetworkControlUpdate* update,
                                     Timestamp at_time);
   PacerConfig GetPacingRates(Timestamp at_time) const;
+  const FieldTrialBasedConfig trial_based_config_;
 
+  const WebRtcKeyValueConfig* const key_value_config_;
   RtcEventLog* const event_log_;
   const bool packet_feedback_only_;
   FieldTrialFlag safe_reset_on_route_change_;
diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc
index 94a98e0..a71902d 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller.cc
@@ -20,7 +20,6 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
-#include "system_wrappers/include/field_trial.h"
 #include "system_wrappers/include/metrics.h"
 
 namespace webrtc {
@@ -83,12 +82,14 @@
 
 }  // namespace
 
-ProbeController::ProbeController()
+ProbeController::ProbeController(const WebRtcKeyValueConfig* key_value_config)
     : enable_periodic_alr_probing_(false),
       in_rapid_recovery_experiment_(
-          webrtc::field_trial::IsEnabled(kBweRapidRecoveryExperiment)),
+          key_value_config->Lookup(kBweRapidRecoveryExperiment)
+              .find("Enabled") == 0),
       limit_probes_with_allocateable_rate_(
-          !webrtc::field_trial::IsDisabled(kCappedProbingFieldTrialName)) {
+          key_value_config->Lookup(kCappedProbingFieldTrialName)
+              .find("Disabled") != 0) {
   Reset(0);
 }
 
diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h
index 98df8c7..bacea0c 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.h
+++ b/modules/congestion_controller/goog_cc/probe_controller.h
@@ -18,6 +18,7 @@
 
 #include "absl/types/optional.h"
 #include "api/transport/network_control.h"
+#include "api/transport/webrtc_key_value_config.h"
 #include "rtc_base/constructor_magic.h"
 #include "rtc_base/system/unused.h"
 
@@ -30,7 +31,7 @@
 // bitrate is adjusted by an application.
 class ProbeController {
  public:
-  ProbeController();
+  explicit ProbeController(const WebRtcKeyValueConfig* key_value_config);
   ~ProbeController();
 
   RTC_WARN_UNUSED_RESULT std::vector<ProbeClusterConfig> SetBitrates(
diff --git a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
index 9472d01..067aabb 100644
--- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
@@ -9,6 +9,7 @@
  */
 #include <memory>
 
+#include "api/transport/field_trial_based_config.h"
 #include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/timestamp.h"
@@ -43,7 +44,7 @@
 class ProbeControllerTest : public ::testing::Test {
  protected:
   ProbeControllerTest() : clock_(100000000L) {
-    probe_controller_.reset(new ProbeController());
+    probe_controller_.reset(new ProbeController(&field_trial_config_));
   }
   ~ProbeControllerTest() override {}
 
@@ -56,6 +57,7 @@
 
   int64_t NowMs() { return clock_.TimeInMilliseconds(); }
 
+  FieldTrialBasedConfig field_trial_config_;
   SimulatedClock clock_;
   std::unique_ptr<ProbeController> probe_controller_;
 };
@@ -223,7 +225,7 @@
 }
 
 TEST_F(ProbeControllerTest, PeriodicProbingAfterReset) {
-  probe_controller_.reset(new ProbeController());
+  probe_controller_.reset(new ProbeController(&field_trial_config_));
   int64_t alr_start_time = clock_.TimeInMilliseconds();
 
   probe_controller_->SetAlrStartTimeMs(alr_start_time);
diff --git a/modules/congestion_controller/include/send_side_congestion_controller.h b/modules/congestion_controller/include/send_side_congestion_controller.h
index 1a601ec..b428eed 100644
--- a/modules/congestion_controller/include/send_side_congestion_controller.h
+++ b/modules/congestion_controller/include/send_side_congestion_controller.h
@@ -14,6 +14,8 @@
 #include <memory>
 #include <vector>
 
+#include "api/transport/field_trial_based_config.h"
+#include "api/transport/webrtc_key_value_config.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
 #include "modules/congestion_controller/include/network_changed_observer.h"
@@ -48,10 +50,12 @@
     : public SendSideCongestionControllerInterface {
  public:
   using Observer = NetworkChangedObserver;
-  DEPRECATED_SendSideCongestionController(const Clock* clock,
-                                          Observer* observer,
-                                          RtcEventLog* event_log,
-                                          PacedSender* pacer);
+  DEPRECATED_SendSideCongestionController(
+      const Clock* clock,
+      Observer* observer,
+      RtcEventLog* event_log,
+      PacedSender* pacer,
+      const WebRtcKeyValueConfig* key_value_config = nullptr);
   ~DEPRECATED_SendSideCongestionController() override;
 
   void RegisterPacketFeedbackObserver(
@@ -134,6 +138,8 @@
   void LimitOutstandingBytes(size_t num_outstanding_bytes);
   void SendProbes(std::vector<ProbeClusterConfig> probe_configs)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(&probe_lock_);
+  const FieldTrialBasedConfig field_trial_config_;
+  const WebRtcKeyValueConfig* const key_value_config_;
   const Clock* const clock_;
   rtc::CriticalSection observer_lock_;
   Observer* observer_ RTC_GUARDED_BY(observer_lock_);
diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc
index d49e567..8b6d223 100644
--- a/modules/congestion_controller/send_side_congestion_controller.cc
+++ b/modules/congestion_controller/send_side_congestion_controller.cc
@@ -32,7 +32,6 @@
 #include "rtc_base/network/sent_packet.h"
 #include "rtc_base/rate_limiter.h"
 #include "rtc_base/time_utils.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 namespace {
@@ -47,17 +46,17 @@
 
 const int64_t kDefaultAcceptedQueueMs = 250;
 
-bool CwndExperimentEnabled() {
-  std::string experiment_string =
-      webrtc::field_trial::FindFullName(kCwndExperiment);
+bool CwndExperimentEnabled(const WebRtcKeyValueConfig* const key_value_config) {
+  std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
   // The experiment is enabled iff the field trial string begins with "Enabled".
   return experiment_string.find("Enabled") == 0;
 }
 
-bool ReadCwndExperimentParameter(int64_t* accepted_queue_ms) {
+bool ReadCwndExperimentParameter(
+    const WebRtcKeyValueConfig* const key_value_config,
+    int64_t* accepted_queue_ms) {
   RTC_DCHECK(accepted_queue_ms);
-  std::string experiment_string =
-      webrtc::field_trial::FindFullName(kCwndExperiment);
+  std::string experiment_string = key_value_config->Lookup(kCwndExperiment);
   int parsed_values =
       sscanf(experiment_string.c_str(), "Enabled-%" PRId64, accepted_queue_ms);
   if (parsed_values == 1) {
@@ -68,16 +67,15 @@
   return false;
 }
 
-bool IsCongestionWindowPushbackExperimentEnabled() {
-  return webrtc::field_trial::IsEnabled(kCongestionPushbackExperiment) &&
-         webrtc::field_trial::IsEnabled(kCwndExperiment);
-}
-
 std::unique_ptr<CongestionWindowPushbackController>
-MaybeCreateCongestionWindowPushbackController() {
-  return IsCongestionWindowPushbackExperimentEnabled()
-             ? absl::make_unique<CongestionWindowPushbackController>()
-             : nullptr;
+MaybeCreateCongestionWindowPushbackController(
+    const WebRtcKeyValueConfig* const key_value_config) {
+  if (key_value_config->Lookup(kCongestionPushbackExperiment).find("Enabled") ==
+          0 &&
+      key_value_config->Lookup(kCwndExperiment).find("Enabled") == 0)
+    return absl::make_unique<CongestionWindowPushbackController>(
+        key_value_config);
+  return nullptr;
 }
 
 static const int64_t kRetransmitWindowSizeMs = 500;
@@ -116,26 +114,32 @@
   std::sort(input->begin(), input->end(), PacketFeedbackComparator());
 }
 
-bool IsPacerPushbackExperimentEnabled() {
-  return webrtc::field_trial::IsEnabled(kPacerPushbackExperiment);
+bool IsPacerPushbackExperimentEnabled(
+    const WebRtcKeyValueConfig* const key_value_config) {
+  return key_value_config->Lookup(kPacerPushbackExperiment).find("Enabled") ==
+         0;
 }
 
 }  // namespace
 
 DEPRECATED_SendSideCongestionController::
-    DEPRECATED_SendSideCongestionController(const Clock* clock,
-                                            Observer* observer,
-                                            RtcEventLog* event_log,
-                                            PacedSender* pacer)
-    : clock_(clock),
+    DEPRECATED_SendSideCongestionController(
+        const Clock* clock,
+        Observer* observer,
+        RtcEventLog* event_log,
+        PacedSender* pacer,
+        const WebRtcKeyValueConfig* key_value_config)
+    : key_value_config_(key_value_config ? key_value_config
+                                         : &field_trial_config_),
+      clock_(clock),
       observer_(observer),
       event_log_(event_log),
       pacer_(pacer),
       bitrate_controller_(
           BitrateController::CreateBitrateController(clock_, event_log)),
       acknowledged_bitrate_estimator_(
-          absl::make_unique<AcknowledgedBitrateEstimator>()),
-      probe_controller_(new ProbeController()),
+          absl::make_unique<AcknowledgedBitrateEstimator>(key_value_config_)),
+      probe_controller_(new ProbeController(key_value_config_)),
       retransmission_rate_limiter_(
           new RateLimiter(clock, kRetransmitWindowSizeMs)),
       transport_feedback_adapter_(clock_),
@@ -147,19 +151,21 @@
       pacer_paused_(false),
       min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log_)),
-      delay_based_bwe_(new DelayBasedBwe(event_log_)),
-      in_cwnd_experiment_(CwndExperimentEnabled()),
+      delay_based_bwe_(new DelayBasedBwe(key_value_config_, event_log_)),
+      in_cwnd_experiment_(CwndExperimentEnabled(key_value_config_)),
       accepted_queue_ms_(kDefaultAcceptedQueueMs),
       was_in_alr_(false),
       send_side_bwe_with_overhead_(
-          webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
+          key_value_config_->Lookup("WebRTC-SendSideBwe-WithOverhead")
+              .find("Enabled") == 0),
       transport_overhead_bytes_per_packet_(0),
-      pacer_pushback_experiment_(IsPacerPushbackExperimentEnabled()),
+      pacer_pushback_experiment_(
+          IsPacerPushbackExperimentEnabled(key_value_config_)),
       congestion_window_pushback_controller_(
-          MaybeCreateCongestionWindowPushbackController()) {
+          MaybeCreateCongestionWindowPushbackController(key_value_config_)) {
   delay_based_bwe_->SetMinBitrate(DataRate::bps(min_bitrate_bps_));
   if (in_cwnd_experiment_ &&
-      !ReadCwndExperimentParameter(&accepted_queue_ms_)) {
+      !ReadCwndExperimentParameter(key_value_config_, &accepted_queue_ms_)) {
     RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
                            "from field trial string. Experiment disabled.";
     in_cwnd_experiment_ = false;
@@ -183,7 +189,7 @@
   accepted_queue_ms_ = accepted_queue_ms;
   congestion_window_pushback_controller_ =
       absl::make_unique<CongestionWindowPushbackController>(
-          min_pushback_target_bitrate_bps);
+          key_value_config_, min_pushback_target_bitrate_bps);
 }
 
 void DEPRECATED_SendSideCongestionController::SetAlrLimitedBackoffExperiment(
@@ -278,8 +284,9 @@
     transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
     min_bitrate_bps_ = min_bitrate_bps;
     probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
-    delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
-    acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
+    delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_));
+    acknowledged_bitrate_estimator_.reset(
+        new AcknowledgedBitrateEstimator(key_value_config_));
     if (bitrate_bps > 0) {
       delay_based_bwe_->SetStartBitrate(DataRate::bps(bitrate_bps));
     }
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index 77aba17..cf23fb0 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -129,6 +129,7 @@
       "..:module_api_public",
       "../..:webrtc_common",
       "../../api:libjingle_peerconnection_api",
+      "../../api/transport:field_trial_based_config",
       "../../api/transport:network_control",
       "../../logging:mocks",
       "../../rtc_base:checks",
diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/modules/remote_bitrate_estimator/test/estimators/send_side.cc
index 0221edf..692a0d4 100644
--- a/modules/remote_bitrate_estimator/test/estimators/send_side.cc
+++ b/modules/remote_bitrate_estimator/test/estimators/send_side.cc
@@ -35,9 +35,10 @@
                                                      observer,
                                                      &event_log_)),
       acknowledged_bitrate_estimator_(
-          absl::make_unique<AcknowledgedBitrateEstimator>()),
+          absl::make_unique<AcknowledgedBitrateEstimator>(
+              &field_trial_config_)),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
-      bwe_(new DelayBasedBwe(nullptr)),
+      bwe_(new DelayBasedBwe(&field_trial_config_, nullptr)),
       feedback_observer_(bitrate_controller_.get()),
       clock_(clock),
       send_time_history_(clock_, 10000),
diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.h b/modules/remote_bitrate_estimator/test/estimators/send_side.h
index 2313b7b..4d7cb18 100644
--- a/modules/remote_bitrate_estimator/test/estimators/send_side.h
+++ b/modules/remote_bitrate_estimator/test/estimators/send_side.h
@@ -15,6 +15,7 @@
 #include <memory>
 #include <vector>
 
+#include "api/transport/field_trial_based_config.h"
 #include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
 #include "modules/bitrate_controller/include/bitrate_controller.h"
 #include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
@@ -46,6 +47,9 @@
   int64_t TimeUntilNextProcess() override;
   void Process() override;
 
+ private:
+  FieldTrialBasedConfig field_trial_config_;
+
  protected:
   std::unique_ptr<BitrateController> bitrate_controller_;
   std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator_;
diff --git a/rtc_tools/BUILD.gn b/rtc_tools/BUILD.gn
index b77d671..4e9e3cf 100644
--- a/rtc_tools/BUILD.gn
+++ b/rtc_tools/BUILD.gn
@@ -260,6 +260,7 @@
 
         # TODO(kwiberg): Remove this dependency.
         "../api/audio_codecs:audio_codecs_api",
+        "../api/transport:field_trial_based_config",
         "../api/transport:goog_cc",
         "../call:call_interfaces",
         "../call:video_stream_api",
diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc
index 13b46ac..f603784 100644
--- a/rtc_tools/event_log_visualizer/analyzer.cc
+++ b/rtc_tools/event_log_visualizer/analyzer.cc
@@ -19,6 +19,7 @@
 
 #include "absl/memory/memory.h"
 #include "absl/strings/string_view.h"
+#include "api/transport/field_trial_based_config.h"
 #include "api/transport/goog_cc_factory.h"
 #include "call/audio_receive_stream.h"
 #include "call/audio_send_stream.h"
@@ -1118,6 +1119,7 @@
 
   RateStatistics acked_bitrate(250, 8000);
 #if !(BWE_TEST_LOGGING_COMPILE_TIME_ENABLE)
+  FieldTrialBasedConfig field_trial_config_;
   // The event_log_visualizer should normally not be compiled with
   // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE since the normal plots won't work.
   // However, compiling with BWE_TEST_LOGGING, runnning with --plot_sendside_bwe
@@ -1126,7 +1128,8 @@
   // we don't instantiate the AcknowledgedBitrateEstimator both here and in
   // SendSideCongestionController since that would lead to duplicate outputs.
   AcknowledgedBitrateEstimator acknowledged_bitrate_estimator(
-      absl::make_unique<BitrateEstimator>());
+      &field_trial_config_,
+      absl::make_unique<BitrateEstimator>(&field_trial_config_));
 #endif  // !(BWE_TEST_LOGGING_COMPILE_TIME_ENABLE)
   int64_t time_us =
       std::min({NextRtpTime(), NextRtcpTime(), NextProcessTime()});