WebRTC-DeprecateGlobalFieldTrialString/Enabled/ - part 11/inf

convert rtc_base/network and collateral.

This also remove last usage of system_wrappers/field_trials
in p2p/...Yay!

Bug: webrtc:10335
Change-Id: Ie8507b1f52bf7f3067e9b4bf8c81a825e4644fda
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256640
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36357}
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index d0571c9..afb410d 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -918,6 +918,7 @@
       "../rtc_base:rtc_base_approved",
       "../rtc_base:socket_address",
       "../rtc_base:threading",
+      "../test:scoped_key_value_config",
       "//third_party/abseil-cpp/absl/flags:flag",
       "//third_party/abseil-cpp/absl/flags:parse",
     ]
diff --git a/examples/stunprober/main.cc b/examples/stunprober/main.cc
index d0ed92c..dda5463 100644
--- a/examples/stunprober/main.cc
+++ b/examples/stunprober/main.cc
@@ -26,6 +26,7 @@
 #include "rtc_base/ssl_adapter.h"
 #include "rtc_base/thread.h"
 #include "rtc_base/time_utils.h"
+#include "test/scoped_key_value_config.h"
 
 using stunprober::AsyncCallback;
 using stunprober::StunProber;
@@ -123,12 +124,13 @@
 
   rtc::InitializeSSL();
   rtc::InitRandom(rtc::Time32());
+  webrtc::test::ScopedKeyValueConfig field_trials;
   rtc::PhysicalSocketServer socket_server;
   rtc::AutoSocketServerThread thread(&socket_server);
   auto socket_factory =
       std::make_unique<rtc::BasicPacketSocketFactory>(&socket_server);
   std::unique_ptr<rtc::BasicNetworkManager> network_manager(
-      new rtc::BasicNetworkManager(&socket_server));
+      new rtc::BasicNetworkManager(&socket_server, &field_trials));
   rtc::NetworkManager::NetworkList networks;
   network_manager->GetNetworks(&networks);
   auto prober = std::make_unique<StunProber>(socket_factory.get(),
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index 758f8bf..0524b56 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -115,6 +115,7 @@
     "../rtc_base:threading",
     "../rtc_base/containers:flat_map",
     "../rtc_base/experiments:field_trial_parser",
+    "../rtc_base/memory:always_valid_pointer",
     "../rtc_base/system:no_unique_address",
 
     # Needed by pseudo_tcp, which should move to a separate target.
@@ -127,7 +128,6 @@
     "../rtc_base/task_utils:to_queued_task",
     "../rtc_base/third_party/base64",
     "../rtc_base/third_party/sigslot",
-    "../system_wrappers:field_trial",
     "../system_wrappers:metrics",
   ]
   absl_deps = [
@@ -166,6 +166,7 @@
       "../rtc_base",
       "../rtc_base:net_helpers",
       "../rtc_base:threading",
+      "../test:scoped_key_value_config",
     ]
   }
 
@@ -260,7 +261,6 @@
       "../rtc_base/network:sent_packet",
       "../rtc_base/third_party/sigslot",
       "../system_wrappers:metrics",
-      "../test:field_trial",
       "../test:rtc_expect_death",
       "../test:scoped_key_value_config",
       "../test:test_support",
diff --git a/p2p/base/fake_port_allocator.h b/p2p/base/fake_port_allocator.h
index e3a239a..3d93b07 100644
--- a/p2p/base/fake_port_allocator.h
+++ b/p2p/base/fake_port_allocator.h
@@ -20,6 +20,7 @@
 #include "p2p/base/udp_port.h"
 #include "rtc_base/net_helpers.h"
 #include "rtc_base/thread.h"
+#include "test/scoped_key_value_config.h"
 
 namespace rtc {
 class SocketFactory;
@@ -36,10 +37,11 @@
                              uint16_t max_port,
                              const std::string& username,
                              const std::string& password,
-                             bool emit_localhost_for_anyaddress) {
+                             bool emit_localhost_for_anyaddress,
+                             const webrtc::WebRtcKeyValueConfig* field_trials) {
     TestUDPPort* port =
         new TestUDPPort(thread, factory, network, min_port, max_port, username,
-                        password, emit_localhost_for_anyaddress);
+                        password, emit_localhost_for_anyaddress, field_trials);
     if (!port->Init()) {
       delete port;
       port = nullptr;
@@ -55,7 +57,8 @@
               uint16_t max_port,
               const std::string& username,
               const std::string& password,
-              bool emit_localhost_for_anyaddress)
+              bool emit_localhost_for_anyaddress,
+              const webrtc::WebRtcKeyValueConfig* field_trials)
       : UDPPort(thread,
                 factory,
                 network,
@@ -63,7 +66,8 @@
                 max_port,
                 username,
                 password,
-                emit_localhost_for_anyaddress) {}
+                emit_localhost_for_anyaddress,
+                field_trials) {}
 };
 
 // A FakePortAllocatorSession can be used with either a real or fake socket
@@ -77,7 +81,8 @@
                            const std::string& content_name,
                            int component,
                            const std::string& ice_ufrag,
-                           const std::string& ice_pwd)
+                           const std::string& ice_pwd,
+                           const webrtc::WebRtcKeyValueConfig& field_trials)
       : PortAllocatorSession(content_name,
                              component,
                              ice_ufrag,
@@ -96,7 +101,8 @@
         port_(),
         port_config_count_(0),
         stun_servers_(allocator->stun_servers()),
-        turn_servers_(allocator->turn_servers()) {
+        turn_servers_(allocator->turn_servers()),
+        field_trials_(field_trials) {
     ipv4_network_.AddIP(rtc::IPAddress(INADDR_LOOPBACK));
     ipv6_network_.AddIP(rtc::IPAddress(in6addr_loopback));
   }
@@ -112,7 +118,8 @@
               ? ipv6_network_
               : ipv4_network_;
       port_.reset(TestUDPPort::Create(network_thread_, factory_, &network, 0, 0,
-                                      username(), password(), false));
+                                      username(), password(), false,
+                                      &field_trials_));
       RTC_DCHECK(port_);
       port_->SubscribePortDestroyed(
           [this](PortInterface* port) { OnPortDestroyed(port); });
@@ -200,6 +207,7 @@
   uint32_t candidate_filter_ = CF_ALL;
   int transport_info_update_count_ = 0;
   bool running_ = false;
+  const webrtc::WebRtcKeyValueConfig& field_trials_;
 };
 
 class FakePortAllocator : public cricket::PortAllocator {
@@ -231,7 +239,7 @@
       const std::string& ice_pwd) override {
     return new FakePortAllocatorSession(this, network_thread_, factory_,
                                         content_name, component, ice_ufrag,
-                                        ice_pwd);
+                                        ice_pwd, field_trials_);
   }
 
   bool initialized() const { return initialized_; }
@@ -245,6 +253,7 @@
   }
 
  private:
+  webrtc::test::ScopedKeyValueConfig field_trials_;
   rtc::Thread* network_thread_;
   rtc::PacketSocketFactory* factory_;
   std::unique_ptr<rtc::BasicPacketSocketFactory> owned_factory_;
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index 1aefe5f..72f4efb 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -110,7 +110,8 @@
            rtc::PacketSocketFactory* factory,
            const rtc::Network* network,
            const std::string& username_fragment,
-           const std::string& password)
+           const std::string& password,
+           const webrtc::WebRtcKeyValueConfig* field_trials)
     : thread_(thread),
       factory_(factory),
       type_(type),
@@ -127,7 +128,8 @@
       ice_role_(ICEROLE_UNKNOWN),
       tiebreaker_(0),
       shared_socket_(true),
-      weak_factory_(this) {
+      weak_factory_(this),
+      field_trials_(field_trials) {
   RTC_DCHECK(factory_ != NULL);
   Construct();
 }
@@ -139,7 +141,8 @@
            uint16_t min_port,
            uint16_t max_port,
            const std::string& username_fragment,
-           const std::string& password)
+           const std::string& password,
+           const webrtc::WebRtcKeyValueConfig* field_trials)
     : thread_(thread),
       factory_(factory),
       type_(type),
@@ -156,7 +159,8 @@
       ice_role_(ICEROLE_UNKNOWN),
       tiebreaker_(0),
       shared_socket_(false),
-      weak_factory_(this) {
+      weak_factory_(this),
+      field_trials_(field_trials) {
   RTC_DCHECK(factory_ != NULL);
   Construct();
 }
@@ -171,7 +175,7 @@
     password_ = rtc::CreateRandomString(ICE_PWD_LENGTH);
   }
   network_->SignalTypeChanged.connect(this, &Port::OnNetworkTypeChanged);
-  network_cost_ = network_->GetCost();
+  network_cost_ = network_->GetCost(*field_trials_);
 
   thread_->PostDelayed(RTC_FROM_HERE, timeout_delay_, this,
                        MSG_DESTROY_IF_DEAD);
@@ -880,7 +884,7 @@
 
 // TODO(honghaiz): Make the network cost configurable from user setting.
 void Port::UpdateNetworkCost() {
-  uint16_t new_cost = network_->GetCost();
+  uint16_t new_cost = network_->GetCost(*field_trials_);
   if (network_cost_ == new_cost) {
     return;
   }
diff --git a/p2p/base/port.h b/p2p/base/port.h
index ad4387d..343170f 100644
--- a/p2p/base/port.h
+++ b/p2p/base/port.h
@@ -22,7 +22,9 @@
 #include "api/candidate.h"
 #include "api/packet_socket_factory.h"
 #include "api/rtc_error.h"
+#include "api/transport/field_trial_based_config.h"
 #include "api/transport/stun.h"
+#include "api/webrtc_key_value_config.h"
 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
 #include "logging/rtc_event_log/ice_logger.h"
@@ -35,6 +37,7 @@
 #include "rtc_base/async_packet_socket.h"
 #include "rtc_base/callback_list.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/memory/always_valid_pointer.h"
 #include "rtc_base/net_helper.h"
 #include "rtc_base/network.h"
 #include "rtc_base/proxy_info.h"
@@ -185,7 +188,8 @@
        rtc::PacketSocketFactory* factory,
        const rtc::Network* network,
        const std::string& username_fragment,
-       const std::string& password);
+       const std::string& password,
+       const webrtc::WebRtcKeyValueConfig* field_trials = nullptr);
   Port(rtc::Thread* thread,
        const std::string& type,
        rtc::PacketSocketFactory* factory,
@@ -193,7 +197,8 @@
        uint16_t min_port,
        uint16_t max_port,
        const std::string& username_fragment,
-       const std::string& password);
+       const std::string& password,
+       const webrtc::WebRtcKeyValueConfig* field_trials = nullptr);
   ~Port() override;
 
   // Note that the port type does NOT uniquely identify different subclasses of
@@ -494,6 +499,9 @@
       MdnsNameRegistrationStatus::kNotStarted;
 
   rtc::WeakPtrFactory<Port> weak_factory_;
+  webrtc::AlwaysValidPointer<const webrtc::WebRtcKeyValueConfig,
+                             webrtc::FieldTrialBasedConfig>
+      field_trials_;
 
   bool MaybeObfuscateAddress(Candidate* c,
                              const std::string& type,
diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc
index f5eed7e..32401e2 100644
--- a/p2p/base/port_unittest.cc
+++ b/p2p/base/port_unittest.cc
@@ -64,6 +64,7 @@
 #include "rtc_base/time_utils.h"
 #include "rtc_base/virtual_socket_server.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 using rtc::AsyncListenSocket;
 using rtc::AsyncPacketSocket;
@@ -519,7 +520,8 @@
   std::unique_ptr<UDPPort> CreateUdpPort(const SocketAddress& addr,
                                          PacketSocketFactory* socket_factory) {
     return UDPPort::Create(&main_, socket_factory, MakeNetwork(addr), 0, 0,
-                           username_, password_, true, absl::nullopt);
+                           username_, password_, true, absl::nullopt,
+                           &field_trials_);
   }
   std::unique_ptr<TCPPort> CreateTcpPort(const SocketAddress& addr) {
     return CreateTcpPort(addr, &socket_factory_);
@@ -527,14 +529,15 @@
   std::unique_ptr<TCPPort> CreateTcpPort(const SocketAddress& addr,
                                          PacketSocketFactory* socket_factory) {
     return TCPPort::Create(&main_, socket_factory, MakeNetwork(addr), 0, 0,
-                           username_, password_, true);
+                           username_, password_, true, &field_trials_);
   }
   std::unique_ptr<StunPort> CreateStunPort(const SocketAddress& addr,
                                            rtc::PacketSocketFactory* factory) {
     ServerAddresses stun_servers;
     stun_servers.insert(kStunAddr);
     return StunPort::Create(&main_, factory, MakeNetwork(addr), 0, 0, username_,
-                            password_, stun_servers, absl::nullopt);
+                            password_, stun_servers, absl::nullopt,
+                            &field_trials_);
   }
   std::unique_ptr<Port> CreateRelayPort(const SocketAddress& addr,
                                         ProtocolType int_proto,
@@ -567,6 +570,7 @@
     args.password = password_;
     args.server_address = &server_address;
     args.config = &config;
+    args.field_trials = &field_trials_;
 
     return TurnPort::Create(args, 0, 0);
   }
@@ -832,6 +836,7 @@
   std::string password_;
   bool role_conflict_;
   int ports_destroyed_;
+  webrtc::test::ScopedKeyValueConfig field_trials_;
 };
 
 void PortTest::TestConnectivity(const char* name1,
diff --git a/p2p/base/stun_port.cc b/p2p/base/stun_port.cc
index 4fa42f7..46052a0 100644
--- a/p2p/base/stun_port.cc
+++ b/p2p/base/stun_port.cc
@@ -157,8 +157,15 @@
                  rtc::AsyncPacketSocket* socket,
                  const std::string& username,
                  const std::string& password,
-                 bool emit_local_for_anyaddress)
-    : Port(thread, LOCAL_PORT_TYPE, factory, network, username, password),
+                 bool emit_local_for_anyaddress,
+                 const webrtc::WebRtcKeyValueConfig* field_trials)
+    : Port(thread,
+           LOCAL_PORT_TYPE,
+           factory,
+           network,
+           username,
+           password,
+           field_trials),
       requests_(thread),
       socket_(socket),
       error_(0),
@@ -174,7 +181,8 @@
                  uint16_t max_port,
                  const std::string& username,
                  const std::string& password,
-                 bool emit_local_for_anyaddress)
+                 bool emit_local_for_anyaddress,
+                 const webrtc::WebRtcKeyValueConfig* field_trials)
     : Port(thread,
            LOCAL_PORT_TYPE,
            factory,
@@ -182,7 +190,8 @@
            min_port,
            max_port,
            username,
-           password),
+           password,
+           field_trials),
       requests_(thread),
       socket_(nullptr),
       error_(0),
@@ -605,11 +614,12 @@
     const std::string& username,
     const std::string& password,
     const ServerAddresses& servers,
-    absl::optional<int> stun_keepalive_interval) {
+    absl::optional<int> stun_keepalive_interval,
+    const webrtc::WebRtcKeyValueConfig* field_trials) {
   // Using `new` to access a non-public constructor.
-  auto port =
-      absl::WrapUnique(new StunPort(thread, factory, network, min_port,
-                                    max_port, username, password, servers));
+  auto port = absl::WrapUnique(new StunPort(thread, factory, network, min_port,
+                                            max_port, username, password,
+                                            servers, field_trials));
   port->set_stun_keepalive_delay(stun_keepalive_interval);
   if (!port->Init()) {
     return nullptr;
@@ -624,7 +634,8 @@
                    uint16_t max_port,
                    const std::string& username,
                    const std::string& password,
-                   const ServerAddresses& servers)
+                   const ServerAddresses& servers,
+                   const webrtc::WebRtcKeyValueConfig* field_trials)
     : UDPPort(thread,
               factory,
               network,
@@ -632,7 +643,8 @@
               max_port,
               username,
               password,
-              false) {
+              false,
+              field_trials) {
   // UDPPort will set these to local udp, updating these to STUN.
   set_type(STUN_PORT_TYPE);
   set_server_addresses(servers);
diff --git a/p2p/base/stun_port.h b/p2p/base/stun_port.h
index 99d22a6..485fca8 100644
--- a/p2p/base/stun_port.h
+++ b/p2p/base/stun_port.h
@@ -40,11 +40,12 @@
       const std::string& username,
       const std::string& password,
       bool emit_local_for_anyaddress,
-      absl::optional<int> stun_keepalive_interval) {
+      absl::optional<int> stun_keepalive_interval,
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) {
     // Using `new` to access a non-public constructor.
-    auto port =
-        absl::WrapUnique(new UDPPort(thread, factory, network, socket, username,
-                                     password, emit_local_for_anyaddress));
+    auto port = absl::WrapUnique(
+        new UDPPort(thread, factory, network, socket, username, password,
+                    emit_local_for_anyaddress, field_trials));
     port->set_stun_keepalive_delay(stun_keepalive_interval);
     if (!port->Init()) {
       return nullptr;
@@ -61,11 +62,12 @@
       const std::string& username,
       const std::string& password,
       bool emit_local_for_anyaddress,
-      absl::optional<int> stun_keepalive_interval) {
+      absl::optional<int> stun_keepalive_interval,
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) {
     // Using `new` to access a non-public constructor.
-    auto port = absl::WrapUnique(new UDPPort(thread, factory, network, min_port,
-                                             max_port, username, password,
-                                             emit_local_for_anyaddress));
+    auto port = absl::WrapUnique(
+        new UDPPort(thread, factory, network, min_port, max_port, username,
+                    password, emit_local_for_anyaddress, field_trials));
     port->set_stun_keepalive_delay(stun_keepalive_interval);
     if (!port->Init()) {
       return nullptr;
@@ -124,7 +126,8 @@
           uint16_t max_port,
           const std::string& username,
           const std::string& password,
-          bool emit_local_for_anyaddress);
+          bool emit_local_for_anyaddress,
+          const webrtc::WebRtcKeyValueConfig* field_trials);
 
   UDPPort(rtc::Thread* thread,
           rtc::PacketSocketFactory* factory,
@@ -132,7 +135,8 @@
           rtc::AsyncPacketSocket* socket,
           const std::string& username,
           const std::string& password,
-          bool emit_local_for_anyaddress);
+          bool emit_local_for_anyaddress,
+          const webrtc::WebRtcKeyValueConfig* field_trials);
 
   bool Init();
 
@@ -270,7 +274,8 @@
       const std::string& username,
       const std::string& password,
       const ServerAddresses& servers,
-      absl::optional<int> stun_keepalive_interval);
+      absl::optional<int> stun_keepalive_interval,
+      const webrtc::WebRtcKeyValueConfig* field_trials);
 
   void PrepareAddress() override;
 
@@ -282,7 +287,8 @@
            uint16_t max_port,
            const std::string& username,
            const std::string& password,
-           const ServerAddresses& servers);
+           const ServerAddresses& servers,
+           const webrtc::WebRtcKeyValueConfig* field_trials);
 };
 
 }  // namespace cricket
diff --git a/p2p/base/stun_port_unittest.cc b/p2p/base/stun_port_unittest.cc
index d483baf..609de9b 100644
--- a/p2p/base/stun_port_unittest.cc
+++ b/p2p/base/stun_port_unittest.cc
@@ -20,6 +20,7 @@
 #include "rtc_base/ssl_adapter.h"
 #include "rtc_base/virtual_socket_server.h"
 #include "test/gmock.h"
+#include "test/scoped_key_value_config.h"
 
 using cricket::ServerAddresses;
 using rtc::SocketAddress;
@@ -77,7 +78,7 @@
     stun_port_ = cricket::StunPort::Create(
         rtc::Thread::Current(), &socket_factory_, &network_, 0, 0,
         rtc::CreateRandomString(16), rtc::CreateRandomString(22), stun_servers,
-        absl::nullopt);
+        absl::nullopt, &field_trials_);
     stun_port_->set_stun_keepalive_delay(stun_keepalive_delay_);
     // If `stun_keepalive_lifetime_` is negative, let the stun port
     // choose its lifetime from the network type.
@@ -104,7 +105,7 @@
     stun_port_ = cricket::UDPPort::Create(
         rtc::Thread::Current(), &socket_factory_, &network_, socket_.get(),
         rtc::CreateRandomString(16), rtc::CreateRandomString(22), false,
-        absl::nullopt);
+        absl::nullopt, &field_trials_);
     ASSERT_TRUE(stun_port_ != NULL);
     ServerAddresses stun_servers;
     stun_servers.insert(server_addr);
@@ -175,6 +176,7 @@
 
  protected:
   cricket::IceCandidateErrorEvent error_event_;
+  webrtc::test::ScopedKeyValueConfig field_trials_;
 };
 
 class StunPortTestWithRealClock : public StunPortTestBase {};
diff --git a/p2p/base/tcp_port.cc b/p2p/base/tcp_port.cc
index 52f74e7..8278ef0 100644
--- a/p2p/base/tcp_port.cc
+++ b/p2p/base/tcp_port.cc
@@ -91,7 +91,8 @@
                  uint16_t max_port,
                  const std::string& username,
                  const std::string& password,
-                 bool allow_listen)
+                 bool allow_listen,
+                 const webrtc::WebRtcKeyValueConfig* field_trials)
     : Port(thread,
            LOCAL_PORT_TYPE,
            factory,
@@ -99,7 +100,8 @@
            min_port,
            max_port,
            username,
-           password),
+           password,
+           field_trials),
       allow_listen_(allow_listen),
       error_(0) {
   // TODO(mallinath) - Set preference value as per RFC 6544.
diff --git a/p2p/base/tcp_port.h b/p2p/base/tcp_port.h
index 0635ed9..80e9a83 100644
--- a/p2p/base/tcp_port.h
+++ b/p2p/base/tcp_port.h
@@ -34,18 +34,20 @@
 // call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
 class TCPPort : public Port {
  public:
-  static std::unique_ptr<TCPPort> Create(rtc::Thread* thread,
-                                         rtc::PacketSocketFactory* factory,
-                                         const rtc::Network* network,
-                                         uint16_t min_port,
-                                         uint16_t max_port,
-                                         const std::string& username,
-                                         const std::string& password,
-                                         bool allow_listen) {
+  static std::unique_ptr<TCPPort> Create(
+      rtc::Thread* thread,
+      rtc::PacketSocketFactory* factory,
+      const rtc::Network* network,
+      uint16_t min_port,
+      uint16_t max_port,
+      const std::string& username,
+      const std::string& password,
+      bool allow_listen,
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) {
     // Using `new` to access a non-public constructor.
     return absl::WrapUnique(new TCPPort(thread, factory, network, min_port,
                                         max_port, username, password,
-                                        allow_listen));
+                                        allow_listen, field_trials));
   }
   ~TCPPort() override;
 
@@ -71,7 +73,8 @@
           uint16_t max_port,
           const std::string& username,
           const std::string& password,
-          bool allow_listen);
+          bool allow_listen,
+          const webrtc::WebRtcKeyValueConfig* field_trials);
 
   // Handles sending using the local TCP socket.
   int SendTo(const void* data,
diff --git a/p2p/base/tcp_port_unittest.cc b/p2p/base/tcp_port_unittest.cc
index ce83c1d..8adf35c 100644
--- a/p2p/base/tcp_port_unittest.cc
+++ b/p2p/base/tcp_port_unittest.cc
@@ -25,6 +25,7 @@
 #include "rtc_base/time_utils.h"
 #include "rtc_base/virtual_socket_server.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 using cricket::Connection;
 using cricket::ICE_PWD_LENGTH;
@@ -82,12 +83,13 @@
   std::unique_ptr<TCPPort> CreateTCPPort(const SocketAddress& addr) {
     return std::unique_ptr<TCPPort>(
         TCPPort::Create(&main_, &socket_factory_, MakeNetwork(addr), 0, 0,
-                        username_, password_, true));
+                        username_, password_, true, &field_trials_));
   }
 
   std::unique_ptr<TCPPort> CreateTCPPort(const rtc::Network* network) {
-    return std::unique_ptr<TCPPort>(TCPPort::Create(
-        &main_, &socket_factory_, network, 0, 0, username_, password_, true));
+    return std::unique_ptr<TCPPort>(
+        TCPPort::Create(&main_, &socket_factory_, network, 0, 0, username_,
+                        password_, true, &field_trials_));
   }
 
  protected:
@@ -100,6 +102,7 @@
   rtc::BasicPacketSocketFactory socket_factory_;
   std::string username_;
   std::string password_;
+  webrtc::test::ScopedKeyValueConfig field_trials_;
 };
 
 TEST_F(TCPPortTest, TestTCPPortWithLocalhostAddress) {
diff --git a/p2p/base/turn_port.cc b/p2p/base/turn_port.cc
index 8320983..d984b6c 100644
--- a/p2p/base/turn_port.cc
+++ b/p2p/base/turn_port.cc
@@ -227,7 +227,13 @@
                    webrtc::TurnCustomizer* customizer,
                    rtc::SSLCertificateVerifier* tls_cert_verifier,
                    const webrtc::WebRtcKeyValueConfig* field_trials)
-    : Port(thread, RELAY_PORT_TYPE, factory, network, username, password),
+    : Port(thread,
+           RELAY_PORT_TYPE,
+           factory,
+           network,
+           username,
+           password,
+           field_trials),
       server_address_(server_address),
       tls_alpn_protocols_(tls_alpn_protocols),
       tls_elliptic_curves_(tls_elliptic_curves),
@@ -268,7 +274,8 @@
            min_port,
            max_port,
            username,
-           password),
+           password,
+           field_trials),
       server_address_(server_address),
       tls_alpn_protocols_(tls_alpn_protocols),
       tls_elliptic_curves_(tls_elliptic_curves),
diff --git a/p2p/base/turn_port_unittest.cc b/p2p/base/turn_port_unittest.cc
index eca0b58..8ca84b6 100644
--- a/p2p/base/turn_port_unittest.cc
+++ b/p2p/base/turn_port_unittest.cc
@@ -375,9 +375,9 @@
   void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }
 
   void CreateUdpPort(const SocketAddress& address) {
-    udp_port_ =
-        UDPPort::Create(&main_, &socket_factory_, MakeNetwork(address), 0, 0,
-                        kIceUfrag2, kIcePwd2, false, absl::nullopt);
+    udp_port_ = UDPPort::Create(&main_, &socket_factory_, MakeNetwork(address),
+                                0, 0, kIceUfrag2, kIcePwd2, false,
+                                absl::nullopt, &field_trials_);
     // UDP port will be controlled.
     udp_port_->SetIceRole(ICEROLE_CONTROLLED);
     udp_port_->SignalPortComplete.connect(this,
diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc
index 6535ba5..10d855c 100644
--- a/p2p/client/basic_port_allocator.cc
+++ b/p2p/client/basic_port_allocator.cc
@@ -756,11 +756,13 @@
       if (rtc::IPIsLinkLocal(network->GetBestIP())) {
         continue;
       }
-      lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost());
+      lowest_cost = std::min<uint16_t>(
+          lowest_cost, network->GetCost(*allocator()->field_trials()));
     }
     NetworkFilter costly_filter(
-        [lowest_cost](const rtc::Network* network) {
-          return network->GetCost() > lowest_cost + rtc::kNetworkCostLow;
+        [lowest_cost, this](const rtc::Network* network) {
+          return network->GetCost(*allocator()->field_trials()) >
+                 lowest_cost + rtc::kNetworkCostLow;
         },
         "costly");
     FilterNetworks(&networks, costly_filter);
@@ -1449,14 +1451,16 @@
         session_->network_thread(), session_->socket_factory(), network_,
         udp_socket_.get(), session_->username(), session_->password(),
         emit_local_candidate_for_anyaddress,
-        session_->allocator()->stun_candidate_keepalive_interval());
+        session_->allocator()->stun_candidate_keepalive_interval(),
+        session_->allocator()->field_trials());
   } else {
     port = UDPPort::Create(
         session_->network_thread(), session_->socket_factory(), network_,
         session_->allocator()->min_port(), session_->allocator()->max_port(),
         session_->username(), session_->password(),
         emit_local_candidate_for_anyaddress,
-        session_->allocator()->stun_candidate_keepalive_interval());
+        session_->allocator()->stun_candidate_keepalive_interval(),
+        session_->allocator()->field_trials());
   }
 
   if (port) {
@@ -1492,7 +1496,8 @@
       session_->network_thread(), session_->socket_factory(), network_,
       session_->allocator()->min_port(), session_->allocator()->max_port(),
       session_->username(), session_->password(),
-      session_->allocator()->allow_tcp_listen());
+      session_->allocator()->allow_tcp_listen(),
+      session_->allocator()->field_trials());
   if (port) {
     session_->AddAllocatedPort(port.release(), this);
     // Since TCPPort is not created using shared socket, `port` will not be
@@ -1520,7 +1525,8 @@
       session_->network_thread(), session_->socket_factory(), network_,
       session_->allocator()->min_port(), session_->allocator()->max_port(),
       session_->username(), session_->password(), config_->StunServers(),
-      session_->allocator()->stun_candidate_keepalive_interval());
+      session_->allocator()->stun_candidate_keepalive_interval(),
+      session_->allocator()->field_trials());
   if (port) {
     session_->AddAllocatedPort(port.release(), this);
     // Since StunPort is not created using shared socket, `port` will not be
diff --git a/pc/connection_context.cc b/pc/connection_context.cc
index 8583e7b..84a0dd3 100644
--- a/pc/connection_context.cc
+++ b/pc/connection_context.cc
@@ -146,7 +146,7 @@
   // If network_monitor_factory_ is non-null, it will be used to create a
   // network monitor while on the network thread.
   default_network_manager_ = std::make_unique<rtc::BasicNetworkManager>(
-      network_monitor_factory_.get(), socket_factory);
+      network_monitor_factory_.get(), socket_factory, &trials());
 
   default_socket_factory_ =
       std::make_unique<rtc::BasicPacketSocketFactory>(socket_factory);
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index e09b62f..4015fc9 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -947,9 +947,12 @@
     "../api:refcountedbase",
     "../api:scoped_refptr",
     "../api:sequence_checker",
+    "../api:webrtc_key_value_config",
     "../api/numerics",
     "../api/task_queue",
+    "../api/transport:field_trial_based_config",
     "../system_wrappers:field_trial",
+    "memory:always_valid_pointer",
     "network:sent_packet",
     "synchronization:mutex",
     "system:file_wrapper",
@@ -1230,6 +1233,8 @@
     ":threading",
     "../api/units:time_delta",
     "../api/units:timestamp",
+    "../test:scoped_key_value_config",
+    "memory:always_valid_pointer",
     "memory:fifo_buffer",
     "synchronization:mutex",
     "task_utils:to_queued_task",
@@ -1546,6 +1551,7 @@
         "../test:field_trial",
         "../test:fileutils",
         "../test:rtc_expect_death",
+        "../test:scoped_key_value_config",
         "../test:test_main",
         "../test:test_support",
         "memory:fifo_buffer",
diff --git a/rtc_base/memory/always_valid_pointer.h b/rtc_base/memory/always_valid_pointer.h
index 570ad93..c6e0a70 100644
--- a/rtc_base/memory/always_valid_pointer.h
+++ b/rtc_base/memory/always_valid_pointer.h
@@ -41,6 +41,10 @@
   Interface* operator->() { return pointer_; }
   Interface& operator*() { return *pointer_; }
 
+  Interface* get() const { return pointer_; }
+  Interface* operator->() const { return pointer_; }
+  Interface& operator*() const { return *pointer_; }
+
  private:
   const std::unique_ptr<Interface> owned_instance_;
   Interface* const pointer_;
diff --git a/rtc_base/nat_unittest.cc b/rtc_base/nat_unittest.cc
index af6256f..50feda9 100644
--- a/rtc_base/nat_unittest.cc
+++ b/rtc_base/nat_unittest.cc
@@ -37,6 +37,7 @@
 #include "rtc_base/thread.h"
 #include "rtc_base/virtual_socket_server.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 namespace rtc {
 namespace {
@@ -219,8 +220,9 @@
 }
 
 void TestPhysicalInternal(const SocketAddress& int_addr) {
+  webrtc::test::ScopedKeyValueConfig field_trials;
   PhysicalSocketServer socket_server;
-  BasicNetworkManager network_manager(nullptr, &socket_server);
+  BasicNetworkManager network_manager(nullptr, &socket_server, &field_trials);
   network_manager.StartUpdating();
   // Process pending messages so the network list is updated.
   Thread::Current()->ProcessMessages(0);
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index 5202630..b2bce37 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -29,8 +29,10 @@
 #include "absl/algorithm/container.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
+#include "api/transport/field_trial_based_config.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/memory/always_valid_pointer.h"
 #include "rtc_base/network_monitor.h"
 #include "rtc_base/socket.h"  // includes something that makes windows happy
 #include "rtc_base/string_encode.h"
@@ -38,7 +40,6 @@
 #include "rtc_base/strings/string_builder.h"
 #include "rtc_base/task_utils/to_queued_task.h"
 #include "rtc_base/thread.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace rtc {
 namespace {
@@ -280,10 +281,13 @@
   return nullptr;
 }
 
-NetworkManagerBase::NetworkManagerBase()
+NetworkManagerBase::NetworkManagerBase(
+    const webrtc::WebRtcKeyValueConfig* field_trials)
     : enumeration_permission_(NetworkManager::ENUMERATION_ALLOWED),
-      signal_network_preference_change_(webrtc::field_trial::IsEnabled(
-          "WebRTC-SignalNetworkPreferenceChange")) {}
+      signal_network_preference_change_(
+          field_trials
+              ? field_trials->IsEnabled("WebRTC-SignalNetworkPreferenceChange")
+              : false) {}
 
 NetworkManagerBase::~NetworkManagerBase() {
   for (const auto& kv : networks_map_) {
@@ -508,25 +512,17 @@
   return false;
 }
 
-BasicNetworkManager::BasicNetworkManager()
-    : BasicNetworkManager(nullptr, nullptr) {}
-
-BasicNetworkManager::BasicNetworkManager(SocketFactory* socket_factory)
-    : BasicNetworkManager(nullptr, socket_factory) {}
-
-BasicNetworkManager::BasicNetworkManager(
-    NetworkMonitorFactory* network_monitor_factory)
-    : BasicNetworkManager(network_monitor_factory, nullptr) {}
-
 BasicNetworkManager::BasicNetworkManager(
     NetworkMonitorFactory* network_monitor_factory,
-    SocketFactory* socket_factory)
-    : network_monitor_factory_(network_monitor_factory),
+    SocketFactory* socket_factory,
+    const webrtc::WebRtcKeyValueConfig* field_trials)
+    : field_trials_(field_trials),
+      network_monitor_factory_(network_monitor_factory),
       socket_factory_(socket_factory),
       allow_mac_based_ipv6_(
-          webrtc::field_trial::IsEnabled("WebRTC-AllowMACBasedIPv6")),
+          field_trials_->IsEnabled("WebRTC-AllowMACBasedIPv6")),
       bind_using_ifname_(
-          !webrtc::field_trial::IsDisabled("WebRTC-BindUsingInterfaceName")) {}
+          !field_trials_->IsDisabled("WebRTC-BindUsingInterfaceName")) {}
 
 BasicNetworkManager::~BasicNetworkManager() {
   if (task_safety_flag_) {
@@ -936,7 +932,8 @@
     return;
   }
   if (!network_monitor_) {
-    network_monitor_.reset(network_monitor_factory_->CreateNetworkMonitor());
+    network_monitor_.reset(
+        network_monitor_factory_->CreateNetworkMonitor(*field_trials_));
     if (!network_monitor_) {
       return;
     }
@@ -1060,24 +1057,6 @@
 Network::Network(absl::string_view name,
                  absl::string_view desc,
                  const IPAddress& prefix,
-                 int prefix_length)
-    : name_(name),
-      description_(desc),
-      prefix_(prefix),
-      prefix_length_(prefix_length),
-      key_(MakeNetworkKey(name, prefix, prefix_length)),
-      scope_id_(0),
-      ignored_(false),
-      type_(ADAPTER_TYPE_UNKNOWN),
-      preference_(0),
-      use_differentiated_cellular_costs_(webrtc::field_trial::IsEnabled(
-          "WebRTC-UseDifferentiatedCellularCosts")),
-      add_network_cost_to_vpn_(
-          webrtc::field_trial::IsEnabled("WebRTC-AddNetworkCostToVpn")) {}
-
-Network::Network(absl::string_view name,
-                 absl::string_view desc,
-                 const IPAddress& prefix,
                  int prefix_length,
                  AdapterType type)
     : name_(name),
@@ -1088,11 +1067,7 @@
       scope_id_(0),
       ignored_(false),
       type_(type),
-      preference_(0),
-      use_differentiated_cellular_costs_(webrtc::field_trial::IsEnabled(
-          "WebRTC-UseDifferentiatedCellularCosts")),
-      add_network_cost_to_vpn_(
-          webrtc::field_trial::IsEnabled("WebRTC-AddNetworkCostToVpn")) {}
+      preference_(0) {}
 
 Network::Network(const Network&) = default;
 
@@ -1162,11 +1137,23 @@
   return mdns_responder_provider_->GetMdnsResponder();
 }
 
-uint16_t Network::GetCost() const {
+uint16_t Network::GetCost(
+    const webrtc::WebRtcKeyValueConfig* field_trials) const {
+  return GetCost(
+      *webrtc::AlwaysValidPointer<const webrtc::WebRtcKeyValueConfig,
+                                  webrtc::FieldTrialBasedConfig>(field_trials));
+}
+
+uint16_t Network::GetCost(
+    const webrtc::WebRtcKeyValueConfig& field_trials) const {
   AdapterType type = IsVpn() ? underlying_type_for_vpn_ : type_;
+  const bool use_differentiated_cellular_costs =
+      field_trials.IsEnabled("WebRTC-UseDifferentiatedCellularCosts");
+  const bool add_network_cost_to_vpn =
+      field_trials.IsEnabled("WebRTC-AddNetworkCostToVpn");
   return ComputeNetworkCostByType(type, IsVpn(),
-                                  use_differentiated_cellular_costs_,
-                                  add_network_cost_to_vpn_);
+                                  use_differentiated_cellular_costs,
+                                  add_network_cost_to_vpn);
 }
 
 // This is the inverse of ComputeNetworkCostByType().
diff --git a/rtc_base/network.h b/rtc_base/network.h
index 063e255..d01a418 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -22,8 +22,11 @@
 #include "absl/strings/string_view.h"
 #include "api/array_view.h"
 #include "api/sequence_checker.h"
+#include "api/transport/field_trial_based_config.h"
+#include "api/webrtc_key_value_config.h"
 #include "rtc_base/ip_address.h"
 #include "rtc_base/mdns_responder_interface.h"
+#include "rtc_base/memory/always_valid_pointer.h"
 #include "rtc_base/network_monitor.h"
 #include "rtc_base/network_monitor_factory.h"
 #include "rtc_base/socket_factory.h"
@@ -205,7 +208,8 @@
 // Base class for NetworkManager implementations.
 class RTC_EXPORT NetworkManagerBase : public NetworkManager {
  public:
-  NetworkManagerBase();
+  NetworkManagerBase(
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr);
   ~NetworkManagerBase() override;
 
   void GetNetworks(NetworkList* networks) const override;
@@ -273,15 +277,28 @@
                                        public NetworkBinderInterface,
                                        public sigslot::has_slots<> {
  public:
+  // This version is used by chromium.
   ABSL_DEPRECATED(
       "Use the version with socket_factory, see bugs.webrtc.org/13145")
-  BasicNetworkManager();
-  explicit BasicNetworkManager(SocketFactory* socket_factory);
-  ABSL_DEPRECATED(
-      "Use the version with socket_factory, see bugs.webrtc.org/13145")
-  explicit BasicNetworkManager(NetworkMonitorFactory* network_monitor_factory);
-  BasicNetworkManager(NetworkMonitorFactory* network_monitor_factory,
-                      SocketFactory* socket_factory);
+  explicit BasicNetworkManager(
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr)
+      : BasicNetworkManager(
+            /* network_monitor_factory= */ nullptr,
+            /* socket_factory= */ nullptr,
+            field_trials) {}
+
+  // This is used by lots of downstream code.
+  BasicNetworkManager(
+      SocketFactory* socket_factory,
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr)
+      : BasicNetworkManager(/* network_monitor_factory= */ nullptr,
+                            socket_factory,
+                            field_trials) {}
+
+  BasicNetworkManager(
+      NetworkMonitorFactory* network_monitor_factory,
+      SocketFactory* socket_factory,
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr);
   ~BasicNetworkManager() override;
 
   void StartUpdating() override;
@@ -354,6 +371,10 @@
   Thread* thread_ = nullptr;
   bool sent_first_update_ = true;
   int start_count_ = 0;
+  // Chromium create BasicNetworkManager() w/o field trials.
+  webrtc::AlwaysValidPointer<const webrtc::WebRtcKeyValueConfig,
+                             webrtc::FieldTrialBasedConfig>
+      field_trials_;
   std::vector<std::string> network_ignore_list_;
   NetworkMonitorFactory* const network_monitor_factory_;
   SocketFactory* const socket_factory_;
@@ -372,13 +393,19 @@
   Network(absl::string_view name,
           absl::string_view description,
           const IPAddress& prefix,
-          int prefix_length);
+          int prefix_length)
+      : Network(name,
+                description,
+                prefix,
+                prefix_length,
+                rtc::ADAPTER_TYPE_UNKNOWN) {}
 
   Network(absl::string_view name,
           absl::string_view description,
           const IPAddress& prefix,
           int prefix_length,
           AdapterType type);
+
   Network(const Network&);
   ~Network();
 
@@ -515,7 +542,16 @@
     }
   }
 
-  uint16_t GetCost() const;
+  // Note: This function is called "rarely".
+  // Twice per Network in BasicPortAllocator if
+  // PORTALLOCATOR_DISABLE_COSTLY_NETWORKS. Once in Port::Construct() (and when
+  // Port::OnNetworkTypeChanged is called).
+  ABSL_DEPRECATED(
+      "Use the version with field trials, see bugs.webrtc.org/webrtc:10335")
+  uint16_t GetCost(
+      const webrtc::WebRtcKeyValueConfig* field_trials = nullptr) const;
+  uint16_t GetCost(const webrtc::WebRtcKeyValueConfig& field_trials) const;
+
   // A unique id assigned by the network manager, which may be signaled
   // to the remote side in the candidate.
   uint16_t id() const { return id_; }
@@ -567,8 +603,6 @@
   int preference_;
   bool active_ = true;
   uint16_t id_ = 0;
-  bool use_differentiated_cellular_costs_ = false;
-  bool add_network_cost_to_vpn_ = false;
   NetworkPreference network_preference_ = NetworkPreference::NEUTRAL;
 
   friend class NetworkManager;
diff --git a/rtc_base/network_monitor_factory.h b/rtc_base/network_monitor_factory.h
index dadcd4a..b261ace 100644
--- a/rtc_base/network_monitor_factory.h
+++ b/rtc_base/network_monitor_factory.h
@@ -11,6 +11,10 @@
 #ifndef RTC_BASE_NETWORK_MONITOR_FACTORY_H_
 #define RTC_BASE_NETWORK_MONITOR_FACTORY_H_
 
+namespace webrtc {
+class WebRtcKeyValueConfig;
+}  // namespace webrtc
+
 namespace rtc {
 
 // Forward declaring this so it's not part of the API surface; it's only
@@ -24,7 +28,8 @@
  */
 class NetworkMonitorFactory {
  public:
-  virtual NetworkMonitorInterface* CreateNetworkMonitor() = 0;
+  virtual NetworkMonitorInterface* CreateNetworkMonitor(
+      const webrtc::WebRtcKeyValueConfig& field_trials) = 0;
 
   virtual ~NetworkMonitorFactory();
 
diff --git a/rtc_base/network_unittest.cc b/rtc_base/network_unittest.cc
index 0b5f3e9..5830793 100644
--- a/rtc_base/network_unittest.cc
+++ b/rtc_base/network_unittest.cc
@@ -36,6 +36,7 @@
 #include "rtc_base/logging.h"  // For RTC_LOG_GLE
 #endif
 #include "test/field_trial.h"
+#include "test/scoped_key_value_config.h"
 
 using ::testing::Contains;
 using ::testing::Not;
@@ -121,7 +122,8 @@
 class FakeNetworkMonitorFactory : public NetworkMonitorFactory {
  public:
   FakeNetworkMonitorFactory() {}
-  NetworkMonitorInterface* CreateNetworkMonitor() override {
+  NetworkMonitorInterface* CreateNetworkMonitor(
+      const webrtc::WebRtcKeyValueConfig& field_trials) override {
     return new FakeNetworkMonitor();
   }
 };
@@ -309,14 +311,18 @@
 #endif  // defined(WEBRTC_POSIX)
 
  protected:
+  webrtc::test::ScopedKeyValueConfig field_trials_;
   bool callback_called_;
 };
 
 class TestBasicNetworkManager : public BasicNetworkManager {
  public:
   TestBasicNetworkManager(NetworkMonitorFactory* network_monitor_factory,
-                          SocketFactory* socket_factory)
-      : BasicNetworkManager(network_monitor_factory, socket_factory) {}
+                          SocketFactory* socket_factory,
+                          const webrtc::WebRtcKeyValueConfig& field_trials)
+      : BasicNetworkManager(network_monitor_factory,
+                            socket_factory,
+                            &field_trials) {}
   using BasicNetworkManager::QueryDefaultLocalAddress;
   using BasicNetworkManager::set_default_local_addresses;
 };
@@ -404,7 +410,7 @@
 // ALLOWED.
 TEST_F(NetworkTest, TestUpdateNetworks) {
   PhysicalSocketServer socket_server;
-  BasicNetworkManager manager(nullptr, &socket_server);
+  BasicNetworkManager manager(nullptr, &socket_server, &field_trials_);
   manager.SignalNetworksChanged.connect(static_cast<NetworkTest*>(this),
                                         &NetworkTest::OnNetworksChanged);
   EXPECT_EQ(NetworkManager::ENUMERATION_ALLOWED,
@@ -798,7 +804,7 @@
 // to be preference-ordered by name. For example, "eth0" before "eth1".
 TEST_F(NetworkTest, NetworksSortedByInterfaceName) {
   PhysicalSocketServer socket_server;
-  BasicNetworkManager manager(&socket_server);
+  BasicNetworkManager manager(&socket_server, &field_trials_);
   Network* eth0 = new Network("test_eth0", "Test Network Adapter 1",
                               IPAddress(0x65432100U), 24);
   eth0->AddIP(IPAddress(0x65432100U));
@@ -896,7 +902,8 @@
   std::string ipv6_address = "1000:2000:3000:4000:0:0:0:1";
   std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF::";
   PhysicalSocketServer socket_server;
-  BasicNetworkManager manager_without_monitor(nullptr, &socket_server);
+  BasicNetworkManager manager_without_monitor(nullptr, &socket_server,
+                                              &field_trials_);
   manager_without_monitor.StartUpdating();
   // A network created without a network monitor will get UNKNOWN type.
   ifaddrs* addr_list = InstallIpv6Network(if_name, ipv6_address, ipv6_mask,
@@ -906,7 +913,8 @@
 
   // With the fake network monitor the type should be correctly determined.
   FakeNetworkMonitorFactory factory;
-  BasicNetworkManager manager_with_monitor(&factory, &socket_server);
+  BasicNetworkManager manager_with_monitor(&factory, &socket_server,
+                                           &field_trials_);
   manager_with_monitor.StartUpdating();
   // Add the same ipv6 address as before but it has the right network type
   // detected by the network monitor now.
@@ -1004,7 +1012,7 @@
   // Sanity check that both interfaces are included by default.
   FakeNetworkMonitorFactory factory;
   PhysicalSocketServer socket_server;
-  BasicNetworkManager manager(&factory, &socket_server);
+  BasicNetworkManager manager(&factory, &socket_server, &field_trials_);
   manager.StartUpdating();
   CallConvertIfAddrs(manager, list, /*include_ignored=*/false, &result);
   EXPECT_EQ(2u, result.size());
@@ -1151,7 +1159,7 @@
 TEST_F(NetworkTest, TestNetworkMonitoring) {
   FakeNetworkMonitorFactory factory;
   PhysicalSocketServer socket_server;
-  BasicNetworkManager manager(&factory, &socket_server);
+  BasicNetworkManager manager(&factory, &socket_server, &field_trials_);
   manager.SignalNetworksChanged.connect(static_cast<NetworkTest*>(this),
                                         &NetworkTest::OnNetworksChanged);
   manager.StartUpdating();
@@ -1182,7 +1190,7 @@
   IPAddress ip;
   FakeNetworkMonitorFactory factory;
   PhysicalSocketServer socket_server;
-  TestBasicNetworkManager manager(&factory, &socket_server);
+  TestBasicNetworkManager manager(&factory, &socket_server, field_trials_);
   manager.SignalNetworksChanged.connect(static_cast<NetworkTest*>(this),
                                         &NetworkTest::OnNetworksChanged);
   manager.StartUpdating();
@@ -1358,7 +1366,7 @@
   // Sanity check that both interfaces are included by default.
   FakeNetworkMonitorFactory factory;
   PhysicalSocketServer socket_server;
-  BasicNetworkManager manager(&factory, &socket_server);
+  BasicNetworkManager manager(&factory, &socket_server, &field_trials_);
   manager.StartUpdating();
   CallConvertIfAddrs(manager, list, /*include_ignored=*/false, &result);
   EXPECT_EQ(2u, result.size());
@@ -1390,6 +1398,7 @@
 TEST_F(NetworkTest, NetworkCostVpn_Default) {
   IPAddress ip1;
   EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));
+  webrtc::test::ScopedKeyValueConfig field_trials;
 
   Network* net1 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
   net1->set_type(ADAPTER_TYPE_VPN);
@@ -1398,13 +1407,13 @@
   Network* net2 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
   net2->set_type(ADAPTER_TYPE_ETHERNET);
 
-  EXPECT_EQ(net1->GetCost(), net2->GetCost());
+  EXPECT_EQ(net1->GetCost(field_trials), net2->GetCost(field_trials));
   delete net1;
   delete net2;
 }
 
 TEST_F(NetworkTest, NetworkCostVpn_VpnMoreExpensive) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-AddNetworkCostToVpn/Enabled/");
 
   IPAddress ip1;
@@ -1417,13 +1426,13 @@
   Network* net2 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
   net2->set_type(ADAPTER_TYPE_ETHERNET);
 
-  EXPECT_GT(net1->GetCost(), net2->GetCost());
+  EXPECT_GT(net1->GetCost(field_trials), net2->GetCost(field_trials));
   delete net1;
   delete net2;
 }
 
 TEST_F(NetworkTest, GuessAdapterFromNetworkCost) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-AddNetworkCostToVpn/Enabled/"
       "WebRTC-UseDifferentiatedCellularCosts/Enabled/");
 
@@ -1435,7 +1444,8 @@
       continue;
     Network net1("em1", "em1", TruncateIP(ip1, 64), 64);
     net1.set_type(type);
-    auto [guess, vpn] = Network::GuessAdapterFromNetworkCost(net1.GetCost());
+    auto [guess, vpn] =
+        Network::GuessAdapterFromNetworkCost(net1.GetCost(field_trials));
     EXPECT_FALSE(vpn);
     if (type == rtc::ADAPTER_TYPE_LOOPBACK) {
       EXPECT_EQ(guess, rtc::ADAPTER_TYPE_ETHERNET);
@@ -1451,7 +1461,8 @@
     Network net1("em1", "em1", TruncateIP(ip1, 64), 64);
     net1.set_type(rtc::ADAPTER_TYPE_VPN);
     net1.set_underlying_type_for_vpn(type);
-    auto [guess, vpn] = Network::GuessAdapterFromNetworkCost(net1.GetCost());
+    auto [guess, vpn] =
+        Network::GuessAdapterFromNetworkCost(net1.GetCost(field_trials));
     EXPECT_TRUE(vpn);
     if (type == rtc::ADAPTER_TYPE_LOOPBACK) {
       EXPECT_EQ(guess, rtc::ADAPTER_TYPE_ETHERNET);
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index c95b128..42db69b 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -1585,6 +1585,7 @@
           ":network_monitor_objc",
           ":network_monitor_observer",
           "../api:sequence_checker",
+          "../api:webrtc_key_value_config",
           "../rtc_base",
           "../rtc_base:threading",
           "../rtc_base/task_utils:pending_task_safety_flag",
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index 2561597..34264c2 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -582,6 +582,7 @@
       "../../api:libjingle_peerconnection_api",
       "../../api:scoped_refptr",
       "../../api:sequence_checker",
+      "../../api:webrtc_key_value_config",
       "../../rtc_base",
       "../../rtc_base:checks",
       "../../rtc_base:ip_address",
diff --git a/sdk/android/src/jni/android_network_monitor.cc b/sdk/android/src/jni/android_network_monitor.cc
index e6f2357..ecf0adf 100644
--- a/sdk/android/src/jni/android_network_monitor.cc
+++ b/sdk/android/src/jni/android_network_monitor.cc
@@ -577,7 +577,8 @@
 AndroidNetworkMonitorFactory::~AndroidNetworkMonitorFactory() = default;
 
 rtc::NetworkMonitorInterface*
-AndroidNetworkMonitorFactory::CreateNetworkMonitor() {
+AndroidNetworkMonitorFactory::CreateNetworkMonitor(
+    const WebRtcKeyValueConfig& field_trials) {
   return new AndroidNetworkMonitor(AttachCurrentThreadIfNeeded(),
                                    j_application_context_);
 }
diff --git a/sdk/android/src/jni/android_network_monitor.h b/sdk/android/src/jni/android_network_monitor.h
index dbf51c2..dfdb18f 100644
--- a/sdk/android/src/jni/android_network_monitor.h
+++ b/sdk/android/src/jni/android_network_monitor.h
@@ -19,6 +19,7 @@
 
 #include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
+#include "api/webrtc_key_value_config.h"
 #include "rtc_base/network_monitor.h"
 #include "rtc_base/network_monitor_factory.h"
 #include "rtc_base/string_utils.h"
@@ -165,7 +166,8 @@
 
   ~AndroidNetworkMonitorFactory() override;
 
-  rtc::NetworkMonitorInterface* CreateNetworkMonitor() override;
+  rtc::NetworkMonitorInterface* CreateNetworkMonitor(
+      const WebRtcKeyValueConfig& field_trials) override;
 
  private:
   ScopedJavaGlobalRef<jobject> j_application_context_;
diff --git a/sdk/objc/native/src/objc_network_monitor.h b/sdk/objc/native/src/objc_network_monitor.h
index 05752e1..7375bbb 100644
--- a/sdk/objc/native/src/objc_network_monitor.h
+++ b/sdk/objc/native/src/objc_network_monitor.h
@@ -15,6 +15,7 @@
 
 #include "absl/strings/string_view.h"
 #include "api/sequence_checker.h"
+#include "api/webrtc_key_value_config.h"
 #include "rtc_base/network_monitor.h"
 #include "rtc_base/network_monitor_factory.h"
 #include "rtc_base/string_utils.h"
@@ -31,7 +32,8 @@
   ObjCNetworkMonitorFactory() = default;
   ~ObjCNetworkMonitorFactory() override = default;
 
-  rtc::NetworkMonitorInterface* CreateNetworkMonitor() override;
+  rtc::NetworkMonitorInterface* CreateNetworkMonitor(
+      const WebRtcKeyValueConfig& field_trials) override;
 };
 
 class ObjCNetworkMonitor : public rtc::NetworkMonitorInterface,
diff --git a/sdk/objc/native/src/objc_network_monitor.mm b/sdk/objc/native/src/objc_network_monitor.mm
index 1790798..798d7ff 100644
--- a/sdk/objc/native/src/objc_network_monitor.mm
+++ b/sdk/objc/native/src/objc_network_monitor.mm
@@ -20,7 +20,8 @@
 
 namespace webrtc {
 
-rtc::NetworkMonitorInterface* ObjCNetworkMonitorFactory::CreateNetworkMonitor() {
+rtc::NetworkMonitorInterface* ObjCNetworkMonitorFactory::CreateNetworkMonitor(
+    const WebRtcKeyValueConfig& field_trials) {
   return new ObjCNetworkMonitor();
 }
 
diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn
index 4113978..6b53315 100644
--- a/test/network/BUILD.gn
+++ b/test/network/BUILD.gn
@@ -45,6 +45,7 @@
     "../../api:sequence_checker",
     "../../api:simulated_network_api",
     "../../api:time_controller",
+    "../../api:webrtc_key_value_config",
     "../../api/numerics",
     "../../api/test/network_emulation",
     "../../api/transport:stun_types",
@@ -67,11 +68,13 @@
     "../../rtc_base:stringutils",
     "../../rtc_base:task_queue_for_test",
     "../../rtc_base:threading",
+    "../../rtc_base/memory:always_valid_pointer",
     "../../rtc_base/synchronization:mutex",
     "../../rtc_base/task_utils:pending_task_safety_flag",
     "../../rtc_base/task_utils:repeating_task",
     "../../rtc_base/task_utils:to_queued_task",
     "../../system_wrappers",
+    "../../test:scoped_key_value_config",
     "../scenario:column_printer",
     "../time_controller",
   ]