diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index f6a3858a6c..9601ee8e9f 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -70,40 +70,15 @@ uint32_t GetWeakPingIntervalInFieldTrial() {
return cricket::WEAK_PING_INTERVAL;
}
-rtc::AdapterType GuessAdapterTypeFromNetworkCost(int network_cost) {
- // The current network costs have been unchanged since they were added
- // to webrtc. If they ever were to change we would need to reconsider
- // this method.
- switch (network_cost) {
- case rtc::kNetworkCostMin:
- return rtc::ADAPTER_TYPE_ETHERNET;
- case rtc::kNetworkCostLow:
- return rtc::ADAPTER_TYPE_WIFI;
- case rtc::kNetworkCostCellular:
- return rtc::ADAPTER_TYPE_CELLULAR;
- case rtc::kNetworkCostCellular2G:
- return rtc::ADAPTER_TYPE_CELLULAR_2G;
- case rtc::kNetworkCostCellular3G:
- return rtc::ADAPTER_TYPE_CELLULAR_3G;
- case rtc::kNetworkCostCellular4G:
- return rtc::ADAPTER_TYPE_CELLULAR_4G;
- case rtc::kNetworkCostCellular5G:
- return rtc::ADAPTER_TYPE_CELLULAR_5G;
- case rtc::kNetworkCostUnknown:
- return rtc::ADAPTER_TYPE_UNKNOWN;
- case rtc::kNetworkCostMax:
- return rtc::ADAPTER_TYPE_ANY;
- }
- return rtc::ADAPTER_TYPE_UNKNOWN;
-}
-
rtc::RouteEndpoint CreateRouteEndpointFromCandidate(
bool local,
const cricket::Candidate& candidate,
bool uses_turn) {
auto adapter_type = candidate.network_type();
if (!local && adapter_type == rtc::ADAPTER_TYPE_UNKNOWN) {
- adapter_type = GuessAdapterTypeFromNetworkCost(candidate.network_cost());
+ bool vpn;
+ std::tie(adapter_type, vpn) =
+ rtc::Network::GuessAdapterFromNetworkCost(candidate.network_cost());
}
// TODO(bugs.webrtc.org/9446) : Rewrite if information about remote network
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index 870f22a3a9..24c1993d0f 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -1168,6 +1168,51 @@ uint16_t Network::GetCost() const {
add_network_cost_to_vpn_);
}
+// This is the inverse of ComputeNetworkCostByType().
+std::pair
+Network::GuessAdapterFromNetworkCost(int network_cost) {
+ switch (network_cost) {
+ case kNetworkCostMin:
+ return {rtc::ADAPTER_TYPE_ETHERNET, false};
+ case kNetworkCostMin + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_ETHERNET, true};
+ case kNetworkCostLow:
+ return {rtc::ADAPTER_TYPE_WIFI, false};
+ case kNetworkCostLow + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_WIFI, true};
+ case kNetworkCostCellular:
+ return {rtc::ADAPTER_TYPE_CELLULAR, false};
+ case kNetworkCostCellular + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_CELLULAR, true};
+ case kNetworkCostCellular2G:
+ return {rtc::ADAPTER_TYPE_CELLULAR_2G, false};
+ case kNetworkCostCellular2G + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_CELLULAR_2G, true};
+ case kNetworkCostCellular3G:
+ return {rtc::ADAPTER_TYPE_CELLULAR_3G, false};
+ case kNetworkCostCellular3G + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_CELLULAR_3G, true};
+ case kNetworkCostCellular4G:
+ return {rtc::ADAPTER_TYPE_CELLULAR_4G, false};
+ case kNetworkCostCellular4G + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_CELLULAR_4G, true};
+ case kNetworkCostCellular5G:
+ return {rtc::ADAPTER_TYPE_CELLULAR_5G, false};
+ case kNetworkCostCellular5G + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_CELLULAR_5G, true};
+ case kNetworkCostUnknown:
+ return {rtc::ADAPTER_TYPE_UNKNOWN, false};
+ case kNetworkCostUnknown + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_UNKNOWN, true};
+ case kNetworkCostMax:
+ return {rtc::ADAPTER_TYPE_ANY, false};
+ case kNetworkCostMax + kNetworkCostVpn:
+ return {rtc::ADAPTER_TYPE_ANY, true};
+ }
+ RTC_LOG(LS_VERBOSE) << "Unknown network cost: " << network_cost;
+ return {rtc::ADAPTER_TYPE_UNKNOWN, false};
+}
+
std::string Network::ToString() const {
rtc::StringBuilder ss;
// Print out the first space-terminated token of the network desc, plus
diff --git a/rtc_base/network.h b/rtc_base/network.h
index 0b462bdede..5a64c34cd4 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -526,6 +526,9 @@ class RTC_EXPORT Network {
SignalNetworkPreferenceChanged(this);
}
+ static std::pair
+ GuessAdapterFromNetworkCost(int network_cost);
+
// Debugging description of this network
std::string ToString() const;
diff --git a/rtc_base/network_constants.h b/rtc_base/network_constants.h
index 0495afdcc9..578b9710d0 100644
--- a/rtc_base/network_constants.h
+++ b/rtc_base/network_constants.h
@@ -57,6 +57,16 @@ enum AdapterType {
std::string AdapterTypeToString(AdapterType type);
+// Useful for testing!
+constexpr AdapterType kAllAdapterTypes[] = {
+ ADAPTER_TYPE_UNKNOWN, ADAPTER_TYPE_ETHERNET,
+ ADAPTER_TYPE_WIFI, ADAPTER_TYPE_CELLULAR,
+ ADAPTER_TYPE_VPN, ADAPTER_TYPE_LOOPBACK,
+ ADAPTER_TYPE_ANY, ADAPTER_TYPE_CELLULAR_2G,
+ ADAPTER_TYPE_CELLULAR_3G, ADAPTER_TYPE_CELLULAR_4G,
+ ADAPTER_TYPE_CELLULAR_5G,
+};
+
} // namespace rtc
#endif // RTC_BASE_NETWORK_CONSTANTS_H_
diff --git a/rtc_base/network_unittest.cc b/rtc_base/network_unittest.cc
index da2fe96bf6..5635f5d868 100644
--- a/rtc_base/network_unittest.cc
+++ b/rtc_base/network_unittest.cc
@@ -1421,6 +1421,45 @@ TEST_F(NetworkTest, NetworkCostVpn_VpnMoreExpensive) {
delete net2;
}
+TEST_F(NetworkTest, GuessAdapterFromNetworkCost) {
+ webrtc::test::ScopedFieldTrials field_trials(
+ "WebRTC-AddNetworkCostToVpn/Enabled/"
+ "WebRTC-UseDifferentiatedCellularCosts/Enabled/");
+
+ IPAddress ip1;
+ EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));
+
+ for (auto type : kAllAdapterTypes) {
+ if (type == rtc::ADAPTER_TYPE_VPN)
+ continue;
+ Network net1("em1", "em1", TruncateIP(ip1, 64), 64);
+ net1.set_type(type);
+ auto [guess, vpn] = Network::GuessAdapterFromNetworkCost(net1.GetCost());
+ EXPECT_FALSE(vpn);
+ if (type == rtc::ADAPTER_TYPE_LOOPBACK) {
+ EXPECT_EQ(guess, rtc::ADAPTER_TYPE_ETHERNET);
+ } else {
+ EXPECT_EQ(type, guess);
+ }
+ }
+
+ // VPN
+ for (auto type : kAllAdapterTypes) {
+ if (type == rtc::ADAPTER_TYPE_VPN)
+ continue;
+ 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());
+ EXPECT_TRUE(vpn);
+ if (type == rtc::ADAPTER_TYPE_LOOPBACK) {
+ EXPECT_EQ(guess, rtc::ADAPTER_TYPE_ETHERNET);
+ } else {
+ EXPECT_EQ(type, guess);
+ }
+ }
+}
+
TEST_F(NetworkTest, VpnList) {
PhysicalSocketServer socket_server;
{