diff --git a/webrtc/api/rtcstatscollector.cc b/webrtc/api/rtcstatscollector.cc index 71f4725ae0..9052de4485 100644 --- a/webrtc/api/rtcstatscollector.cc +++ b/webrtc/api/rtcstatscollector.cc @@ -17,14 +17,30 @@ #include "webrtc/api/peerconnection.h" #include "webrtc/api/webrtcsession.h" #include "webrtc/base/checks.h" -#include "webrtc/base/sslidentity.h" #include "webrtc/p2p/base/candidate.h" +#include "webrtc/p2p/base/p2pconstants.h" #include "webrtc/p2p/base/port.h" namespace webrtc { namespace { +std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { + return "RTCCertificate_" + fingerprint; +} + +std::string RTCIceCandidatePairStatsIDFromConnectionInfo( + const cricket::ConnectionInfo& info) { + return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + + info.remote_candidate.id(); +} + +std::string RTCTransportStatsIDFromTransportChannel( + const std::string& transport_name, int channel_component) { + return "RTCTransport_" + transport_name + "_" + + rtc::ToString<>(channel_component); +} + const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { if (type == cricket::LOCAL_PORT_TYPE) return RTCIceCandidateType::kHost; @@ -128,9 +144,15 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThread( SessionStats session_stats; if (pc_->session()->GetTransportStats(&session_stats)) { - ProduceCertificateStats_s(timestamp_us, session_stats, report.get()); - ProduceIceCandidateAndPairStats_s(timestamp_us, session_stats, - report.get()); + std::map transport_cert_stats = + PrepareTransportCertificateStats_s(session_stats); + + ProduceCertificateStats_s( + timestamp_us, transport_cert_stats, report.get()); + ProduceIceCandidateAndPairStats_s( + timestamp_us, session_stats, report.get()); + ProduceTransportStats_s( + timestamp_us, session_stats, transport_cert_stats, report.get()); } ProduceDataChannelStats_s(timestamp_us, report.get()); ProducePeerConnectionStats_s(timestamp_us, report.get()); @@ -199,44 +221,38 @@ void RTCStatsCollector::DeliverCachedReport() { } void RTCStatsCollector::ProduceCertificateStats_s( - int64_t timestamp_us, const SessionStats& session_stats, + int64_t timestamp_us, + const std::map& transport_cert_stats, RTCStatsReport* report) const { RTC_DCHECK(signaling_thread_->IsCurrent()); - for (const auto& transport_stats : session_stats.transport_stats) { - rtc::scoped_refptr local_certificate; - if (pc_->session()->GetLocalCertificate( - transport_stats.second.transport_name, &local_certificate)) { - ProduceCertificateStatsFromSSLCertificateAndChain_s( - timestamp_us, local_certificate->ssl_certificate(), report); + for (const auto& kvp : transport_cert_stats) { + if (kvp.second.local) { + ProduceCertificateStatsFromSSLCertificateStats_s( + timestamp_us, *kvp.second.local.get(), report); } - std::unique_ptr remote_certificate = - pc_->session()->GetRemoteSSLCertificate( - transport_stats.second.transport_name); - if (remote_certificate) { - ProduceCertificateStatsFromSSLCertificateAndChain_s( - timestamp_us, *remote_certificate.get(), report); + if (kvp.second.remote) { + ProduceCertificateStatsFromSSLCertificateStats_s( + timestamp_us, *kvp.second.remote.get(), report); } } } -void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateAndChain_s( - int64_t timestamp_us, const rtc::SSLCertificate& certificate, +void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateStats_s( + int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats, RTCStatsReport* report) const { RTC_DCHECK(signaling_thread_->IsCurrent()); - std::unique_ptr ssl_stats = - certificate.GetStats(); - RTCCertificateStats* prev_stats = nullptr; - for (rtc::SSLCertificateStats* s = ssl_stats.get(); s; + RTCCertificateStats* prev_certificate_stats = nullptr; + for (const rtc::SSLCertificateStats* s = &certificate_stats; s; s = s->issuer.get()) { - RTCCertificateStats* stats = new RTCCertificateStats( - "RTCCertificate_" + s->fingerprint, timestamp_us); - stats->fingerprint = s->fingerprint; - stats->fingerprint_algorithm = s->fingerprint_algorithm; - stats->base64_certificate = s->base64_certificate; - if (prev_stats) - prev_stats->issuer_certificate_id = stats->id(); - report->AddStats(std::unique_ptr(stats)); - prev_stats = stats; + RTCCertificateStats* certificate_stats = new RTCCertificateStats( + RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us); + certificate_stats->fingerprint = s->fingerprint; + certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm; + certificate_stats->base64_certificate = s->base64_certificate; + if (prev_certificate_stats) + prev_certificate_stats->issuer_certificate_id = certificate_stats->id(); + report->AddStats(std::unique_ptr(certificate_stats)); + prev_certificate_stats = certificate_stats; } } @@ -270,10 +286,10 @@ void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( for (const auto& channel_stats : transport_stats.second.channel_stats) { for (const cricket::ConnectionInfo& info : channel_stats.connection_infos) { - const std::string& id = "RTCIceCandidatePair_" + - info.local_candidate.id() + "_" + info.remote_candidate.id(); std::unique_ptr candidate_pair_stats( - new RTCIceCandidatePairStats(id, timestamp_us)); + new RTCIceCandidatePairStats( + RTCIceCandidatePairStatsIDFromConnectionInfo(info), + timestamp_us)); // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, // crbug.com/633550. @@ -381,6 +397,98 @@ void RTCStatsCollector::ProducePeerConnectionStats_s( report->AddStats(std::move(stats)); } +void RTCStatsCollector::ProduceTransportStats_s( + int64_t timestamp_us, const SessionStats& session_stats, + const std::map& transport_cert_stats, + RTCStatsReport* report) const { + RTC_DCHECK(signaling_thread_->IsCurrent()); + for (const auto& transport : session_stats.transport_stats) { + // Get reference to RTCP channel, if it exists. + std::string rtcp_transport_stats_id; + for (const auto& channel_stats : transport.second.channel_stats) { + if (channel_stats.component == + cricket::ICE_CANDIDATE_COMPONENT_RTCP) { + rtcp_transport_stats_id = RTCTransportStatsIDFromTransportChannel( + transport.second.transport_name, channel_stats.component); + break; + } + } + + // Get reference to local and remote certificates of this transport, if they + // exist. + const auto& certificate_stats_it = transport_cert_stats.find( + transport.second.transport_name); + RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend()); + std::string local_certificate_id; + if (certificate_stats_it->second.local) { + local_certificate_id = RTCCertificateIDFromFingerprint( + certificate_stats_it->second.local->fingerprint); + } + std::string remote_certificate_id; + if (certificate_stats_it->second.remote) { + remote_certificate_id = RTCCertificateIDFromFingerprint( + certificate_stats_it->second.remote->fingerprint); + } + + // There is one transport stats for each channel. + for (const auto& channel_stats : transport.second.channel_stats) { + std::unique_ptr transport_stats( + new RTCTransportStats( + RTCTransportStatsIDFromTransportChannel( + transport.second.transport_name, channel_stats.component), + timestamp_us)); + transport_stats->bytes_sent = 0; + transport_stats->bytes_received = 0; + transport_stats->active_connection = false; + for (const cricket::ConnectionInfo& info : + channel_stats.connection_infos) { + *transport_stats->bytes_sent += info.sent_total_bytes; + *transport_stats->bytes_received += info.recv_total_bytes; + if (info.best_connection) { + transport_stats->active_connection = true; + transport_stats->selected_candidate_pair_id = + RTCIceCandidatePairStatsIDFromConnectionInfo(info); + } + } + if (channel_stats.component != cricket::ICE_CANDIDATE_COMPONENT_RTCP && + !rtcp_transport_stats_id.empty()) { + transport_stats->rtcp_transport_stats_id = rtcp_transport_stats_id; + } + if (!local_certificate_id.empty()) + transport_stats->local_certificate_id = local_certificate_id; + if (!remote_certificate_id.empty()) + transport_stats->remote_certificate_id = remote_certificate_id; + report->AddStats(std::move(transport_stats)); + } + } +} + +std::map +RTCStatsCollector::PrepareTransportCertificateStats_s( + const SessionStats& session_stats) const { + RTC_DCHECK(signaling_thread_->IsCurrent()); + std::map transport_cert_stats; + for (const auto& transport_stats : session_stats.transport_stats) { + CertificateStatsPair certificate_stats_pair; + rtc::scoped_refptr local_certificate; + if (pc_->session()->GetLocalCertificate( + transport_stats.second.transport_name, &local_certificate)) { + certificate_stats_pair.local = + local_certificate->ssl_certificate().GetStats(); + } + std::unique_ptr remote_certificate = + pc_->session()->GetRemoteSSLCertificate( + transport_stats.second.transport_name); + if (remote_certificate) { + certificate_stats_pair.remote = remote_certificate->GetStats(); + } + transport_cert_stats.insert( + std::make_pair(transport_stats.second.transport_name, + std::move(certificate_stats_pair))); + } + return transport_cert_stats; +} + const char* CandidateTypeToRTCIceCandidateTypeForTesting( const std::string& type) { return CandidateTypeToRTCIceCandidateType(type); diff --git a/webrtc/api/rtcstatscollector.h b/webrtc/api/rtcstatscollector.h index ae04e61e56..de374fc9a3 100644 --- a/webrtc/api/rtcstatscollector.h +++ b/webrtc/api/rtcstatscollector.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_API_RTCSTATSCOLLECTOR_H_ #define WEBRTC_API_RTCSTATSCOLLECTOR_H_ +#include #include #include @@ -20,6 +21,7 @@ #include "webrtc/base/asyncinvoker.h" #include "webrtc/base/refcount.h" #include "webrtc/base/scoped_ref_ptr.h" +#include "webrtc/base/sslidentity.h" #include "webrtc/base/timeutils.h" namespace cricket { @@ -76,15 +78,21 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface { const rtc::scoped_refptr& partial_report); private: + struct CertificateStatsPair { + std::unique_ptr local; + std::unique_ptr remote; + }; + void AddPartialResults_s(rtc::scoped_refptr partial_report); void DeliverCachedReport(); // Produces |RTCCertificateStats|. void ProduceCertificateStats_s( - int64_t timestamp_us, const SessionStats& session_stats, + int64_t timestamp_us, + const std::map& transport_cert_stats, RTCStatsReport* report) const; - void ProduceCertificateStatsFromSSLCertificateAndChain_s( - int64_t timestamp_us, const rtc::SSLCertificate& certificate, + void ProduceCertificateStatsFromSSLCertificateStats_s( + int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats, RTCStatsReport* report) const; // Produces |RTCDataChannelStats|. void ProduceDataChannelStats_s( @@ -99,6 +107,15 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface { // Produces |RTCPeerConnectionStats|. void ProducePeerConnectionStats_s( int64_t timestamp_us, RTCStatsReport* report) const; + // Produces |RTCTransportStats|. + void ProduceTransportStats_s( + int64_t timestamp_us, const SessionStats& session_stats, + const std::map& transport_cert_stats, + RTCStatsReport* report) const; + + // Helper function to stats-producing functions. + std::map + PrepareTransportCertificateStats_s(const SessionStats& session_stats) const; PeerConnection* const pc_; rtc::Thread* const signaling_thread_; diff --git a/webrtc/api/rtcstatscollector_unittest.cc b/webrtc/api/rtcstatscollector_unittest.cc index fb07e0b29e..0e7860a940 100644 --- a/webrtc/api/rtcstatscollector_unittest.cc +++ b/webrtc/api/rtcstatscollector_unittest.cc @@ -31,6 +31,7 @@ #include "webrtc/base/timeutils.h" #include "webrtc/logging/rtc_event_log/rtc_event_log.h" #include "webrtc/media/base/fakemediaengine.h" +#include "webrtc/p2p/base/p2pconstants.h" #include "webrtc/p2p/base/port.h" using testing::_; @@ -368,7 +369,7 @@ class RTCStatsCollectorTest : public testing::Test { const std::string& id = "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + info.remote_candidate.id(); const RTCStats* stats = report->Get(id); - EXPECT_TRUE(stats); + ASSERT_TRUE(stats); const RTCIceCandidatePairStats& candidate_pair_stats = stats->cast_to(); @@ -427,7 +428,7 @@ class RTCStatsCollectorTest : public testing::Test { for (size_t i = 0; i < cert_info.fingerprints.size(); ++i) { const RTCStats* stats = report->Get( "RTCCertificate_" + cert_info.fingerprints[i]); - EXPECT_TRUE(stats); + ASSERT_TRUE(stats); const RTCCertificateStats& cert_stats = stats->cast_to(); EXPECT_EQ(*cert_stats.fingerprint, cert_info.fingerprints[i]); @@ -442,6 +443,72 @@ class RTCStatsCollectorTest : public testing::Test { } } + void ExpectReportContainsTransportStats( + const rtc::scoped_refptr& report, + const cricket::TransportStats& transport, + const CertificateInfo* local_certinfo, + const CertificateInfo* remote_certinfo) { + std::string rtcp_transport_stats_id; + for (const auto& channel_stats : transport.channel_stats) { + if (channel_stats.component == cricket::ICE_CANDIDATE_COMPONENT_RTCP) { + rtcp_transport_stats_id = "RTCTransport_" + transport.transport_name + + "_" + rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTCP); + } + } + for (const auto& channel_stats : transport.channel_stats) { + const cricket::ConnectionInfo* best_connection_info = nullptr; + const RTCStats* stats = report->Get( + "RTCTransport_" + transport.transport_name + "_" + + rtc::ToString<>(channel_stats.component)); + ASSERT_TRUE(stats); + const RTCTransportStats& transport_stats = + stats->cast_to(); + uint64_t bytes_sent = 0; + uint64_t bytes_received = 0; + for (const cricket::ConnectionInfo& info : + channel_stats.connection_infos) { + bytes_sent += info.sent_total_bytes; + bytes_received += info.recv_total_bytes; + if (info.best_connection) + best_connection_info = &info; + } + EXPECT_EQ(*transport_stats.bytes_sent, bytes_sent); + EXPECT_EQ(*transport_stats.bytes_received, bytes_received); + if (best_connection_info) { + EXPECT_EQ(*transport_stats.active_connection, true); + // TODO(hbos): Instead of testing how the ID looks, test that the + // corresponding pair's IP addresses are equal to the IP addresses of + // the |best_connection_info| data. crbug.com/653873 + EXPECT_EQ(*transport_stats.selected_candidate_pair_id, + "RTCIceCandidatePair_" + + best_connection_info->local_candidate.id() + "_" + + best_connection_info->remote_candidate.id()); + EXPECT_TRUE(report->Get(*transport_stats.selected_candidate_pair_id)); + } else { + EXPECT_EQ(*transport_stats.active_connection, false); + EXPECT_FALSE(transport_stats.selected_candidate_pair_id.is_defined()); + } + if (channel_stats.component != cricket::ICE_CANDIDATE_COMPONENT_RTCP && + !rtcp_transport_stats_id.empty()) { + EXPECT_EQ(*transport_stats.rtcp_transport_stats_id, + rtcp_transport_stats_id); + } else { + EXPECT_FALSE(transport_stats.rtcp_transport_stats_id.is_defined()); + } + if (local_certinfo && remote_certinfo) { + EXPECT_EQ(*transport_stats.local_certificate_id, + "RTCCertificate_" + local_certinfo->fingerprints[0]); + EXPECT_EQ(*transport_stats.remote_certificate_id, + "RTCCertificate_" + remote_certinfo->fingerprints[0]); + EXPECT_TRUE(report->Get(*transport_stats.local_certificate_id)); + EXPECT_TRUE(report->Get(*transport_stats.remote_certificate_id)); + } else { + EXPECT_FALSE(transport_stats.local_certificate_id.is_defined()); + EXPECT_FALSE(transport_stats.remote_certificate_id.is_defined()); + } + } + } + void ExpectReportContainsDataChannel( const rtc::scoped_refptr& report, const DataChannel& data_channel) { @@ -849,7 +916,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { EXPECT_EQ(report->GetStatsOfType().size(), static_cast(1)) << "Expecting 1 RTCPeerConnectionStats."; stats = report->Get("RTCPeerConnection"); - EXPECT_TRUE(stats); + ASSERT_TRUE(stats); { // Expected stats with the above four data channels // TODO(hbos): When the |RTCPeerConnectionStats| is the number of data @@ -863,6 +930,105 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { } } +TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) { + std::unique_ptr rtp_local_candidate = CreateFakeCandidate( + "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42); + std::unique_ptr rtp_remote_candidate = + CreateFakeCandidate("42.42.42.42", 42, "protocol", + cricket::LOCAL_PORT_TYPE, 42); + std::unique_ptr rtcp_local_candidate = + CreateFakeCandidate("42.42.42.42", 42, "protocol", + cricket::LOCAL_PORT_TYPE, 42); + std::unique_ptr rtcp_remote_candidate = + CreateFakeCandidate("42.42.42.42", 42, "protocol", + cricket::LOCAL_PORT_TYPE, 42); + + SessionStats session_stats; + session_stats.transport_stats["transport"].transport_name = "transport"; + + cricket::ConnectionInfo rtp_connection_info; + rtp_connection_info.best_connection = false; + rtp_connection_info.local_candidate = *rtp_local_candidate.get(); + rtp_connection_info.remote_candidate = *rtp_remote_candidate.get(); + rtp_connection_info.sent_total_bytes = 42; + rtp_connection_info.recv_total_bytes = 1337; + cricket::TransportChannelStats rtp_transport_channel_stats; + rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP; + rtp_transport_channel_stats.connection_infos.push_back(rtp_connection_info); + session_stats.transport_stats["transport"].channel_stats.push_back( + rtp_transport_channel_stats); + + + // Mock the session to return the desired candidates. + EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke( + [this, &session_stats](SessionStats* stats) { + *stats = session_stats; + return true; + })); + + // Get stats without RTCP, an active connection or certificates. + rtc::scoped_refptr report = GetStatsReport(); + ExpectReportContainsTransportStats( + report, session_stats.transport_stats["transport"], nullptr, nullptr); + + cricket::ConnectionInfo rtcp_connection_info; + rtcp_connection_info.best_connection = false; + rtcp_connection_info.local_candidate = *rtcp_local_candidate.get(); + rtcp_connection_info.remote_candidate = *rtcp_remote_candidate.get(); + rtcp_connection_info.sent_total_bytes = 1337; + rtcp_connection_info.recv_total_bytes = 42; + cricket::TransportChannelStats rtcp_transport_channel_stats; + rtcp_transport_channel_stats.component = + cricket::ICE_CANDIDATE_COMPONENT_RTCP; + rtcp_transport_channel_stats.connection_infos.push_back(rtcp_connection_info); + session_stats.transport_stats["transport"].channel_stats.push_back( + rtcp_transport_channel_stats); + + collector_->ClearCachedStatsReport(); + // Get stats with RTCP and without an active connection or certificates. + report = GetStatsReport(); + ExpectReportContainsTransportStats( + report, session_stats.transport_stats["transport"], nullptr, nullptr); + + // Get stats with an active connection. + rtcp_connection_info.best_connection = true; + + collector_->ClearCachedStatsReport(); + report = GetStatsReport(); + ExpectReportContainsTransportStats( + report, session_stats.transport_stats["transport"], nullptr, nullptr); + + // Get stats with certificates. + std::unique_ptr local_certinfo = + CreateFakeCertificateAndInfoFromDers( + std::vector({ "(local) local", "(local) chain" })); + std::unique_ptr remote_certinfo = + CreateFakeCertificateAndInfoFromDers( + std::vector({ "(remote) local", "(remote) chain" })); + EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly( + Invoke([this, &local_certinfo](const std::string& transport_name, + rtc::scoped_refptr* certificate) { + if (transport_name == "transport") { + *certificate = local_certinfo->certificate; + return true; + } + return false; + })); + EXPECT_CALL(test_->session(), + GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke( + [this, &remote_certinfo](const std::string& transport_name) { + if (transport_name == "transport") + return remote_certinfo->certificate->ssl_certificate().GetReference(); + return static_cast(nullptr); + })); + + collector_->ClearCachedStatsReport(); + report = GetStatsReport(); + ExpectReportContainsTransportStats( + report, session_stats.transport_stats["transport"], + local_certinfo.get(), remote_certinfo.get()); +} + class RTCStatsCollectorTestWithFakeCollector : public testing::Test { public: RTCStatsCollectorTestWithFakeCollector() diff --git a/webrtc/api/stats/rtcstats_objects.h b/webrtc/api/stats/rtcstats_objects.h index ad6a39cdfe..4e8a3ee154 100644 --- a/webrtc/api/stats/rtcstats_objects.h +++ b/webrtc/api/stats/rtcstats_objects.h @@ -43,6 +43,45 @@ struct RTCIceCandidateType { static const char* kRelay; }; +// https://w3c.github.io/webrtc-stats/#certificatestats-dict* +class RTCCertificateStats final : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCCertificateStats(const std::string& id, int64_t timestamp_us); + RTCCertificateStats(std::string&& id, int64_t timestamp_us); + RTCCertificateStats(const RTCCertificateStats& other); + ~RTCCertificateStats() override; + + RTCStatsMember fingerprint; + RTCStatsMember fingerprint_algorithm; + RTCStatsMember base64_certificate; + RTCStatsMember issuer_certificate_id; +}; + +// https://w3c.github.io/webrtc-stats/#dcstats-dict* +class RTCDataChannelStats final : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCDataChannelStats(const std::string& id, int64_t timestamp_us); + RTCDataChannelStats(std::string&& id, int64_t timestamp_us); + RTCDataChannelStats(const RTCDataChannelStats& other); + ~RTCDataChannelStats() override; + + RTCStatsMember label; + RTCStatsMember protocol; + RTCStatsMember datachannelid; + // TODO(hbos): Support enum types? "RTCStatsMember"? + RTCStatsMember state; + RTCStatsMember messages_sent; + RTCStatsMember bytes_sent; + RTCStatsMember messages_received; + RTCStatsMember bytes_received; +}; + +// https://w3c.github.io/webrtc-stats/#candidatepair-dict* +// TODO(hbos): Finish implementation. Tracking bug crbug.com/633550 class RTCIceCandidatePairStats : public RTCStats { public: WEBRTC_RTCSTATS_DECL(); @@ -81,6 +120,7 @@ class RTCIceCandidatePairStats : public RTCStats { }; // https://w3c.github.io/webrtc-stats/#icecandidate-dict* +// TODO(hbos): Finish implementation. Tracking bug crbug.com/632723 class RTCIceCandidateStats : public RTCStats { public: WEBRTC_RTCSTATS_DECL(); @@ -121,45 +161,8 @@ class RTCRemoteIceCandidateStats final : public RTCIceCandidateStats { const char* type() const override; }; -// https://w3c.github.io/webrtc-stats/#certificatestats-dict* -class RTCCertificateStats final : public RTCStats { - public: - WEBRTC_RTCSTATS_DECL(); - - RTCCertificateStats(const std::string& id, int64_t timestamp_us); - RTCCertificateStats(std::string&& id, int64_t timestamp_us); - RTCCertificateStats(const RTCCertificateStats& other); - ~RTCCertificateStats() override; - - RTCStatsMember fingerprint; - RTCStatsMember fingerprint_algorithm; - RTCStatsMember base64_certificate; - RTCStatsMember issuer_certificate_id; -}; - -// https://w3c.github.io/webrtc-stats/#dcstats-dict* -class RTCDataChannelStats final : public RTCStats { - public: - WEBRTC_RTCSTATS_DECL(); - - RTCDataChannelStats(const std::string& id, int64_t timestamp_us); - RTCDataChannelStats(std::string&& id, int64_t timestamp_us); - RTCDataChannelStats(const RTCDataChannelStats& other); - ~RTCDataChannelStats() override; - - RTCStatsMember label; - RTCStatsMember protocol; - RTCStatsMember datachannelid; - // TODO(hbos): Support enum types? "RTCStatsMember"? - RTCStatsMember state; - RTCStatsMember messages_sent; - RTCStatsMember bytes_sent; - RTCStatsMember messages_received; - RTCStatsMember bytes_received; -}; - // https://w3c.github.io/webrtc-stats/#pcstats-dict* -// TODO(hbos): Tracking bug crbug.com/636818 +// TODO(hbos): Finish implementation. Tracking bug crbug.com/636818 class RTCPeerConnectionStats final : public RTCStats { public: WEBRTC_RTCSTATS_DECL(); @@ -173,6 +176,25 @@ class RTCPeerConnectionStats final : public RTCStats { RTCStatsMember data_channels_closed; }; +// https://w3c.github.io/webrtc-stats/#transportstats-dict* +class RTCTransportStats final : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCTransportStats(const std::string& id, int64_t timestamp_us); + RTCTransportStats(std::string&& id, int64_t timestamp_us); + RTCTransportStats(const RTCTransportStats& other); + ~RTCTransportStats() override; + + RTCStatsMember bytes_sent; + RTCStatsMember bytes_received; + RTCStatsMember rtcp_transport_stats_id; + RTCStatsMember active_connection; + RTCStatsMember selected_candidate_pair_id; + RTCStatsMember local_certificate_id; + RTCStatsMember remote_certificate_id; +}; + } // namespace webrtc #endif // WEBRTC_API_STATS_RTCSTATS_OBJECTS_H_ diff --git a/webrtc/stats/rtcstats_objects.cc b/webrtc/stats/rtcstats_objects.cc index 3d82d09e4a..6a4203ed0e 100644 --- a/webrtc/stats/rtcstats_objects.cc +++ b/webrtc/stats/rtcstats_objects.cc @@ -30,6 +30,82 @@ const char* RTCIceCandidateType::kSrflx = "srflx"; const char* RTCIceCandidateType::kPrflx = "prflx"; const char* RTCIceCandidateType::kRelay = "relay"; +WEBRTC_RTCSTATS_IMPL(RTCCertificateStats, RTCStats, "certificate", + &fingerprint, + &fingerprint_algorithm, + &base64_certificate, + &issuer_certificate_id); + +RTCCertificateStats::RTCCertificateStats( + const std::string& id, int64_t timestamp_us) + : RTCCertificateStats(std::string(id), timestamp_us) { +} + +RTCCertificateStats::RTCCertificateStats( + std::string&& id, int64_t timestamp_us) + : RTCStats(std::move(id), timestamp_us), + fingerprint("fingerprint"), + fingerprint_algorithm("fingerprintAlgorithm"), + base64_certificate("base64Certificate"), + issuer_certificate_id("issuerCertificateId") { +} + +RTCCertificateStats::RTCCertificateStats( + const RTCCertificateStats& other) + : RTCStats(other.id(), other.timestamp_us()), + fingerprint(other.fingerprint), + fingerprint_algorithm(other.fingerprint_algorithm), + base64_certificate(other.base64_certificate), + issuer_certificate_id(other.issuer_certificate_id) { +} + +RTCCertificateStats::~RTCCertificateStats() { +} + +WEBRTC_RTCSTATS_IMPL(RTCDataChannelStats, RTCStats, "data-channel", + &label, + &protocol, + &datachannelid, + &state, + &messages_sent, + &bytes_sent, + &messages_received, + &bytes_received); + +RTCDataChannelStats::RTCDataChannelStats( + const std::string& id, int64_t timestamp_us) + : RTCDataChannelStats(std::string(id), timestamp_us) { +} + +RTCDataChannelStats::RTCDataChannelStats( + std::string&& id, int64_t timestamp_us) + : RTCStats(std::move(id), timestamp_us), + label("label"), + protocol("protocol"), + datachannelid("datachannelid"), + state("state"), + messages_sent("messagesSent"), + bytes_sent("bytesSent"), + messages_received("messagesReceived"), + bytes_received("bytesReceived") { +} + +RTCDataChannelStats::RTCDataChannelStats( + const RTCDataChannelStats& other) + : RTCStats(other.id(), other.timestamp_us()), + label(other.label), + protocol(other.protocol), + datachannelid(other.datachannelid), + state(other.state), + messages_sent(other.messages_sent), + bytes_sent(other.bytes_sent), + messages_received(other.messages_received), + bytes_received(other.bytes_received) { +} + +RTCDataChannelStats::~RTCDataChannelStats() { +} + WEBRTC_RTCSTATS_IMPL(RTCIceCandidatePairStats, RTCStats, "candidate-pair", &transport_id, &local_candidate_id, @@ -191,82 +267,6 @@ const char* RTCRemoteIceCandidateStats::type() const { return kType; } -WEBRTC_RTCSTATS_IMPL(RTCCertificateStats, RTCStats, "certificate", - &fingerprint, - &fingerprint_algorithm, - &base64_certificate, - &issuer_certificate_id); - -RTCCertificateStats::RTCCertificateStats( - const std::string& id, int64_t timestamp_us) - : RTCCertificateStats(std::string(id), timestamp_us) { -} - -RTCCertificateStats::RTCCertificateStats( - std::string&& id, int64_t timestamp_us) - : RTCStats(std::move(id), timestamp_us), - fingerprint("fingerprint"), - fingerprint_algorithm("fingerprintAlgorithm"), - base64_certificate("base64Certificate"), - issuer_certificate_id("issuerCertificateId") { -} - -RTCCertificateStats::RTCCertificateStats( - const RTCCertificateStats& other) - : RTCStats(other.id(), other.timestamp_us()), - fingerprint(other.fingerprint), - fingerprint_algorithm(other.fingerprint_algorithm), - base64_certificate(other.base64_certificate), - issuer_certificate_id(other.issuer_certificate_id) { -} - -RTCCertificateStats::~RTCCertificateStats() { -} - -WEBRTC_RTCSTATS_IMPL(RTCDataChannelStats, RTCStats, "data-channel", - &label, - &protocol, - &datachannelid, - &state, - &messages_sent, - &bytes_sent, - &messages_received, - &bytes_received); - -RTCDataChannelStats::RTCDataChannelStats( - const std::string& id, int64_t timestamp_us) - : RTCDataChannelStats(std::string(id), timestamp_us) { -} - -RTCDataChannelStats::RTCDataChannelStats( - std::string&& id, int64_t timestamp_us) - : RTCStats(std::move(id), timestamp_us), - label("label"), - protocol("protocol"), - datachannelid("datachannelid"), - state("state"), - messages_sent("messagesSent"), - bytes_sent("bytesSent"), - messages_received("messagesReceived"), - bytes_received("bytesReceived") { -} - -RTCDataChannelStats::RTCDataChannelStats( - const RTCDataChannelStats& other) - : RTCStats(other.id(), other.timestamp_us()), - label(other.label), - protocol(other.protocol), - datachannelid(other.datachannelid), - state(other.state), - messages_sent(other.messages_sent), - bytes_sent(other.bytes_sent), - messages_received(other.messages_received), - bytes_received(other.bytes_received) { -} - -RTCDataChannelStats::~RTCDataChannelStats() { -} - WEBRTC_RTCSTATS_IMPL(RTCPeerConnectionStats, RTCStats, "peer-connection", &data_channels_opened, &data_channels_closed); @@ -293,4 +293,45 @@ RTCPeerConnectionStats::RTCPeerConnectionStats( RTCPeerConnectionStats::~RTCPeerConnectionStats() { } +WEBRTC_RTCSTATS_IMPL(RTCTransportStats, RTCStats, "transport", + &bytes_sent, + &bytes_received, + &rtcp_transport_stats_id, + &active_connection, + &selected_candidate_pair_id, + &local_certificate_id, + &remote_certificate_id); + +RTCTransportStats::RTCTransportStats( + const std::string& id, int64_t timestamp_us) + : RTCTransportStats(std::string(id), timestamp_us) { +} + +RTCTransportStats::RTCTransportStats( + std::string&& id, int64_t timestamp_us) + : RTCStats(std::move(id), timestamp_us), + bytes_sent("bytesSent"), + bytes_received("bytesReceived"), + rtcp_transport_stats_id("rtcpTransportStatsId"), + active_connection("activeConnection"), + selected_candidate_pair_id("selectedCandidatePairId"), + local_certificate_id("localCertificateId"), + remote_certificate_id("remoteCertificateId") { +} + +RTCTransportStats::RTCTransportStats( + const RTCTransportStats& other) + : RTCStats(other.id(), other.timestamp_us()), + bytes_sent(other.bytes_sent), + bytes_received(other.bytes_received), + rtcp_transport_stats_id(other.rtcp_transport_stats_id), + active_connection(other.active_connection), + selected_candidate_pair_id(other.selected_candidate_pair_id), + local_certificate_id(other.local_certificate_id), + remote_certificate_id(other.remote_certificate_id) { +} + +RTCTransportStats::~RTCTransportStats() { +} + } // namespace webrtc