Add support for RTCTransportStats.selectedCandidatePairChanges
This patch adds accounting and reporting needed for newly added RTCTransportStats.selectedCandidatePairChanges, https://w3c.github.io/webrtc-stats/#dom-rtctransportstats-selectedcandidatepairchanges a) P2PTransportChannel counts everytime selected_connection_ is modified and reports this counter in the GetStats()-call. b) RTCStatsCollector puts the counter into the standardized stats object. Bug: webrtc:10900 Change-Id: Ibaeca18706b8edcbcb44b0c6f2754854bcb545ba Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/149830 Reviewed-by: Qingsi Wang <qingsi@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Jonas Oreland <jonaso@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28987}
This commit is contained in:
parent
3b69817e62
commit
149dc72dfa
@ -594,6 +594,7 @@ class RTC_EXPORT RTCTransportStats final : public RTCStats {
|
|||||||
RTCStatsMember<std::string> selected_candidate_pair_id;
|
RTCStatsMember<std::string> selected_candidate_pair_id;
|
||||||
RTCStatsMember<std::string> local_certificate_id;
|
RTCStatsMember<std::string> local_certificate_id;
|
||||||
RTCStatsMember<std::string> remote_certificate_id;
|
RTCStatsMember<std::string> remote_certificate_id;
|
||||||
|
RTCStatsMember<uint32_t> selected_candidate_pair_changes;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -193,14 +193,13 @@ class FakeIceTransport : public IceTransportInternal {
|
|||||||
|
|
||||||
void RemoveAllRemoteCandidates() override { remote_candidates_.clear(); }
|
void RemoveAllRemoteCandidates() override { remote_candidates_.clear(); }
|
||||||
|
|
||||||
bool GetStats(ConnectionInfos* candidate_pair_stats_list,
|
bool GetStats(IceTransportStats* ice_transport_stats) override {
|
||||||
CandidateStatsList* candidate_stats_list) override {
|
|
||||||
CandidateStats candidate_stats;
|
CandidateStats candidate_stats;
|
||||||
ConnectionInfo candidate_pair_stats;
|
ConnectionInfo candidate_pair_stats;
|
||||||
candidate_stats_list->clear();
|
ice_transport_stats->candidate_stats_list.clear();
|
||||||
candidate_stats_list->push_back(candidate_stats);
|
ice_transport_stats->candidate_stats_list.push_back(candidate_stats);
|
||||||
candidate_pair_stats_list->clear();
|
ice_transport_stats->connection_infos.clear();
|
||||||
candidate_pair_stats_list->push_back(candidate_pair_stats);
|
ice_transport_stats->connection_infos.push_back(candidate_pair_stats);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,15 @@
|
|||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
||||||
|
struct IceTransportStats {
|
||||||
|
CandidateStatsList candidate_stats_list;
|
||||||
|
ConnectionInfos connection_infos;
|
||||||
|
// Number of times the selected candidate pair has changed
|
||||||
|
// Initially 0 and 1 once the first candidate pair has been selected.
|
||||||
|
// The counter is increase also when "unselecting" a connection.
|
||||||
|
uint32_t selected_candidate_pair_changes = 0;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::vector<Candidate> Candidates;
|
typedef std::vector<Candidate> Candidates;
|
||||||
|
|
||||||
enum IceConnectionState {
|
enum IceConnectionState {
|
||||||
@ -256,8 +265,7 @@ class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal {
|
|||||||
virtual IceGatheringState gathering_state() const = 0;
|
virtual IceGatheringState gathering_state() const = 0;
|
||||||
|
|
||||||
// Returns the current stats for this connection.
|
// Returns the current stats for this connection.
|
||||||
virtual bool GetStats(ConnectionInfos* candidate_pair_stats_list,
|
virtual bool GetStats(IceTransportStats* ice_transport_stats) = 0;
|
||||||
CandidateStatsList* candidate_stats_list) = 0;
|
|
||||||
|
|
||||||
// Returns RTT estimate over the currently active connection, or an empty
|
// Returns RTT estimate over the currently active connection, or an empty
|
||||||
// absl::optional if there is none.
|
// absl::optional if there is none.
|
||||||
|
|||||||
@ -40,9 +40,7 @@ class MockIceTransport : public IceTransportInternal {
|
|||||||
MOCK_METHOD2(SetOption, int(rtc::Socket::Option opt, int value));
|
MOCK_METHOD2(SetOption, int(rtc::Socket::Option opt, int value));
|
||||||
MOCK_METHOD0(GetError, int());
|
MOCK_METHOD0(GetError, int());
|
||||||
MOCK_CONST_METHOD0(GetIceRole, cricket::IceRole());
|
MOCK_CONST_METHOD0(GetIceRole, cricket::IceRole());
|
||||||
MOCK_METHOD2(GetStats,
|
MOCK_METHOD1(GetStats, bool(cricket::IceTransportStats* ice_transport_stats));
|
||||||
bool(cricket::ConnectionInfos* candidate_pair_stats_list,
|
|
||||||
cricket::CandidateStatsList* candidate_stats_list));
|
|
||||||
|
|
||||||
IceTransportState GetState() const override {
|
IceTransportState GetState() const override {
|
||||||
return IceTransportState::STATE_INIT;
|
return IceTransportState::STATE_INIT;
|
||||||
|
|||||||
@ -1493,15 +1493,15 @@ int P2PTransportChannel::SendPacket(const char* data,
|
|||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool P2PTransportChannel::GetStats(ConnectionInfos* candidate_pair_stats_list,
|
bool P2PTransportChannel::GetStats(IceTransportStats* ice_transport_stats) {
|
||||||
CandidateStatsList* candidate_stats_list) {
|
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
// Gather candidate and candidate pair stats.
|
// Gather candidate and candidate pair stats.
|
||||||
candidate_stats_list->clear();
|
ice_transport_stats->candidate_stats_list.clear();
|
||||||
candidate_pair_stats_list->clear();
|
ice_transport_stats->connection_infos.clear();
|
||||||
|
|
||||||
if (!allocator_sessions_.empty()) {
|
if (!allocator_sessions_.empty()) {
|
||||||
allocator_session()->GetCandidateStatsFromReadyPorts(candidate_stats_list);
|
allocator_session()->GetCandidateStatsFromReadyPorts(
|
||||||
|
&ice_transport_stats->candidate_stats_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(qingsi): Remove naming inconsistency for candidate pair/connection.
|
// TODO(qingsi): Remove naming inconsistency for candidate pair/connection.
|
||||||
@ -1510,10 +1510,12 @@ bool P2PTransportChannel::GetStats(ConnectionInfos* candidate_pair_stats_list,
|
|||||||
stats.local_candidate = SanitizeLocalCandidate(stats.local_candidate);
|
stats.local_candidate = SanitizeLocalCandidate(stats.local_candidate);
|
||||||
stats.remote_candidate = SanitizeRemoteCandidate(stats.remote_candidate);
|
stats.remote_candidate = SanitizeRemoteCandidate(stats.remote_candidate);
|
||||||
stats.best_connection = (selected_connection_ == connection);
|
stats.best_connection = (selected_connection_ == connection);
|
||||||
candidate_pair_stats_list->push_back(std::move(stats));
|
ice_transport_stats->connection_infos.push_back(std::move(stats));
|
||||||
connection->set_reported(true);
|
connection->set_reported(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ice_transport_stats->selected_candidate_pair_changes =
|
||||||
|
selected_candidate_pair_changes_;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1991,6 +1993,8 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn,
|
|||||||
SignalCandidatePairChanged(pair_change);
|
SignalCandidatePairChanged(pair_change);
|
||||||
}
|
}
|
||||||
SignalNetworkRouteChanged(network_route_);
|
SignalNetworkRouteChanged(network_route_);
|
||||||
|
|
||||||
|
++selected_candidate_pair_changes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning: UpdateState should eventually be called whenever a connection
|
// Warning: UpdateState should eventually be called whenever a connection
|
||||||
|
|||||||
@ -131,8 +131,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal {
|
|||||||
int SetOption(rtc::Socket::Option opt, int value) override;
|
int SetOption(rtc::Socket::Option opt, int value) override;
|
||||||
bool GetOption(rtc::Socket::Option opt, int* value) override;
|
bool GetOption(rtc::Socket::Option opt, int* value) override;
|
||||||
int GetError() override;
|
int GetError() override;
|
||||||
bool GetStats(std::vector<ConnectionInfo>* candidate_pair_stats_list,
|
bool GetStats(IceTransportStats* ice_transport_stats) override;
|
||||||
std::vector<CandidateStats>* candidate_stats_list) override;
|
|
||||||
absl::optional<int> GetRttEstimate() override;
|
absl::optional<int> GetRttEstimate() override;
|
||||||
const Connection* selected_connection() const override;
|
const Connection* selected_connection() const override;
|
||||||
absl::optional<const CandidatePair> GetSelectedCandidatePair() const override;
|
absl::optional<const CandidatePair> GetSelectedCandidatePair() const override;
|
||||||
@ -499,6 +498,9 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal {
|
|||||||
void AddRemoteCandidateWithResolver(Candidate candidate,
|
void AddRemoteCandidateWithResolver(Candidate candidate,
|
||||||
rtc::AsyncResolverInterface* resolver);
|
rtc::AsyncResolverInterface* resolver);
|
||||||
|
|
||||||
|
// Number of times the selected_connection_ has been modified.
|
||||||
|
uint32_t selected_candidate_pair_changes_ = 0;
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(P2PTransportChannel);
|
RTC_DISALLOW_COPY_AND_ASSIGN(P2PTransportChannel);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1231,13 +1231,13 @@ TEST_F(P2PTransportChannelTest, GetStats) {
|
|||||||
ep2_ch1()->writable(),
|
ep2_ch1()->writable(),
|
||||||
kMediumTimeout, clock);
|
kMediumTimeout, clock);
|
||||||
TestSendRecv(&clock);
|
TestSendRecv(&clock);
|
||||||
ConnectionInfos infos;
|
IceTransportStats ice_transport_stats;
|
||||||
CandidateStatsList candidate_stats_list;
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
ASSERT_TRUE(ep1_ch1()->GetStats(&infos, &candidate_stats_list));
|
ASSERT_GE(ice_transport_stats.connection_infos.size(), 1u);
|
||||||
ASSERT_GE(infos.size(), 1u);
|
ASSERT_GE(ice_transport_stats.candidate_stats_list.size(), 1u);
|
||||||
ASSERT_GE(candidate_stats_list.size(), 1u);
|
EXPECT_EQ(ice_transport_stats.selected_candidate_pair_changes, 1u);
|
||||||
ConnectionInfo* best_conn_info = nullptr;
|
ConnectionInfo* best_conn_info = nullptr;
|
||||||
for (ConnectionInfo& info : infos) {
|
for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
|
||||||
if (info.best_connection) {
|
if (info.best_connection) {
|
||||||
best_conn_info = &info;
|
best_conn_info = &info;
|
||||||
break;
|
break;
|
||||||
@ -1582,13 +1582,16 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveRemoteCandidateIsSanitized) {
|
|||||||
EXPECT_EQ(PRFLX_PORT_TYPE, pair_ep1->remote_candidate().type());
|
EXPECT_EQ(PRFLX_PORT_TYPE, pair_ep1->remote_candidate().type());
|
||||||
EXPECT_TRUE(pair_ep1->remote_candidate().address().ipaddr().IsNil());
|
EXPECT_TRUE(pair_ep1->remote_candidate().address().ipaddr().IsNil());
|
||||||
|
|
||||||
ConnectionInfos pair_stats;
|
IceTransportStats ice_transport_stats;
|
||||||
CandidateStatsList candidate_stats;
|
ep1_ch1()->GetStats(&ice_transport_stats);
|
||||||
ep1_ch1()->GetStats(&pair_stats, &candidate_stats);
|
|
||||||
// Check the candidate pair stats.
|
// Check the candidate pair stats.
|
||||||
ASSERT_EQ(1u, pair_stats.size());
|
ASSERT_EQ(1u, ice_transport_stats.connection_infos.size());
|
||||||
EXPECT_EQ(PRFLX_PORT_TYPE, pair_stats[0].remote_candidate.type());
|
EXPECT_EQ(PRFLX_PORT_TYPE,
|
||||||
EXPECT_TRUE(pair_stats[0].remote_candidate.address().ipaddr().IsNil());
|
ice_transport_stats.connection_infos[0].remote_candidate.type());
|
||||||
|
EXPECT_TRUE(ice_transport_stats.connection_infos[0]
|
||||||
|
.remote_candidate.address()
|
||||||
|
.ipaddr()
|
||||||
|
.IsNil());
|
||||||
|
|
||||||
// Let ep1 receive the remote candidate to update its type from prflx to host.
|
// Let ep1 receive the remote candidate to update its type from prflx to host.
|
||||||
ResumeCandidates(1);
|
ResumeCandidates(1);
|
||||||
@ -1608,12 +1611,14 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveRemoteCandidateIsSanitized) {
|
|||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
updated_pair_ep1->remote_candidate().address().EqualIPs(kPublicAddrs[1]));
|
updated_pair_ep1->remote_candidate().address().EqualIPs(kPublicAddrs[1]));
|
||||||
|
|
||||||
ep1_ch1()->GetStats(&pair_stats, &candidate_stats);
|
ep1_ch1()->GetStats(&ice_transport_stats);
|
||||||
// Check the candidate pair stats.
|
// Check the candidate pair stats.
|
||||||
ASSERT_EQ(1u, pair_stats.size());
|
ASSERT_EQ(1u, ice_transport_stats.connection_infos.size());
|
||||||
EXPECT_EQ(LOCAL_PORT_TYPE, pair_stats[0].remote_candidate.type());
|
EXPECT_EQ(LOCAL_PORT_TYPE,
|
||||||
EXPECT_TRUE(
|
ice_transport_stats.connection_infos[0].remote_candidate.type());
|
||||||
pair_stats[0].remote_candidate.address().EqualIPs(kPublicAddrs[1]));
|
EXPECT_TRUE(ice_transport_stats.connection_infos[0]
|
||||||
|
.remote_candidate.address()
|
||||||
|
.EqualIPs(kPublicAddrs[1]));
|
||||||
|
|
||||||
DestroyChannels();
|
DestroyChannels();
|
||||||
}
|
}
|
||||||
@ -5010,17 +5015,15 @@ TEST_F(P2PTransportChannelTest,
|
|||||||
ASSERT_EQ_WAIT(3u, ep1_ch1()->connections().size(), kMediumTimeout);
|
ASSERT_EQ_WAIT(3u, ep1_ch1()->connections().size(), kMediumTimeout);
|
||||||
ASSERT_EQ_WAIT(3u, ep2_ch1()->connections().size(), kMediumTimeout);
|
ASSERT_EQ_WAIT(3u, ep2_ch1()->connections().size(), kMediumTimeout);
|
||||||
|
|
||||||
ConnectionInfos connection_infos_ep1;
|
IceTransportStats ice_transport_stats1;
|
||||||
CandidateStatsList candidate_stats_list_ep1;
|
IceTransportStats ice_transport_stats2;
|
||||||
ConnectionInfos connection_infos_ep2;
|
ep1_ch1()->GetStats(&ice_transport_stats1);
|
||||||
CandidateStatsList candidate_stats_list_ep2;
|
ep2_ch1()->GetStats(&ice_transport_stats2);
|
||||||
ep1_ch1()->GetStats(&connection_infos_ep1, &candidate_stats_list_ep1);
|
EXPECT_EQ(3u, ice_transport_stats1.connection_infos.size());
|
||||||
ep2_ch1()->GetStats(&connection_infos_ep2, &candidate_stats_list_ep2);
|
EXPECT_EQ(3u, ice_transport_stats1.candidate_stats_list.size());
|
||||||
EXPECT_EQ(3u, connection_infos_ep1.size());
|
EXPECT_EQ(3u, ice_transport_stats2.connection_infos.size());
|
||||||
EXPECT_EQ(3u, candidate_stats_list_ep1.size());
|
|
||||||
EXPECT_EQ(3u, connection_infos_ep2.size());
|
|
||||||
// Check the stats of ep1 seen by ep1.
|
// Check the stats of ep1 seen by ep1.
|
||||||
for (const auto& connection_info : connection_infos_ep1) {
|
for (const auto& connection_info : ice_transport_stats1.connection_infos) {
|
||||||
const auto& local_candidate = connection_info.local_candidate;
|
const auto& local_candidate = connection_info.local_candidate;
|
||||||
if (local_candidate.type() == LOCAL_PORT_TYPE) {
|
if (local_candidate.type() == LOCAL_PORT_TYPE) {
|
||||||
EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
|
EXPECT_TRUE(local_candidate.address().IsUnresolvedIP());
|
||||||
@ -5037,7 +5040,7 @@ TEST_F(P2PTransportChannelTest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check the stats of ep1 seen by ep2.
|
// Check the stats of ep1 seen by ep2.
|
||||||
for (const auto& connection_info : connection_infos_ep2) {
|
for (const auto& connection_info : ice_transport_stats2.connection_infos) {
|
||||||
const auto& remote_candidate = connection_info.remote_candidate;
|
const auto& remote_candidate = connection_info.remote_candidate;
|
||||||
if (remote_candidate.type() == LOCAL_PORT_TYPE) {
|
if (remote_candidate.type() == LOCAL_PORT_TYPE) {
|
||||||
EXPECT_TRUE(remote_candidate.address().IsUnresolvedIP());
|
EXPECT_TRUE(remote_candidate.address().IsUnresolvedIP());
|
||||||
@ -5053,6 +5056,96 @@ TEST_F(P2PTransportChannelTest,
|
|||||||
DestroyChannels();
|
DestroyChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(P2PTransportChannelTest,
|
||||||
|
ConnectingIncreasesSelectedCandidatePairChanges) {
|
||||||
|
rtc::ScopedFakeClock clock;
|
||||||
|
ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
|
||||||
|
kDefaultPortAllocatorFlags);
|
||||||
|
CreateChannels();
|
||||||
|
|
||||||
|
IceTransportStats ice_transport_stats;
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
// Let the channels connect.
|
||||||
|
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
|
||||||
|
kMediumTimeout, clock);
|
||||||
|
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
DestroyChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(P2PTransportChannelTest,
|
||||||
|
DisconnectedIncreasesSelectedCandidatePairChanges) {
|
||||||
|
rtc::ScopedFakeClock clock;
|
||||||
|
ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
|
||||||
|
kDefaultPortAllocatorFlags);
|
||||||
|
CreateChannels();
|
||||||
|
|
||||||
|
IceTransportStats ice_transport_stats;
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
// Let the channels connect.
|
||||||
|
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
|
||||||
|
kMediumTimeout, clock);
|
||||||
|
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
// Prune connections and wait for disconnect.
|
||||||
|
for (Connection* con : ep1_ch1()->connections()) {
|
||||||
|
con->Prune();
|
||||||
|
}
|
||||||
|
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() == nullptr,
|
||||||
|
kMediumTimeout, clock);
|
||||||
|
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(2u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
DestroyChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(P2PTransportChannelTest,
|
||||||
|
NewSelectionIncreasesSelectedCandidatePairChanges) {
|
||||||
|
rtc::ScopedFakeClock clock;
|
||||||
|
ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
|
||||||
|
kDefaultPortAllocatorFlags);
|
||||||
|
CreateChannels();
|
||||||
|
|
||||||
|
IceTransportStats ice_transport_stats;
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(0u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
// Let the channels connect.
|
||||||
|
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
|
||||||
|
kMediumTimeout, clock);
|
||||||
|
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_EQ(1u, ice_transport_stats.selected_candidate_pair_changes);
|
||||||
|
|
||||||
|
// Prune the currently selected connection and wait for selection
|
||||||
|
// of a new one.
|
||||||
|
const Connection* selected_connection = ep1_ch1()->selected_connection();
|
||||||
|
for (Connection* con : ep1_ch1()->connections()) {
|
||||||
|
if (con == selected_connection) {
|
||||||
|
con->Prune();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPECT_TRUE_SIMULATED_WAIT(
|
||||||
|
ep1_ch1()->selected_connection() != nullptr &&
|
||||||
|
(ep1_ch1()->GetStats(&ice_transport_stats),
|
||||||
|
ice_transport_stats.selected_candidate_pair_changes >= 2u),
|
||||||
|
kMediumTimeout, clock);
|
||||||
|
|
||||||
|
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
|
||||||
|
EXPECT_GE(ice_transport_stats.selected_candidate_pair_changes, 2u);
|
||||||
|
|
||||||
|
DestroyChannels();
|
||||||
|
}
|
||||||
|
|
||||||
// A similar test as above to check the selected candidate pair is sanitized
|
// A similar test as above to check the selected candidate pair is sanitized
|
||||||
// when it is queried via GetSelectedCandidatePair.
|
// when it is queried via GetSelectedCandidatePair.
|
||||||
TEST_F(P2PTransportChannelTest,
|
TEST_F(P2PTransportChannelTest,
|
||||||
|
|||||||
@ -747,7 +747,7 @@ bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
|
|||||||
dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
|
dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
|
||||||
substats.dtls_state = dtls_transport->dtls_state();
|
substats.dtls_state = dtls_transport->dtls_state();
|
||||||
if (!dtls_transport->ice_transport()->GetStats(
|
if (!dtls_transport->ice_transport()->GetStats(
|
||||||
&substats.connection_infos, &substats.candidate_stats_list)) {
|
&substats.ice_transport_stats)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stats->channel_stats.push_back(substats);
|
stats->channel_stats.push_back(substats);
|
||||||
|
|||||||
@ -7251,7 +7251,7 @@ void PeerConnection::ReportBestConnectionState(
|
|||||||
for (const cricket::TransportChannelStats& channel_stats :
|
for (const cricket::TransportChannelStats& channel_stats :
|
||||||
stats.channel_stats) {
|
stats.channel_stats) {
|
||||||
for (const cricket::ConnectionInfo& connection_info :
|
for (const cricket::ConnectionInfo& connection_info :
|
||||||
channel_stats.connection_infos) {
|
channel_stats.ice_transport_stats.connection_infos) {
|
||||||
if (!connection_info.best_connection) {
|
if (!connection_info.best_connection) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1258,7 +1258,7 @@ void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
|
|||||||
std::string transport_id = RTCTransportStatsIDFromTransportChannel(
|
std::string transport_id = RTCTransportStatsIDFromTransportChannel(
|
||||||
transport_name, channel_stats.component);
|
transport_name, channel_stats.component);
|
||||||
for (const cricket::ConnectionInfo& info :
|
for (const cricket::ConnectionInfo& info :
|
||||||
channel_stats.connection_infos) {
|
channel_stats.ice_transport_stats.connection_infos) {
|
||||||
std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
|
std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
|
||||||
new RTCIceCandidatePairStats(
|
new RTCIceCandidatePairStats(
|
||||||
RTCIceCandidatePairStatsIDFromConnectionInfo(info),
|
RTCIceCandidatePairStatsIDFromConnectionInfo(info),
|
||||||
@ -1689,8 +1689,10 @@ void RTCStatsCollector::ProduceTransportStats_n(
|
|||||||
transport_stats->bytes_received = 0;
|
transport_stats->bytes_received = 0;
|
||||||
transport_stats->dtls_state =
|
transport_stats->dtls_state =
|
||||||
DtlsTransportStateToRTCDtlsTransportState(channel_stats.dtls_state);
|
DtlsTransportStateToRTCDtlsTransportState(channel_stats.dtls_state);
|
||||||
|
transport_stats->selected_candidate_pair_changes =
|
||||||
|
channel_stats.ice_transport_stats.selected_candidate_pair_changes;
|
||||||
for (const cricket::ConnectionInfo& info :
|
for (const cricket::ConnectionInfo& info :
|
||||||
channel_stats.connection_infos) {
|
channel_stats.ice_transport_stats.connection_infos) {
|
||||||
*transport_stats->bytes_sent += info.sent_total_bytes;
|
*transport_stats->bytes_sent += info.sent_total_bytes;
|
||||||
*transport_stats->bytes_received += info.recv_total_bytes;
|
*transport_stats->bytes_received += info.recv_total_bytes;
|
||||||
if (info.best_connection) {
|
if (info.best_connection) {
|
||||||
|
|||||||
@ -1135,35 +1135,35 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
|
|||||||
|
|
||||||
// Add candidate pairs to connection.
|
// Add candidate pairs to connection.
|
||||||
cricket::TransportChannelStats a_transport_channel_stats;
|
cricket::TransportChannelStats a_transport_channel_stats;
|
||||||
a_transport_channel_stats.connection_infos.push_back(
|
a_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
cricket::ConnectionInfo());
|
cricket::ConnectionInfo());
|
||||||
a_transport_channel_stats.connection_infos[0].local_candidate =
|
a_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
*a_local_host.get();
|
.local_candidate = *a_local_host.get();
|
||||||
a_transport_channel_stats.connection_infos[0].remote_candidate =
|
a_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
*a_remote_srflx.get();
|
.remote_candidate = *a_remote_srflx.get();
|
||||||
a_transport_channel_stats.connection_infos.push_back(
|
a_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
cricket::ConnectionInfo());
|
cricket::ConnectionInfo());
|
||||||
a_transport_channel_stats.connection_infos[1].local_candidate =
|
a_transport_channel_stats.ice_transport_stats.connection_infos[1]
|
||||||
*a_local_prflx.get();
|
.local_candidate = *a_local_prflx.get();
|
||||||
a_transport_channel_stats.connection_infos[1].remote_candidate =
|
a_transport_channel_stats.ice_transport_stats.connection_infos[1]
|
||||||
*a_remote_relay.get();
|
.remote_candidate = *a_remote_relay.get();
|
||||||
a_transport_channel_stats.connection_infos.push_back(
|
a_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
cricket::ConnectionInfo());
|
cricket::ConnectionInfo());
|
||||||
a_transport_channel_stats.connection_infos[2].local_candidate =
|
a_transport_channel_stats.ice_transport_stats.connection_infos[2]
|
||||||
*a_local_relay.get();
|
.local_candidate = *a_local_relay.get();
|
||||||
a_transport_channel_stats.connection_infos[2].remote_candidate =
|
a_transport_channel_stats.ice_transport_stats.connection_infos[2]
|
||||||
*a_remote_relay.get();
|
.remote_candidate = *a_remote_relay.get();
|
||||||
|
|
||||||
pc_->AddVoiceChannel("audio", "a");
|
pc_->AddVoiceChannel("audio", "a");
|
||||||
pc_->SetTransportStats("a", a_transport_channel_stats);
|
pc_->SetTransportStats("a", a_transport_channel_stats);
|
||||||
|
|
||||||
cricket::TransportChannelStats b_transport_channel_stats;
|
cricket::TransportChannelStats b_transport_channel_stats;
|
||||||
b_transport_channel_stats.connection_infos.push_back(
|
b_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
cricket::ConnectionInfo());
|
cricket::ConnectionInfo());
|
||||||
b_transport_channel_stats.connection_infos[0].local_candidate =
|
b_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
*b_local.get();
|
.local_candidate = *b_local.get();
|
||||||
b_transport_channel_stats.connection_infos[0].remote_candidate =
|
b_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
*b_remote.get();
|
.remote_candidate = *b_remote.get();
|
||||||
|
|
||||||
pc_->AddVideoChannel("video", "b");
|
pc_->AddVideoChannel("video", "b");
|
||||||
pc_->SetTransportStats("b", b_transport_channel_stats);
|
pc_->SetTransportStats("b", b_transport_channel_stats);
|
||||||
@ -1225,7 +1225,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
|||||||
|
|
||||||
cricket::TransportChannelStats transport_channel_stats;
|
cricket::TransportChannelStats transport_channel_stats;
|
||||||
transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
||||||
transport_channel_stats.connection_infos.push_back(connection_info);
|
transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
|
connection_info);
|
||||||
|
|
||||||
pc_->AddVideoChannel("video", kTransportName);
|
pc_->AddVideoChannel("video", kTransportName);
|
||||||
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
||||||
@ -1266,7 +1267,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
|||||||
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
||||||
|
|
||||||
// Set nominated and "GetStats" again.
|
// Set nominated and "GetStats" again.
|
||||||
transport_channel_stats.connection_infos[0].nominated = true;
|
transport_channel_stats.ice_transport_stats.connection_infos[0].nominated =
|
||||||
|
true;
|
||||||
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
||||||
report = stats_->GetFreshStatsReport();
|
report = stats_->GetFreshStatsReport();
|
||||||
expected_pair.nominated = true;
|
expected_pair.nominated = true;
|
||||||
@ -1277,8 +1279,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
|||||||
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
||||||
|
|
||||||
// Set round trip times and "GetStats" again.
|
// Set round trip times and "GetStats" again.
|
||||||
transport_channel_stats.connection_infos[0].total_round_trip_time_ms = 7331;
|
transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
transport_channel_stats.connection_infos[0].current_round_trip_time_ms = 1337;
|
.total_round_trip_time_ms = 7331;
|
||||||
|
transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
|
.current_round_trip_time_ms = 1337;
|
||||||
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
||||||
report = stats_->GetFreshStatsReport();
|
report = stats_->GetFreshStatsReport();
|
||||||
expected_pair.total_round_trip_time = 7.331;
|
expected_pair.total_round_trip_time = 7.331;
|
||||||
@ -1290,7 +1294,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
|||||||
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
||||||
|
|
||||||
// Make pair the current pair, clear bandwidth and "GetStats" again.
|
// Make pair the current pair, clear bandwidth and "GetStats" again.
|
||||||
transport_channel_stats.connection_infos[0].best_connection = true;
|
transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
|
.best_connection = true;
|
||||||
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
||||||
report = stats_->GetFreshStatsReport();
|
report = stats_->GetFreshStatsReport();
|
||||||
// |expected_pair.available_[outgoing/incoming]_bitrate| should still be
|
// |expected_pair.available_[outgoing/incoming]_bitrate| should still be
|
||||||
@ -2066,8 +2071,11 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
|||||||
rtp_connection_info.recv_total_bytes = 1337;
|
rtp_connection_info.recv_total_bytes = 1337;
|
||||||
cricket::TransportChannelStats rtp_transport_channel_stats;
|
cricket::TransportChannelStats rtp_transport_channel_stats;
|
||||||
rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
||||||
rtp_transport_channel_stats.connection_infos.push_back(rtp_connection_info);
|
rtp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
|
rtp_connection_info);
|
||||||
rtp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_NEW;
|
rtp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_NEW;
|
||||||
|
rtp_transport_channel_stats.ice_transport_stats
|
||||||
|
.selected_candidate_pair_changes = 1;
|
||||||
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
|
||||||
|
|
||||||
// Get stats without RTCP, an active connection or certificates.
|
// Get stats without RTCP, an active connection or certificates.
|
||||||
@ -2080,6 +2088,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
|||||||
expected_rtp_transport.bytes_sent = 42;
|
expected_rtp_transport.bytes_sent = 42;
|
||||||
expected_rtp_transport.bytes_received = 1337;
|
expected_rtp_transport.bytes_received = 1337;
|
||||||
expected_rtp_transport.dtls_state = RTCDtlsTransportState::kNew;
|
expected_rtp_transport.dtls_state = RTCDtlsTransportState::kNew;
|
||||||
|
expected_rtp_transport.selected_candidate_pair_changes = 1;
|
||||||
|
|
||||||
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@ -2095,7 +2104,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
|||||||
cricket::TransportChannelStats rtcp_transport_channel_stats;
|
cricket::TransportChannelStats rtcp_transport_channel_stats;
|
||||||
rtcp_transport_channel_stats.component =
|
rtcp_transport_channel_stats.component =
|
||||||
cricket::ICE_CANDIDATE_COMPONENT_RTCP;
|
cricket::ICE_CANDIDATE_COMPONENT_RTCP;
|
||||||
rtcp_transport_channel_stats.connection_infos.push_back(rtcp_connection_info);
|
rtcp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
||||||
|
rtcp_connection_info);
|
||||||
rtcp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_CONNECTING;
|
rtcp_transport_channel_stats.dtls_state = cricket::DTLS_TRANSPORT_CONNECTING;
|
||||||
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
|
||||||
rtcp_transport_channel_stats});
|
rtcp_transport_channel_stats});
|
||||||
@ -2110,9 +2120,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
|||||||
expected_rtcp_transport.bytes_sent = 1337;
|
expected_rtcp_transport.bytes_sent = 1337;
|
||||||
expected_rtcp_transport.bytes_received = 42;
|
expected_rtcp_transport.bytes_received = 42;
|
||||||
expected_rtcp_transport.dtls_state = RTCDtlsTransportState::kConnecting;
|
expected_rtcp_transport.dtls_state = RTCDtlsTransportState::kConnecting;
|
||||||
|
expected_rtcp_transport.selected_candidate_pair_changes = 0;
|
||||||
|
|
||||||
expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
|
expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
|
||||||
|
|
||||||
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
expected_rtp_transport,
|
expected_rtp_transport,
|
||||||
@ -2123,7 +2133,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
|||||||
report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
|
report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
|
||||||
|
|
||||||
// Get stats with an active connection (selected candidate pair).
|
// Get stats with an active connection (selected candidate pair).
|
||||||
rtcp_transport_channel_stats.connection_infos[0].best_connection = true;
|
rtcp_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
||||||
|
.best_connection = true;
|
||||||
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
|
||||||
rtcp_transport_channel_stats});
|
rtcp_transport_channel_stats});
|
||||||
|
|
||||||
|
|||||||
@ -959,6 +959,8 @@ class RTCStatsReportVerifier {
|
|||||||
RTCCertificateStats::kType);
|
RTCCertificateStats::kType);
|
||||||
verifier.TestMemberIsIDReference(transport.remote_certificate_id,
|
verifier.TestMemberIsIDReference(transport.remote_certificate_id,
|
||||||
RTCCertificateStats::kType);
|
RTCCertificateStats::kType);
|
||||||
|
verifier.TestMemberIsPositive<uint32_t>(
|
||||||
|
transport.selected_candidate_pair_changes);
|
||||||
return verifier.ExpectAllMembersSuccessfullyTested();
|
return verifier.ExpectAllMembersSuccessfullyTested();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -865,13 +865,13 @@ void StatsCollector::ExtractSessionInfo() {
|
|||||||
// not paired. Also, the candidate report generated in
|
// not paired. Also, the candidate report generated in
|
||||||
// AddConnectionInfoReport do not report port stats like StunStats.
|
// AddConnectionInfoReport do not report port stats like StunStats.
|
||||||
for (const cricket::CandidateStats& stats :
|
for (const cricket::CandidateStats& stats :
|
||||||
channel_iter.candidate_stats_list) {
|
channel_iter.ice_transport_stats.candidate_stats_list) {
|
||||||
AddCandidateReport(stats, true);
|
AddCandidateReport(stats, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int connection_id = 0;
|
int connection_id = 0;
|
||||||
for (const cricket::ConnectionInfo& info :
|
for (const cricket::ConnectionInfo& info :
|
||||||
channel_iter.connection_infos) {
|
channel_iter.ice_transport_stats.connection_infos) {
|
||||||
StatsReport* connection_report = AddConnectionInfoReport(
|
StatsReport* connection_report = AddConnectionInfoReport(
|
||||||
transport_name, channel_iter.component, connection_id++,
|
transport_name, channel_iter.component, connection_id++,
|
||||||
channel_report->id(), info);
|
channel_report->id(), info);
|
||||||
|
|||||||
@ -1296,7 +1296,7 @@ TEST_F(StatsCollectorTest, IceCandidateReport) {
|
|||||||
connection_info.local_candidate = local;
|
connection_info.local_candidate = local;
|
||||||
connection_info.remote_candidate = remote;
|
connection_info.remote_candidate = remote;
|
||||||
TransportChannelStats channel_stats;
|
TransportChannelStats channel_stats;
|
||||||
channel_stats.connection_infos.push_back(connection_info);
|
channel_stats.ice_transport_stats.connection_infos.push_back(connection_info);
|
||||||
|
|
||||||
pc->AddVoiceChannel("audio", kTransportName);
|
pc->AddVoiceChannel("audio", kTransportName);
|
||||||
pc->SetTransportStats(kTransportName, channel_stats);
|
pc->SetTransportStats(kTransportName, channel_stats);
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "p2p/base/dtls_transport_internal.h"
|
#include "p2p/base/dtls_transport_internal.h"
|
||||||
|
#include "p2p/base/ice_transport_internal.h"
|
||||||
#include "p2p/base/port.h"
|
#include "p2p/base/port.h"
|
||||||
#include "rtc_base/ssl_stream_adapter.h"
|
#include "rtc_base/ssl_stream_adapter.h"
|
||||||
|
|
||||||
@ -26,11 +27,10 @@ struct TransportChannelStats {
|
|||||||
~TransportChannelStats();
|
~TransportChannelStats();
|
||||||
|
|
||||||
int component = 0;
|
int component = 0;
|
||||||
CandidateStatsList candidate_stats_list;
|
|
||||||
ConnectionInfos connection_infos;
|
|
||||||
int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
|
int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
|
||||||
int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
|
int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
|
||||||
DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
|
DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
|
||||||
|
IceTransportStats ice_transport_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information about all the channels of a transport.
|
// Information about all the channels of a transport.
|
||||||
|
|||||||
@ -868,7 +868,8 @@ WEBRTC_RTCSTATS_IMPL(RTCTransportStats, RTCStats, "transport",
|
|||||||
&dtls_state,
|
&dtls_state,
|
||||||
&selected_candidate_pair_id,
|
&selected_candidate_pair_id,
|
||||||
&local_certificate_id,
|
&local_certificate_id,
|
||||||
&remote_certificate_id)
|
&remote_certificate_id,
|
||||||
|
&selected_candidate_pair_changes)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RTCTransportStats::RTCTransportStats(const std::string& id,
|
RTCTransportStats::RTCTransportStats(const std::string& id,
|
||||||
@ -883,7 +884,8 @@ RTCTransportStats::RTCTransportStats(std::string&& id, int64_t timestamp_us)
|
|||||||
dtls_state("dtlsState"),
|
dtls_state("dtlsState"),
|
||||||
selected_candidate_pair_id("selectedCandidatePairId"),
|
selected_candidate_pair_id("selectedCandidatePairId"),
|
||||||
local_certificate_id("localCertificateId"),
|
local_certificate_id("localCertificateId"),
|
||||||
remote_certificate_id("remoteCertificateId") {}
|
remote_certificate_id("remoteCertificateId"),
|
||||||
|
selected_candidate_pair_changes("selectedCandidatePairChanges") {}
|
||||||
|
|
||||||
RTCTransportStats::RTCTransportStats(const RTCTransportStats& other)
|
RTCTransportStats::RTCTransportStats(const RTCTransportStats& other)
|
||||||
: RTCStats(other.id(), other.timestamp_us()),
|
: RTCStats(other.id(), other.timestamp_us()),
|
||||||
@ -893,7 +895,8 @@ RTCTransportStats::RTCTransportStats(const RTCTransportStats& other)
|
|||||||
dtls_state(other.dtls_state),
|
dtls_state(other.dtls_state),
|
||||||
selected_candidate_pair_id(other.selected_candidate_pair_id),
|
selected_candidate_pair_id(other.selected_candidate_pair_id),
|
||||||
local_certificate_id(other.local_certificate_id),
|
local_certificate_id(other.local_certificate_id),
|
||||||
remote_certificate_id(other.remote_certificate_id) {}
|
remote_certificate_id(other.remote_certificate_id),
|
||||||
|
selected_candidate_pair_changes(other.selected_candidate_pair_changes) {}
|
||||||
|
|
||||||
RTCTransportStats::~RTCTransportStats() {}
|
RTCTransportStats::~RTCTransportStats() {}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user