Extend RTCIceCandidateStats with non-standard network_adapter_type

This cl/ extends the RTCIceCandidateStats object with
network_adapter_type and vpn, so that it maps the underlying
WebRTC objects completly.

Bug: webrtc:13773
Change-Id: I5cf79972c60ca6bf2a127dc96fa90811263ba6fd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/253241
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36110}
This commit is contained in:
Jonas Oreland 2022-03-02 11:17:36 +01:00 committed by WebRTC LUCI CQ
parent f08e2663aa
commit 0d13bbd4b1
7 changed files with 105 additions and 11 deletions

View File

@ -109,6 +109,13 @@ class RTC_EXPORT Candidate {
network_type_ = network_type;
}
rtc::AdapterType underlying_type_for_vpn() const {
return underlying_type_for_vpn_;
}
void set_underlying_type_for_vpn(rtc::AdapterType network_type) {
underlying_type_for_vpn_ = network_type;
}
// Candidates in a new generation replace those in the old generation.
uint32_t generation() const { return generation_; }
void set_generation(uint32_t generation) { generation_ = generation; }
@ -195,6 +202,7 @@ class RTC_EXPORT Candidate {
std::string type_;
std::string network_name_;
rtc::AdapterType network_type_;
rtc::AdapterType underlying_type_for_vpn_;
uint32_t generation_;
std::string foundation_;
rtc::SocketAddress related_address_;

View File

@ -106,6 +106,20 @@ class RTC_EXPORT RTCCertificateStats final : public RTCStats {
RTCStatsMember<std::string> issuer_certificate_id;
};
// Non standard extension mapping to rtc::AdapterType
struct RTCNetworkAdapterType {
static constexpr char kUnknown[] = "unknown";
static constexpr char kEthernet[] = "ethernet";
static constexpr char kWifi[] = "wifi";
static constexpr char kCellular[] = "cellular";
static constexpr char kLoopback[] = "loopback";
static constexpr char kAny[] = "any";
static constexpr char kCellular2g[] = "cellular2g";
static constexpr char kCellular3g[] = "cellular3g";
static constexpr char kCellular4g[] = "cellular4g";
static constexpr char kCellular5g[] = "cellular5g";
};
// https://w3c.github.io/webrtc-stats/#codec-dict*
class RTC_EXPORT RTCCodecStats final : public RTCStats {
public:
@ -227,6 +241,9 @@ class RTC_EXPORT RTCIceCandidateStats : public RTCStats {
RTCStatsMember<int32_t> priority;
RTCStatsMember<std::string> url;
RTCNonStandardStatsMember<bool> vpn;
RTCNonStandardStatsMember<std::string> network_adapter_type;
protected:
RTCIceCandidateStats(const std::string& id,
int64_t timestamp_us,

View File

@ -276,6 +276,7 @@ void Port::AddAddress(const rtc::SocketAddress& address,
c.set_tcptype(tcptype);
c.set_network_name(network_->name());
c.set_network_type(network_->type());
c.set_underlying_type_for_vpn(network_->underlying_type_for_vpn());
c.set_url(url);
c.set_related_address(related_address);

View File

@ -230,7 +230,7 @@ const char* DtlsTransportStateToRTCDtlsTransportState(
}
}
const char* NetworkAdapterTypeToStatsType(rtc::AdapterType type) {
const char* NetworkTypeToStatsType(rtc::AdapterType type) {
switch (type) {
case rtc::ADAPTER_TYPE_CELLULAR:
case rtc::ADAPTER_TYPE_CELLULAR_2G:
@ -253,6 +253,36 @@ const char* NetworkAdapterTypeToStatsType(rtc::AdapterType type) {
return nullptr;
}
absl::string_view NetworkTypeToStatsNetworkAdapterType(rtc::AdapterType type) {
switch (type) {
case rtc::ADAPTER_TYPE_CELLULAR:
return RTCNetworkAdapterType::kCellular;
case rtc::ADAPTER_TYPE_CELLULAR_2G:
return RTCNetworkAdapterType::kCellular2g;
case rtc::ADAPTER_TYPE_CELLULAR_3G:
return RTCNetworkAdapterType::kCellular3g;
case rtc::ADAPTER_TYPE_CELLULAR_4G:
return RTCNetworkAdapterType::kCellular4g;
case rtc::ADAPTER_TYPE_CELLULAR_5G:
return RTCNetworkAdapterType::kCellular5g;
case rtc::ADAPTER_TYPE_ETHERNET:
return RTCNetworkAdapterType::kEthernet;
case rtc::ADAPTER_TYPE_WIFI:
return RTCNetworkAdapterType::kWifi;
case rtc::ADAPTER_TYPE_UNKNOWN:
return RTCNetworkAdapterType::kUnknown;
case rtc::ADAPTER_TYPE_LOOPBACK:
return RTCNetworkAdapterType::kLoopback;
case rtc::ADAPTER_TYPE_ANY:
return RTCNetworkAdapterType::kAny;
case rtc::ADAPTER_TYPE_VPN:
/* should not be handled here. Vpn is modelled as a bool */
break;
}
RTC_DCHECK_NOTREACHED();
return nullptr;
}
const char* QualityLimitationReasonToRTCQualityLimitationReason(
QualityLimitationReason reason) {
switch (reason) {
@ -733,7 +763,7 @@ const std::string& ProduceIceCandidateStats(int64_t timestamp_us,
candidate_stats->transport_id = transport_id;
if (is_local) {
candidate_stats->network_type =
NetworkAdapterTypeToStatsType(candidate.network_type());
NetworkTypeToStatsType(candidate.network_type());
const std::string& candidate_type = candidate.type();
const std::string& relay_protocol = candidate.relay_protocol();
const std::string& url = candidate.url();
@ -752,6 +782,16 @@ const std::string& ProduceIceCandidateStats(int64_t timestamp_us,
candidate_stats->url = url;
}
}
if (candidate.network_type() == rtc::ADAPTER_TYPE_VPN) {
candidate_stats->vpn = true;
candidate_stats->network_adapter_type =
std::string(NetworkTypeToStatsNetworkAdapterType(
candidate.underlying_type_for_vpn()));
} else {
candidate_stats->vpn = false;
candidate_stats->network_adapter_type = std::string(
NetworkTypeToStatsNetworkAdapterType(candidate.network_type()));
}
} else {
// We don't expect to know the adapter type of remote candidates.
RTC_DCHECK_EQ(rtc::ADAPTER_TYPE_UNKNOWN, candidate.network_type());

View File

@ -216,11 +216,14 @@ std::unique_ptr<cricket::Candidate> CreateFakeCandidate(
const std::string& protocol,
const rtc::AdapterType adapter_type,
const std::string& candidate_type,
uint32_t priority) {
uint32_t priority,
const rtc::AdapterType underlying_type_for_vpn =
rtc::ADAPTER_TYPE_UNKNOWN) {
std::unique_ptr<cricket::Candidate> candidate(new cricket::Candidate());
candidate->set_address(rtc::SocketAddress(hostname, port));
candidate->set_protocol(protocol);
candidate->set_network_type(adapter_type);
candidate->set_underlying_type_for_vpn(underlying_type_for_vpn);
candidate->set_type(candidate_type);
candidate->set_priority(priority);
return candidate;
@ -1256,9 +1259,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCDataChannelStats) {
TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
// Candidates in the first transport stats.
std::unique_ptr<cricket::Candidate> a_local_host =
CreateFakeCandidate("1.2.3.4", 5, "a_local_host's protocol",
rtc::ADAPTER_TYPE_VPN, cricket::LOCAL_PORT_TYPE, 0);
std::unique_ptr<cricket::Candidate> a_local_host = CreateFakeCandidate(
"1.2.3.4", 5, "a_local_host's protocol", rtc::ADAPTER_TYPE_VPN,
cricket::LOCAL_PORT_TYPE, 0, rtc::ADAPTER_TYPE_ETHERNET);
RTCLocalIceCandidateStats expected_a_local_host(
"RTCIceCandidate_" + a_local_host->id(), 0);
expected_a_local_host.transport_id = "RTCTransport_a_0";
@ -1269,6 +1272,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
expected_a_local_host.protocol = "a_local_host's protocol";
expected_a_local_host.candidate_type = "host";
expected_a_local_host.priority = 0;
expected_a_local_host.vpn = true;
expected_a_local_host.network_adapter_type = RTCNetworkAdapterType::kEthernet;
std::unique_ptr<cricket::Candidate> a_remote_srflx = CreateFakeCandidate(
"6.7.8.9", 10, "remote_srflx's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
@ -1284,8 +1289,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
expected_a_remote_srflx.priority = 1;
std::unique_ptr<cricket::Candidate> a_local_prflx = CreateFakeCandidate(
"11.12.13.14", 15, "a_local_prflx's protocol", rtc::ADAPTER_TYPE_CELLULAR,
cricket::PRFLX_PORT_TYPE, 2);
"11.12.13.14", 15, "a_local_prflx's protocol",
rtc::ADAPTER_TYPE_CELLULAR_2G, cricket::PRFLX_PORT_TYPE, 2);
RTCLocalIceCandidateStats expected_a_local_prflx(
"RTCIceCandidate_" + a_local_prflx->id(), 0);
expected_a_local_prflx.transport_id = "RTCTransport_a_0";
@ -1296,6 +1301,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
expected_a_local_prflx.protocol = "a_local_prflx's protocol";
expected_a_local_prflx.candidate_type = "prflx";
expected_a_local_prflx.priority = 2;
expected_a_local_prflx.vpn = false;
expected_a_local_prflx.network_adapter_type =
RTCNetworkAdapterType::kCellular2g;
std::unique_ptr<cricket::Candidate> a_remote_relay = CreateFakeCandidate(
"16.17.18.19", 20, "a_remote_relay's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
@ -1328,6 +1336,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
expected_a_local_relay.candidate_type = "relay";
expected_a_local_relay.priority = 1;
expected_a_local_relay.url = "turn:url1";
expected_a_local_relay.vpn = false;
expected_a_local_relay.network_adapter_type = RTCNetworkAdapterType::kUnknown;
std::unique_ptr<cricket::Candidate> a_local_relay_prflx = CreateFakeCandidate(
"11.12.13.20", 22, "a_local_relay_prflx's protocol",
@ -1345,6 +1355,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
expected_a_local_relay_prflx.relay_protocol = "udp";
expected_a_local_relay_prflx.candidate_type = "prflx";
expected_a_local_relay_prflx.priority = 1;
expected_a_local_relay_prflx.vpn = false;
expected_a_local_relay_prflx.network_adapter_type =
RTCNetworkAdapterType::kUnknown;
// Candidates in the second transport stats.
std::unique_ptr<cricket::Candidate> b_local =
@ -1360,6 +1373,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
expected_b_local.protocol = "b_local's protocol";
expected_b_local.candidate_type = "host";
expected_b_local.priority = 42;
expected_b_local.vpn = false;
expected_b_local.network_adapter_type = RTCNetworkAdapterType::kWifi;
std::unique_ptr<cricket::Candidate> b_remote = CreateFakeCandidate(
"42.42.42.42", 42, "b_remote's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
@ -1594,6 +1609,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
expected_local_candidate.protocol = "protocol";
expected_local_candidate.candidate_type = "host";
expected_local_candidate.priority = 42;
expected_local_candidate.vpn = false;
expected_local_candidate.network_adapter_type = RTCNetworkAdapterType::kWifi;
ASSERT_TRUE(report->Get(expected_local_candidate.id()));
EXPECT_EQ(expected_local_candidate,
report->Get(expected_local_candidate.id())

View File

@ -521,6 +521,7 @@ class RTCStatsReportVerifier {
candidate_pair.consent_requests_sent);
verifier.TestMemberIsUndefined(candidate_pair.consent_responses_received);
verifier.TestMemberIsUndefined(candidate_pair.consent_responses_sent);
return verifier.ExpectAllMembersSuccessfullyTested();
}
@ -531,8 +532,12 @@ class RTCStatsReportVerifier {
verifier.TestMemberIsDefined(candidate.is_remote);
if (*candidate.is_remote) {
verifier.TestMemberIsUndefined(candidate.network_type);
verifier.TestMemberIsUndefined(candidate.network_adapter_type);
verifier.TestMemberIsUndefined(candidate.vpn);
} else {
verifier.TestMemberIsDefined(candidate.network_type);
verifier.TestMemberIsDefined(candidate.network_adapter_type);
verifier.TestMemberIsDefined(candidate.vpn);
}
verifier.TestMemberIsDefined(candidate.ip);
verifier.TestMemberIsDefined(candidate.address);

View File

@ -277,7 +277,9 @@ WEBRTC_RTCSTATS_IMPL(RTCIceCandidateStats, RTCStats, "abstract-ice-candidate",
&relay_protocol,
&candidate_type,
&priority,
&url)
&url,
&vpn,
&network_adapter_type)
// clang-format on
RTCIceCandidateStats::RTCIceCandidateStats(const std::string& id,
@ -299,7 +301,9 @@ RTCIceCandidateStats::RTCIceCandidateStats(std::string&& id,
relay_protocol("relayProtocol"),
candidate_type("candidateType"),
priority("priority"),
url("url") {}
url("url"),
vpn("vpn"),
network_adapter_type("networkAdapterType") {}
RTCIceCandidateStats::RTCIceCandidateStats(const RTCIceCandidateStats& other)
: RTCStats(other.id(), other.timestamp_us()),
@ -313,7 +317,9 @@ RTCIceCandidateStats::RTCIceCandidateStats(const RTCIceCandidateStats& other)
relay_protocol(other.relay_protocol),
candidate_type(other.candidate_type),
priority(other.priority),
url(other.url) {}
url(other.url),
vpn(other.vpn),
network_adapter_type(other.network_adapter_type) {}
RTCIceCandidateStats::~RTCIceCandidateStats() {}