Change internal candidate type to enum

Bug: webrtc:15846
Change-Id: I66480cd2a239655a897af5ed2625959e8d6cc33a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338644
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41802}
diff --git a/api/candidate.cc b/api/candidate.cc
index 06b3156..930b874 100644
--- a/api/candidate.cc
+++ b/api/candidate.cc
@@ -18,6 +18,23 @@
 #include "rtc_base/logging.h"
 #include "rtc_base/strings/string_builder.h"
 
+using webrtc::IceCandidateType;
+
+namespace webrtc {
+absl::string_view IceCandidateTypeToString(IceCandidateType type) {
+  switch (type) {
+    case IceCandidateType::kHost:
+      return "host";
+    case IceCandidateType::kSrflx:
+      return "srflx";
+    case IceCandidateType::kPrflx:
+      return "prflx";
+    case IceCandidateType::kRelay:
+      return "relay";
+  }
+}
+}  // namespace webrtc
+
 namespace cricket {
 
 ABSL_CONST_INIT const absl::string_view LOCAL_PORT_TYPE = "local";
@@ -25,11 +42,25 @@
 ABSL_CONST_INIT const absl::string_view PRFLX_PORT_TYPE = "prflx";
 ABSL_CONST_INIT const absl::string_view RELAY_PORT_TYPE = "relay";
 
+namespace {
+IceCandidateType CandidateTypeFromString(absl::string_view type) {
+  if (type == LOCAL_PORT_TYPE) {
+    return IceCandidateType::kHost;
+  } else if (type == STUN_PORT_TYPE) {
+    return IceCandidateType::kSrflx;
+  } else if (type == PRFLX_PORT_TYPE) {
+    return IceCandidateType::kPrflx;
+  } else {
+    RTC_DCHECK_EQ(type, RELAY_PORT_TYPE);
+    return IceCandidateType::kRelay;
+  }
+}
+}  // namespace
+
 Candidate::Candidate()
     : id_(rtc::CreateRandomString(8)),
       component_(ICE_CANDIDATE_COMPONENT_DEFAULT),
       priority_(0),
-      type_(LOCAL_PORT_TYPE),
       network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
       underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
       generation_(0),
@@ -42,11 +73,11 @@
                      uint32_t priority,
                      absl::string_view username,
                      absl::string_view password,
-                     absl::string_view type,
+                     webrtc::IceCandidateType type,
                      uint32_t generation,
                      absl::string_view foundation,
-                     uint16_t network_id,
-                     uint16_t network_cost)
+                     uint16_t network_id /*= 0*/,
+                     uint16_t network_cost /*= 0*/)
     : id_(rtc::CreateRandomString(8)),
       component_(component),
       protocol_(protocol),
@@ -62,6 +93,29 @@
       network_id_(network_id),
       network_cost_(network_cost) {}
 
+Candidate::Candidate(int component,
+                     absl::string_view protocol,
+                     const rtc::SocketAddress& address,
+                     uint32_t priority,
+                     absl::string_view username,
+                     absl::string_view password,
+                     absl::string_view type,
+                     uint32_t generation,
+                     absl::string_view foundation,
+                     uint16_t network_id,
+                     uint16_t network_cost)
+    : Candidate(component,
+                protocol,
+                address,
+                priority,
+                username,
+                password,
+                CandidateTypeFromString(type),
+                generation,
+                foundation,
+                network_id,
+                network_cost) {}
+
 Candidate::Candidate(const Candidate&) = default;
 
 Candidate::~Candidate() = default;
@@ -70,28 +124,25 @@
   id_ = rtc::CreateRandomString(8);
 }
 
+void Candidate::set_type(absl::string_view type ABSL_ATTRIBUTE_LIFETIME_BOUND) {
+  set_type(CandidateTypeFromString(type));
+}
+
 bool Candidate::is_local() const {
-  return type_ == LOCAL_PORT_TYPE;
+  return type_ == IceCandidateType::kHost;
 }
 bool Candidate::is_stun() const {
-  return type_ == STUN_PORT_TYPE;
+  return type_ == IceCandidateType::kSrflx;
 }
 bool Candidate::is_prflx() const {
-  return type_ == PRFLX_PORT_TYPE;
+  return type_ == IceCandidateType::kPrflx;
 }
 bool Candidate::is_relay() const {
-  return type_ == RELAY_PORT_TYPE;
+  return type_ == IceCandidateType::kRelay;
 }
 
 absl::string_view Candidate::type_name() const {
-  // The LOCAL_PORT_TYPE and STUN_PORT_TYPE constants are not the standard type
-  // names, so check for those specifically. For other types, `type_` will have
-  // the correct name.
-  if (is_local())
-    return "host";
-  if (is_stun())
-    return "srflx";
-  return type_;
+  return webrtc::IceCandidateTypeToString(type_);
 }
 
 bool Candidate::IsEquivalent(const Candidate& c) const {
@@ -229,7 +280,7 @@
   // transport protocols are different.
 
   rtc::StringBuilder sb;
-  sb << type_ << base_address.ipaddr().ToString() << protocol_
+  sb << type_name() << base_address.ipaddr().ToString() << protocol_
      << relay_protocol_;
 
   // https://www.rfc-editor.org/rfc/rfc5245#section-5.2
diff --git a/api/candidate.h b/api/candidate.h
index 77774ed..9535962 100644
--- a/api/candidate.h
+++ b/api/candidate.h
@@ -26,6 +26,7 @@
 
 namespace webrtc {
 enum class IceCandidateType : int { kHost, kSrflx, kPrflx, kRelay };
+RTC_EXPORT absl::string_view IceCandidateTypeToString(IceCandidateType);
 }  // namespace webrtc
 
 namespace cricket {
@@ -42,13 +43,21 @@
 static constexpr size_t kMaxTurnServers = 32;
 
 // Candidate for ICE based connection discovery.
-// TODO(phoglund): remove things in here that are not needed in the public API.
-
 class RTC_EXPORT Candidate {
  public:
   Candidate();
-  // TODO(pthatcher): Match the ordering and param list as per RFC 5245
-  // candidate-attribute syntax. http://tools.ietf.org/html/rfc5245#section-15.1
+  Candidate(int component,
+            absl::string_view protocol,
+            const rtc::SocketAddress& address,
+            uint32_t priority,
+            absl::string_view username,
+            absl::string_view password,
+            webrtc::IceCandidateType type,
+            uint32_t generation,
+            absl::string_view foundation,
+            uint16_t network_id = 0,
+            uint16_t network_cost = 0);
+  // TODO(tommi): Deprecate.
   Candidate(int component,
             absl::string_view protocol,
             const rtc::SocketAddress& address,
@@ -103,7 +112,7 @@
   const std::string& password() const { return password_; }
   void set_password(absl::string_view password) { Assign(password_, password); }
 
-  const std::string& type() const { return type_; }
+  webrtc::IceCandidateType type() const { return type_; }
 
   // Returns the name of the candidate type as specified in
   // https://datatracker.ietf.org/doc/html/rfc5245#section-15.1
@@ -113,13 +122,14 @@
   // cricket::LOCAL_PORT_TYPE). The type should really be an enum rather than a
   // string, but until we make that change the lifetime attribute helps us lock
   // things down. See also the `Port` class.
-  void set_type(absl::string_view type ABSL_ATTRIBUTE_LIFETIME_BOUND) {
-    Assign(type_, type);
-  }
+  void set_type(webrtc::IceCandidateType type) { type_ = type; }
 
-  // Provide these simple checkers to abstract away dependency on the port types
-  // that are currently defined outside of Candidate. This will ease the change
-  // from the string type to an enum.
+  // TODO(tommi): Deprecate.
+  void set_type(absl::string_view type ABSL_ATTRIBUTE_LIFETIME_BOUND);
+
+  // Simple checkers for checking the candidate type without dependency on the
+  // IceCandidateType enum. The `is_local()` and `is_stun()` names are legacy
+  // names and should now more accurately be `is_host()` and `is_srflx()`.
   bool is_local() const;
   bool is_stun() const;
   bool is_prflx() const;
@@ -271,7 +281,7 @@
   uint32_t priority_;
   std::string username_;
   std::string password_;
-  std::string type_;
+  webrtc::IceCandidateType type_ = webrtc::IceCandidateType::kHost;
   std::string network_name_;
   rtc::AdapterType network_type_;
   rtc::AdapterType underlying_type_for_vpn_;
diff --git a/api/candidate_unittest.cc b/api/candidate_unittest.cc
index a74afdc..4743610 100644
--- a/api/candidate_unittest.cc
+++ b/api/candidate_unittest.cc
@@ -15,6 +15,8 @@
 #include "p2p/base/p2p_constants.h"
 #include "rtc_base/gunit.h"
 
+using webrtc::IceCandidateType;
+
 namespace cricket {
 
 TEST(CandidateTest, Id) {
@@ -38,19 +40,19 @@
   Candidate c;
   // The `type_name()` property defaults to "host".
   EXPECT_EQ(c.type_name(), "host");
-  EXPECT_EQ(c.type(), LOCAL_PORT_TYPE);
+  EXPECT_EQ(c.type(), IceCandidateType::kHost);
 
-  c.set_type(STUN_PORT_TYPE);
+  c.set_type(IceCandidateType::kSrflx);
   EXPECT_EQ(c.type_name(), "srflx");
-  EXPECT_EQ(c.type(), STUN_PORT_TYPE);
+  EXPECT_EQ(c.type(), IceCandidateType::kSrflx);
 
-  c.set_type(PRFLX_PORT_TYPE);
+  c.set_type(IceCandidateType::kPrflx);
   EXPECT_EQ(c.type_name(), "prflx");
-  EXPECT_EQ(c.type(), PRFLX_PORT_TYPE);
+  EXPECT_EQ(c.type(), IceCandidateType::kPrflx);
 
-  c.set_type(RELAY_PORT_TYPE);
+  c.set_type(IceCandidateType::kRelay);
   EXPECT_EQ(c.type_name(), "relay");
-  EXPECT_EQ(c.type(), RELAY_PORT_TYPE);
+  EXPECT_EQ(c.type(), IceCandidateType::kRelay);
 }
 
 TEST(CandidateTest, Foundation) {
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index e3ac48c..bd6f0bdb 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -45,7 +45,25 @@
 #include "rtc_base/trace_event.h"
 #include "system_wrappers/include/metrics.h"
 
+namespace cricket {
 namespace {
+using ::webrtc::IceCandidateType;
+using ::webrtc::RTCError;
+using ::webrtc::RTCErrorType;
+using ::webrtc::SafeTask;
+using ::webrtc::TimeDelta;
+
+IceCandidateType PortTypeToIceCandidateType(PortInterface* port) {
+  auto type = port->Type();
+  if (type == LOCAL_PORT_TYPE)
+    return IceCandidateType::kHost;
+  if (type == STUN_PORT_TYPE)
+    return IceCandidateType::kSrflx;
+  if (type == PRFLX_PORT_TYPE)
+    return IceCandidateType::kPrflx;
+  RTC_DCHECK_EQ(type, RELAY_PORT_TYPE);
+  return IceCandidateType::kRelay;
+}
 
 cricket::PortInterface::CandidateOrigin GetOrigin(
     cricket::PortInterface* port,
@@ -91,15 +109,8 @@
                             uses_turn);
 }
 
-using ::webrtc::RTCError;
-using ::webrtc::RTCErrorType;
-using ::webrtc::SafeTask;
-using ::webrtc::TimeDelta;
-
 }  // unnamed namespace
 
-namespace cricket {
-
 bool IceCredentialsChanged(absl::string_view old_ufrag,
                            absl::string_view old_pwd,
                            absl::string_view new_ufrag,
@@ -1411,8 +1422,10 @@
   }
 
   if (ice_field_trials_.skip_relay_to_non_relay_connections) {
-    if ((port->Type() != remote_candidate.type()) &&
-        (port->Type() == RELAY_PORT_TYPE || remote_candidate.is_relay())) {
+    IceCandidateType port_type = PortTypeToIceCandidateType(port);
+    if ((port_type != remote_candidate.type()) &&
+        (port_type == IceCandidateType::kRelay ||
+         remote_candidate.is_relay())) {
       RTC_LOG(LS_INFO) << ToString() << ": skip creating connection "
                        << port->Type() << " to "
                        << remote_candidate.type_name();
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index b180ab8..3109088 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -73,6 +73,7 @@
 using ::testing::SizeIs;
 using ::testing::Values;
 using ::testing::WithParamInterface;
+using ::webrtc::IceCandidateType;
 using ::webrtc::PendingTaskSafetyFlag;
 using ::webrtc::SafeTask;
 
@@ -321,9 +322,9 @@
   };
 
   struct Result {
-    Result(absl::string_view controlling_type,
+    Result(IceCandidateType controlling_type,
            absl::string_view controlling_protocol,
-           absl::string_view controlled_type,
+           IceCandidateType controlled_type,
            absl::string_view controlled_protocol,
            int wait)
         : controlling_type(controlling_type),
@@ -333,10 +334,10 @@
           connect_wait(wait) {}
 
     // The expected candidate type and protocol of the controlling ICE agent.
-    std::string controlling_type;
+    IceCandidateType controlling_type;
     std::string controlling_protocol;
     // The expected candidate type and protocol of the controlled ICE agent.
-    std::string controlled_type;
+    IceCandidateType controlled_type;
     std::string controlled_protocol;
     // How long to wait before the correct candidate pair is selected.
     int connect_wait;
@@ -1025,87 +1026,87 @@
 
 // The tests have only a few outcomes, which we predefine.
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
+    P2PTransportChannelTestBase::kLocalUdpToLocalUdp(IceCandidateType::kHost,
                                                      "udp",
-                                                     "local",
+                                                     IceCandidateType::kHost,
                                                      "udp",
                                                      1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
+    P2PTransportChannelTestBase::kLocalUdpToStunUdp(IceCandidateType::kHost,
                                                     "udp",
-                                                    "stun",
+                                                    IceCandidateType::kSrflx,
                                                     "udp",
                                                     1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
+    P2PTransportChannelTestBase::kLocalUdpToPrflxUdp(IceCandidateType::kHost,
                                                      "udp",
-                                                     "prflx",
+                                                     IceCandidateType::kPrflx,
                                                      "udp",
                                                      1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
+    P2PTransportChannelTestBase::kPrflxUdpToLocalUdp(IceCandidateType::kPrflx,
                                                      "udp",
-                                                     "local",
+                                                     IceCandidateType::kHost,
                                                      "udp",
                                                      1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
+    P2PTransportChannelTestBase::kStunUdpToLocalUdp(IceCandidateType::kSrflx,
                                                     "udp",
-                                                    "local",
+                                                    IceCandidateType::kHost,
                                                     "udp",
                                                     1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
+    P2PTransportChannelTestBase::kStunUdpToStunUdp(IceCandidateType::kSrflx,
                                                    "udp",
-                                                   "stun",
+                                                   IceCandidateType::kSrflx,
                                                    "udp",
                                                    1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
+    P2PTransportChannelTestBase::kStunUdpToPrflxUdp(IceCandidateType::kSrflx,
                                                     "udp",
-                                                    "prflx",
+                                                    IceCandidateType::kPrflx,
                                                     "udp",
                                                     1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
+    P2PTransportChannelTestBase::kPrflxUdpToStunUdp(IceCandidateType::kPrflx,
                                                     "udp",
-                                                    "stun",
+                                                    IceCandidateType::kSrflx,
                                                     "udp",
                                                     1000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
+    P2PTransportChannelTestBase::kLocalUdpToRelayUdp(IceCandidateType::kHost,
                                                      "udp",
-                                                     "relay",
+                                                     IceCandidateType::kRelay,
                                                      "udp",
                                                      2000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
+    P2PTransportChannelTestBase::kPrflxUdpToRelayUdp(IceCandidateType::kPrflx,
                                                      "udp",
-                                                     "relay",
+                                                     IceCandidateType::kRelay,
                                                      "udp",
                                                      2000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
+    P2PTransportChannelTestBase::kRelayUdpToPrflxUdp(IceCandidateType::kRelay,
                                                      "udp",
-                                                     "prflx",
+                                                     IceCandidateType::kPrflx,
                                                      "udp",
                                                      2000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
+    P2PTransportChannelTestBase::kLocalTcpToLocalTcp(IceCandidateType::kHost,
                                                      "tcp",
-                                                     "local",
+                                                     IceCandidateType::kHost,
                                                      "tcp",
                                                      3000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
+    P2PTransportChannelTestBase::kLocalTcpToPrflxTcp(IceCandidateType::kHost,
                                                      "tcp",
-                                                     "prflx",
+                                                     IceCandidateType::kPrflx,
                                                      "tcp",
                                                      3000);
 const P2PTransportChannelTestBase::Result
-    P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
+    P2PTransportChannelTestBase::kPrflxTcpToLocalTcp(IceCandidateType::kPrflx,
                                                      "tcp",
-                                                     "local",
+                                                     IceCandidateType::kHost,
                                                      "tcp",
                                                      3000);
 
@@ -1788,8 +1789,8 @@
   fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
                           kPublicAddrs[0].ipaddr()});
   CreateChannels();
-  // Expect a "prflx" candidate on the side that can only make outgoing
-  // connections, endpoint 0.
+  // Expect a IceCandidateType::kPrflx candidate on the side that can only make
+  // outgoing connections, endpoint 0.
   Test(kPrflxTcpToLocalTcp);
   DestroyChannels();
 }
@@ -2393,8 +2394,8 @@
 
 TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
   ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
-  Test(
-      P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
+  Test(P2PTransportChannelTestBase::Result(
+      IceCandidateType::kPrflx, "udp", IceCandidateType::kSrflx, "udp", 1000));
 }
 
 // Test what happens when we have multiple available pathways.
@@ -4959,8 +4960,8 @@
   // types and, for relay local candidate, the expected relay protocol and ping
   // it.
   void VerifyNextPingableConnection(
-      absl::string_view local_candidate_type,
-      absl::string_view remote_candidate_type,
+      IceCandidateType local_candidate_type,
+      IceCandidateType remote_candidate_type,
       absl::string_view relay_protocol_type = UDP_PROTOCOL_NAME) {
     Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
     ASSERT_TRUE(conn != nullptr);
@@ -5053,22 +5054,27 @@
   EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
 
   // Initially, only have Local/Local and Local/Relay.
-  VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kHost,
+                               IceCandidateType::kHost);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kHost);
 
   // Remote Relay candidate arrives.
   ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
   EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
 
   // Relay/Relay should be the first since it hasn't been pinged before.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kRelay);
 
   // Local/Relay is the final one.
-  VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kHost,
+                               IceCandidateType::kRelay);
 
   // Now, every connection has been pinged once. The next one should be
   // Relay/Relay.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kRelay);
 }
 
 // Test that when we receive a new remote candidate, they will be tried first
@@ -5084,24 +5090,29 @@
   EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
 
   // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kRelay);
 
   // Next, ping Local/Relay.
-  VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kHost,
+                               IceCandidateType::kRelay);
 
   // Remote Local candidate arrives.
   ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
   EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);
 
   // Local/Local should be the first since it hasn't been pinged before.
-  VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kHost,
+                               IceCandidateType::kHost);
 
   // Relay/Local is the final one.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kHost);
 
   // Now, every connection has been pinged once. The next one should be
   // Relay/Relay.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kRelay);
 }
 
 // Test skip_relay_to_non_relay_connections field-trial.
@@ -5146,14 +5157,16 @@
   EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);
 
   // UDP Relay/Relay should be pinged first.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kRelay);
 
   // TCP Relay/Relay is the next.
-  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
-                               TCP_PROTOCOL_NAME);
+  VerifyNextPingableConnection(IceCandidateType::kRelay,
+                               IceCandidateType::kRelay, TCP_PROTOCOL_NAME);
 
   // Finally, Local/Relay will be pinged.
-  VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
+  VerifyNextPingableConnection(IceCandidateType::kHost,
+                               IceCandidateType::kRelay);
 }
 
 // Test that a resolver is created, asked for a result, and destroyed
diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc
index f77040d..a8c0352 100644
--- a/p2p/client/basic_port_allocator_unittest.cc
+++ b/p2p/client/basic_port_allocator_unittest.cc
@@ -50,8 +50,9 @@
 
 using rtc::IPAddress;
 using rtc::SocketAddress;
-using ::testing::Contains;
-using ::testing::Not;
+using testing::Contains;
+using testing::Not;
+using webrtc::IceCandidateType;
 
 #define MAYBE_SKIP_IPV4                        \
   if (!rtc::HasIPv4Enabled()) {                \
@@ -325,7 +326,7 @@
 
   // Find a candidate and return it.
   static bool FindCandidate(const std::vector<Candidate>& candidates,
-                            absl::string_view type,
+                            IceCandidateType type,
                             absl::string_view proto,
                             const SocketAddress& addr,
                             Candidate* found) {
@@ -342,7 +343,7 @@
 
   // Convenience method to call FindCandidate with no return.
   static bool HasCandidate(const std::vector<Candidate>& candidates,
-                           absl::string_view type,
+                           IceCandidateType type,
                            absl::string_view proto,
                            const SocketAddress& addr) {
     return FindCandidate(candidates, type, proto, addr, nullptr);
@@ -351,7 +352,7 @@
   // Version of HasCandidate that also takes a related address.
   static bool HasCandidateWithRelatedAddr(
       const std::vector<Candidate>& candidates,
-      absl::string_view type,
+      IceCandidateType type,
       absl::string_view proto,
       const SocketAddress& addr,
       const SocketAddress& related_addr) {
@@ -553,7 +554,7 @@
 
     uint32_t total_candidates = 0;
     if (!host_candidate_addr.IsNil()) {
-      EXPECT_TRUE(HasCandidate(candidates_, "local", "udp",
+      EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
                                rtc::SocketAddress(kPrivateAddr.ipaddr(), 0)));
       ++total_candidates;
     }
@@ -563,20 +564,20 @@
         related_address.SetIP(rtc::GetAnyIP(stun_candidate_addr.family()));
       }
       EXPECT_TRUE(HasCandidateWithRelatedAddr(
-          candidates_, "stun", "udp",
+          candidates_, IceCandidateType::kSrflx, "udp",
           rtc::SocketAddress(stun_candidate_addr, 0), related_address));
       ++total_candidates;
     }
     if (!relay_candidate_udp_transport_addr.IsNil()) {
       EXPECT_TRUE(HasCandidateWithRelatedAddr(
-          candidates_, "relay", "udp",
+          candidates_, IceCandidateType::kRelay, "udp",
           rtc::SocketAddress(relay_candidate_udp_transport_addr, 0),
           rtc::SocketAddress(stun_candidate_addr, 0)));
       ++total_candidates;
     }
     if (!relay_candidate_tcp_transport_addr.IsNil()) {
       EXPECT_TRUE(HasCandidateWithRelatedAddr(
-          candidates_, "relay", "udp",
+          candidates_, IceCandidateType::kRelay, "udp",
           rtc::SocketAddress(relay_candidate_tcp_transport_addr, 0),
           rtc::SocketAddress(stun_candidate_addr, 0)));
       ++total_candidates;
@@ -623,8 +624,9 @@
     const std::vector<Candidate>& ready_candidates =
         session_->ReadyCandidates();
     EXPECT_EQ(3U, ready_candidates.size());
-    EXPECT_TRUE(HasCandidate(ready_candidates, "local", "udp", kClientAddr));
-    EXPECT_TRUE(HasCandidate(ready_candidates, "relay", "udp",
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "udp",
+                             kClientAddr));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kRelay, "udp",
                              rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
   }
 
@@ -670,10 +672,11 @@
     const std::vector<Candidate>& ready_candidates =
         session_->ReadyCandidates();
     EXPECT_EQ(2U, ready_candidates.size());
-    EXPECT_TRUE(HasCandidate(ready_candidates, "local", "udp", kClientAddr));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "udp",
+                             kClientAddr));
 
     // The external candidate is always udp.
-    EXPECT_TRUE(HasCandidate(ready_candidates, "relay", "udp",
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kRelay, "udp",
                              rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
   }
 
@@ -725,19 +728,23 @@
     const std::vector<Candidate>& ready_candidates =
         session_->ReadyCandidates();
     EXPECT_EQ(10U, ready_candidates.size());
-    EXPECT_TRUE(HasCandidate(ready_candidates, "local", "udp", kClientAddr));
-    EXPECT_TRUE(HasCandidate(ready_candidates, "local", "udp", kClientAddr2));
-    EXPECT_TRUE(
-        HasCandidate(ready_candidates, "local", "udp", kClientIPv6Addr));
-    EXPECT_TRUE(
-        HasCandidate(ready_candidates, "local", "udp", kClientIPv6Addr2));
-    EXPECT_TRUE(HasCandidate(ready_candidates, "local", "tcp", kClientAddr));
-    EXPECT_TRUE(HasCandidate(ready_candidates, "local", "tcp", kClientAddr2));
-    EXPECT_TRUE(
-        HasCandidate(ready_candidates, "local", "tcp", kClientIPv6Addr));
-    EXPECT_TRUE(
-        HasCandidate(ready_candidates, "local", "tcp", kClientIPv6Addr2));
-    EXPECT_TRUE(HasCandidate(ready_candidates, "relay", "udp",
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "udp",
+                             kClientAddr));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "udp",
+                             kClientAddr2));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "udp",
+                             kClientIPv6Addr));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "udp",
+                             kClientIPv6Addr2));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "tcp",
+                             kClientAddr));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "tcp",
+                             kClientAddr2));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "tcp",
+                             kClientIPv6Addr));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kHost, "tcp",
+                             kClientIPv6Addr2));
+    EXPECT_TRUE(HasCandidate(ready_candidates, IceCandidateType::kRelay, "udp",
                              rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
   }
 };
@@ -815,7 +822,7 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Should only get one Wi-Fi candidate.
   EXPECT_EQ(1U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", wifi));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp", wifi));
 }
 
 // Test that when the PORTALLOCATOR_DISABLE_COSTLY_NETWORKS flag is set and
@@ -841,8 +848,10 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Should only get two candidates, none of which is cell.
   EXPECT_EQ(2U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", unknown1));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", unknown2));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", unknown1));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", unknown2));
 }
 
 // Test that when the PORTALLOCATOR_DISABLE_COSTLY_NETWORKS flag is set and
@@ -869,7 +878,7 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Should only get one Wi-Fi candidate.
   EXPECT_EQ(1U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", wifi));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp", wifi));
 }
 
 // Test that if the PORTALLOCATOR_DISABLE_COSTLY_NETWORKS flag is set, but the
@@ -890,7 +899,8 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Make sure we got the cell candidate.
   EXPECT_EQ(1U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", cellular));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", cellular));
 }
 
 // Test that if both PORTALLOCATOR_DISABLE_COSTLY_NETWORKS is set, and there is
@@ -913,8 +923,10 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Make sure we got both wifi and cell candidates.
   EXPECT_EQ(2U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", wifi_link_local));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", cellular));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           wifi_link_local));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", cellular));
 }
 
 // Test that if both PORTALLOCATOR_DISABLE_COSTLY_NETWORKS is set, and there is
@@ -940,8 +952,9 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Make sure we got only wifi candidates.
   EXPECT_EQ(2U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", wifi));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", wifi_link_local));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp", wifi));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           wifi_link_local));
 }
 
 // Test that the adapter types of the Ethernet and the VPN can be correctly
@@ -986,8 +999,10 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(2U, candidates_.size());
   // Ensure the expected two interfaces (eth0 and eth1) were used.
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr2));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr2));
 }
 
 // Ensure that allocator.max_ipv6_networks() doesn't prevent IPv4 networks from
@@ -1012,9 +1027,12 @@
   EXPECT_EQ(3U, candidates_.size());
   // Ensure that only one IPv6 interface was used, but both IPv4 interfaces
   // were used.
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr2));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr2));
 }
 
 // Test that we could use loopback interface as host candidate.
@@ -1039,9 +1057,12 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(3U, candidates_.size());
   EXPECT_EQ(3U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kSrflx, "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
 }
 
 // Test that when the same network interface is brought down and up, the
@@ -1134,7 +1155,8 @@
   // a single TCP active candidate, since that doesn't require creating a
   // socket).
   ASSERT_EQ(1U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
   candidate_allocation_done_ = false;
 
   // Now simulate the interface coming up, with the newfound ability to bind
@@ -1146,11 +1168,13 @@
                              kDefaultAllocationTimeout, fake_clock);
   // Should get UDP and TCP candidate.
   ASSERT_EQ(2U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
   // TODO(deadbeef): This is actually the same active TCP candidate as before.
   // We should extend this test to also verify that a server candidate is
   // gathered.
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
 }
 
 // Verify candidates with default step delay of 1sec.
@@ -1165,7 +1189,8 @@
   EXPECT_EQ(3U, ports_.size());
 
   ASSERT_EQ_SIMULATED_WAIT(3U, candidates_.size(), 1500, fake_clock);
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
   EXPECT_EQ(3U, ports_.size());
   EXPECT_TRUE(candidate_allocation_done_);
   // If we Stop gathering now, we shouldn't get a second "done" callback.
@@ -1252,7 +1277,7 @@
   // candidate for it is useless and shouldn't be signaled. So we only have
   // STUN/TURN candidates.
   EXPECT_EQ(3U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp",
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kSrflx, "udp",
                            rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0)));
   // Again, two TURN candidates, using UDP/TCP for the first hop to the TURN
   // server.
@@ -1387,11 +1412,12 @@
   EXPECT_EQ(2U, ports_.size());
   EXPECT_EQ(2U, candidates_.size());
   Candidate turn_candidate;
-  EXPECT_TRUE(FindCandidate(candidates_, "relay", "udp", kTurnUdpExtAddr,
-                            &turn_candidate));
+  EXPECT_TRUE(FindCandidate(candidates_, IceCandidateType::kRelay, "udp",
+                            kTurnUdpExtAddr, &turn_candidate));
   // The TURN candidate should use TCP to contact the TURN server.
   EXPECT_EQ(TCP_PROTOCOL_NAME, turn_candidate.relay_protocol());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
 }
 
 // Test that we can get OnCandidatesAllocationDone callback when all the ports
@@ -1416,7 +1442,8 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(1U, candidates_.size());
   EXPECT_EQ(1U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
 }
 
 // Test that we don't crash or malfunction if we can't create UDP sockets or
@@ -1432,7 +1459,8 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(1U, candidates_.size());
   EXPECT_EQ(1U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
 }
 
 // Test that we don't crash or malfunction if we can't create any sockets.
@@ -1458,8 +1486,10 @@
   EXPECT_EQ_SIMULATED_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout,
                            fake_clock);
   EXPECT_EQ(2U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
   // We wait at least for a full STUN timeout, which
   // cricket::STUN_TOTAL_TIMEOUT seconds.
   EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
@@ -1529,7 +1559,7 @@
   session_->StartGettingPorts();
   EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
                              kDefaultAllocationTimeout, fake_clock);
-  EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp",
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kRelay, "udp",
                            rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
 
   EXPECT_EQ(1U, candidates_.size());
@@ -1601,9 +1631,12 @@
   ASSERT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(3U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kSrflx, "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
   EXPECT_EQ(3U, ports_.size());
   for (const Candidate& candidate : candidates_) {
     EXPECT_EQ(kIceUfrag0, candidate.username());
@@ -1624,7 +1657,8 @@
   ASSERT_EQ_SIMULATED_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout,
                            fake_clock);
   EXPECT_EQ(2U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
   EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
                              kDefaultAllocationTimeout, fake_clock);
 }
@@ -1643,8 +1677,9 @@
   ASSERT_EQ_SIMULATED_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout,
                            fake_clock);
   ASSERT_EQ(2U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp",
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kSrflx, "udp",
                            rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0)));
   EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
                              kDefaultAllocationTimeout, fake_clock);
@@ -1672,10 +1707,11 @@
                              kDefaultAllocationTimeout, fake_clock);
   ASSERT_EQ(3U, candidates_.size());
   ASSERT_EQ(3U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp",
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kRelay, "udp",
                            rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
-  EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp",
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kRelay, "udp",
                            rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
 }
 
@@ -1830,10 +1866,11 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(3U, candidates_.size());
   ASSERT_EQ(2U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp",
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kSrflx, "udp",
                            rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0)));
-  EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp",
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kRelay, "udp",
                            rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
   EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
                              kDefaultAllocationTimeout, fake_clock);
@@ -1868,13 +1905,14 @@
   ASSERT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(3U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
   Candidate stun_candidate;
-  EXPECT_TRUE(FindCandidate(candidates_, "stun", "udp",
+  EXPECT_TRUE(FindCandidate(candidates_, IceCandidateType::kSrflx, "udp",
                             rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0),
                             &stun_candidate));
   EXPECT_TRUE(HasCandidateWithRelatedAddr(
-      candidates_, "relay", "udp",
+      candidates_, IceCandidateType::kRelay, "udp",
       rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0),
       stun_candidate.address()));
 
@@ -1905,8 +1943,9 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(2U, candidates_.size());
   ASSERT_EQ(2U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp",
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kRelay, "udp",
                            rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)));
   EXPECT_EQ(1U, ports_[0]->Candidates().size());
   EXPECT_EQ(1U, ports_[1]->Candidates().size());
@@ -1932,13 +1971,14 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(3U, candidates_.size());
   ASSERT_EQ(3U, ports_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
   Candidate stun_candidate;
-  EXPECT_TRUE(FindCandidate(candidates_, "stun", "udp",
+  EXPECT_TRUE(FindCandidate(candidates_, IceCandidateType::kSrflx, "udp",
                             rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0),
                             &stun_candidate));
   Candidate turn_candidate;
-  EXPECT_TRUE(FindCandidate(candidates_, "relay", "udp",
+  EXPECT_TRUE(FindCandidate(candidates_, IceCandidateType::kRelay, "udp",
                             rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0),
                             &turn_candidate));
   // Not using shared socket, so the STUN request's server reflexive address
@@ -1969,13 +2009,14 @@
 
   ASSERT_EQ_SIMULATED_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout,
                            fake_clock);
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
   Candidate stun_candidate;
-  EXPECT_TRUE(FindCandidate(candidates_, "stun", "udp",
+  EXPECT_TRUE(FindCandidate(candidates_, IceCandidateType::kSrflx, "udp",
                             rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0),
                             &stun_candidate));
   EXPECT_TRUE(HasCandidateWithRelatedAddr(
-      candidates_, "relay", "udp",
+      candidates_, IceCandidateType::kRelay, "udp",
       rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0),
       stun_candidate.address()));
 
@@ -1997,7 +2038,8 @@
   ASSERT_EQ_SIMULATED_WAIT(1U, ports_.size(), kDefaultAllocationTimeout,
                            fake_clock);
   EXPECT_EQ(1U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
   // STUN timeout is 9.5sec. We need to wait to get candidate done signal.
   EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, kStunTimeoutMs,
                              fake_clock);
@@ -2023,7 +2065,8 @@
   EXPECT_EQ_SIMULATED_WAIT(1U, ports_.size(), kDefaultAllocationTimeout,
                            fake_clock);
   EXPECT_EQ(1U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kPrivateAddr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kPrivateAddr));
   EXPECT_NE(0U, session_->flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
 }
 
@@ -2041,10 +2084,14 @@
                              kDefaultAllocationTimeout, fake_clock);
   EXPECT_EQ(4U, ports_.size());
   EXPECT_EQ(4U, candidates_.size());
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "udp", kClientAddr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "tcp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(
+      HasCandidate(candidates_, IceCandidateType::kHost, "tcp", kClientAddr));
 }
 
 TEST_F(BasicPortAllocatorTest, TestStopGettingPorts) {
@@ -2631,8 +2678,10 @@
 
   EXPECT_EQ(2U, candidates_.size());
   // ethe1 and wifi1 were selected.
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr3));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr3));
 }
 
 TEST_F(BasicPortAllocatorTest, Select3DifferentIntefaces) {
@@ -2656,9 +2705,12 @@
 
   EXPECT_EQ(3U, candidates_.size());
   // ethe1, wifi1, and cell1 were selected.
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr3));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr5));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr3));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr5));
 }
 
 TEST_F(BasicPortAllocatorTest, Select4DifferentIntefaces) {
@@ -2682,10 +2734,14 @@
 
   EXPECT_EQ(4U, candidates_.size());
   // ethe1, ethe2, wifi1, and cell1 were selected.
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr2));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr3));
-  EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr5));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr2));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr3));
+  EXPECT_TRUE(HasCandidate(candidates_, IceCandidateType::kHost, "udp",
+                           kClientIPv6Addr5));
 }
 
 }  // namespace cricket
diff --git a/pc/legacy_stats_collector.cc b/pc/legacy_stats_collector.cc
index 135829a..45e6872 100644
--- a/pc/legacy_stats_collector.cc
+++ b/pc/legacy_stats_collector.cc
@@ -513,6 +513,15 @@
   return "unknown";
 }
 
+// Return std::string to make sure that the type remains kString compatible.
+std::string GetLegacyCandidateTypeName(const cricket::Candidate& c) {
+  if (c.is_local())
+    return "local";
+  if (c.is_stun())
+    return "stun";
+  return std::string(c.type_name());
+}
+
 const char* AdapterTypeToStatsType(rtc::AdapterType type) {
   switch (type) {
     case rtc::ADAPTER_TYPE_UNKNOWN:
@@ -811,11 +820,11 @@
   report->AddString(StatsReport::kStatsValueNameLocalAddress,
                     info.local_candidate.address().ToString());
   report->AddString(StatsReport::kStatsValueNameLocalCandidateType,
-                    info.local_candidate.type());
+                    GetLegacyCandidateTypeName(info.local_candidate));
   report->AddString(StatsReport::kStatsValueNameRemoteAddress,
                     info.remote_candidate.address().ToString());
   report->AddString(StatsReport::kStatsValueNameRemoteCandidateType,
-                    info.remote_candidate.type());
+                    GetLegacyCandidateTypeName(info.remote_candidate));
   report->AddString(StatsReport::kStatsValueNameTransportType,
                     info.local_candidate.protocol());
   report->AddString(StatsReport::kStatsValueNameLocalCandidateRelayProtocol,