Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/api/rtcstatscollector.h" | 11 #include "webrtc/api/rtcstatscollector.h" |
| 12 | 12 |
| 13 #include <memory> | 13 #include <memory> |
| 14 #include <utility> | 14 #include <utility> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "webrtc/api/peerconnection.h" | 17 #include "webrtc/api/peerconnection.h" |
| 18 #include "webrtc/api/webrtcsession.h" | 18 #include "webrtc/api/webrtcsession.h" |
| 19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/sslidentity.h" | |
| 21 #include "webrtc/p2p/base/candidate.h" | 20 #include "webrtc/p2p/base/candidate.h" |
| 22 #include "webrtc/p2p/base/port.h" | 21 #include "webrtc/p2p/base/port.h" |
| 23 | 22 |
| 24 namespace webrtc { | 23 namespace webrtc { |
| 25 | 24 |
| 25 namespace { | |
| 26 | |
| 27 std::string RTCCertificateID(const std::string& fingerprint) { | |
|
Taylor Brandstetter
2016/10/17 21:19:03
nit: "RTCCertificateID" sounds more like a class n
hbos
2016/10/19 16:30:00
Done.
| |
| 28 return "RTCCertificate_" + fingerprint; | |
| 29 } | |
| 30 | |
| 31 std::string RTCIceCandidatePairStatsID(const cricket::ConnectionInfo& info) { | |
| 32 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + | |
| 33 info.remote_candidate.id(); | |
| 34 } | |
| 35 | |
| 36 } // namespace | |
| 37 | |
| 26 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { | 38 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { |
| 27 if (type == cricket::LOCAL_PORT_TYPE) | 39 if (type == cricket::LOCAL_PORT_TYPE) |
| 28 return RTCIceCandidateType::kHost; | 40 return RTCIceCandidateType::kHost; |
| 29 if (type == cricket::STUN_PORT_TYPE) | 41 if (type == cricket::STUN_PORT_TYPE) |
| 30 return RTCIceCandidateType::kSrflx; | 42 return RTCIceCandidateType::kSrflx; |
| 31 if (type == cricket::PRFLX_PORT_TYPE) | 43 if (type == cricket::PRFLX_PORT_TYPE) |
| 32 return RTCIceCandidateType::kPrflx; | 44 return RTCIceCandidateType::kPrflx; |
| 33 if (type == cricket::RELAY_PORT_TYPE) | 45 if (type == cricket::RELAY_PORT_TYPE) |
| 34 return RTCIceCandidateType::kRelay; | 46 return RTCIceCandidateType::kRelay; |
| 35 RTC_NOTREACHED(); | 47 RTC_NOTREACHED(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 cached_report_ = nullptr; | 112 cached_report_ = nullptr; |
| 101 } | 113 } |
| 102 | 114 |
| 103 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( | 115 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( |
| 104 int64_t timestamp_us) { | 116 int64_t timestamp_us) { |
| 105 RTC_DCHECK(signaling_thread_->IsCurrent()); | 117 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 106 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); | 118 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
| 107 | 119 |
| 108 SessionStats session_stats; | 120 SessionStats session_stats; |
| 109 if (pc_->session()->GetTransportStats(&session_stats)) { | 121 if (pc_->session()->GetTransportStats(&session_stats)) { |
| 110 ProduceCertificateStats_s(timestamp_us, session_stats, report.get()); | 122 std::map<std::string, CertificateStatsPair> certificate_stats_map = |
| 111 ProduceIceCandidateAndPairStats_s(timestamp_us, session_stats, | 123 PrepareCertificateStatsMap_s(session_stats); |
| 112 report.get()); | 124 |
| 125 ProduceCertificateStats_s( | |
| 126 timestamp_us, session_stats, certificate_stats_map, report.get()); | |
| 127 ProduceIceCandidateAndPairStats_s( | |
| 128 timestamp_us, session_stats, report.get()); | |
| 129 ProduceTransportStats_s( | |
| 130 timestamp_us, session_stats, certificate_stats_map, report.get()); | |
| 113 } | 131 } |
| 114 ProducePeerConnectionStats_s(timestamp_us, report.get()); | 132 ProducePeerConnectionStats_s(timestamp_us, report.get()); |
| 115 | 133 |
| 116 AddPartialResults(report); | 134 AddPartialResults(report); |
| 117 } | 135 } |
| 118 | 136 |
| 119 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( | 137 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( |
| 120 int64_t timestamp_us) { | 138 int64_t timestamp_us) { |
| 121 RTC_DCHECK(worker_thread_->IsCurrent()); | 139 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 122 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); | 140 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 RTC_DCHECK(cached_report_); | 189 RTC_DCHECK(cached_report_); |
| 172 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback : | 190 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback : |
| 173 callbacks_) { | 191 callbacks_) { |
| 174 callback->OnStatsDelivered(cached_report_); | 192 callback->OnStatsDelivered(cached_report_); |
| 175 } | 193 } |
| 176 callbacks_.clear(); | 194 callbacks_.clear(); |
| 177 } | 195 } |
| 178 | 196 |
| 179 void RTCStatsCollector::ProduceCertificateStats_s( | 197 void RTCStatsCollector::ProduceCertificateStats_s( |
| 180 int64_t timestamp_us, const SessionStats& session_stats, | 198 int64_t timestamp_us, const SessionStats& session_stats, |
| 199 const std::map<std::string, CertificateStatsPair>& certificate_stats_map, | |
| 181 RTCStatsReport* report) const { | 200 RTCStatsReport* report) const { |
| 182 RTC_DCHECK(signaling_thread_->IsCurrent()); | 201 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 202 std::map<std::string, CertificateStatsPair> transport_certificates; | |
| 183 for (const auto& transport_stats : session_stats.transport_stats) { | 203 for (const auto& transport_stats : session_stats.transport_stats) { |
|
Taylor Brandstetter
2016/10/17 21:19:03
nit: Instead of iterating the transport stats and
hbos
2016/10/19 16:30:00
Oh yeah, done.
| |
| 184 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate; | 204 const auto& certificate_stats_it = certificate_stats_map.find( |
| 185 if (pc_->session()->GetLocalCertificate( | 205 transport_stats.second.transport_name); |
| 186 transport_stats.second.transport_name, &local_certificate)) { | 206 RTC_DCHECK(certificate_stats_it != certificate_stats_map.cend()); |
| 187 ProduceCertificateStatsFromSSLCertificateAndChain_s( | 207 if (certificate_stats_it->second.local) { |
| 188 timestamp_us, local_certificate->ssl_certificate(), report); | 208 ProduceCertificateStatsFromSSLCertificateStats_s( |
| 209 timestamp_us, *certificate_stats_it->second.local.get(), report); | |
| 189 } | 210 } |
| 190 std::unique_ptr<rtc::SSLCertificate> remote_certificate = | 211 if (certificate_stats_it->second.remote) { |
| 191 pc_->session()->GetRemoteSSLCertificate( | 212 ProduceCertificateStatsFromSSLCertificateStats_s( |
| 192 transport_stats.second.transport_name); | 213 timestamp_us, *certificate_stats_it->second.remote.get(), report); |
| 193 if (remote_certificate) { | |
| 194 ProduceCertificateStatsFromSSLCertificateAndChain_s( | |
| 195 timestamp_us, *remote_certificate.get(), report); | |
| 196 } | 214 } |
| 197 } | 215 } |
| 198 } | 216 } |
| 199 | 217 |
| 200 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateAndChain_s( | 218 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateStats_s( |
| 201 int64_t timestamp_us, const rtc::SSLCertificate& certificate, | 219 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats, |
| 202 RTCStatsReport* report) const { | 220 RTCStatsReport* report) const { |
| 203 RTC_DCHECK(signaling_thread_->IsCurrent()); | 221 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 204 std::unique_ptr<rtc::SSLCertificateStats> ssl_stats = | 222 RTCCertificateStats* prev_certificate_stats = nullptr; |
| 205 certificate.GetStats(); | 223 for (const rtc::SSLCertificateStats* s = &certificate_stats; s; |
| 206 RTCCertificateStats* prev_stats = nullptr; | |
| 207 for (rtc::SSLCertificateStats* s = ssl_stats.get(); s; | |
| 208 s = s->issuer.get()) { | 224 s = s->issuer.get()) { |
| 209 RTCCertificateStats* stats = new RTCCertificateStats( | 225 RTCCertificateStats* certificate_stats = new RTCCertificateStats( |
| 210 "RTCCertificate_" + s->fingerprint, timestamp_us); | 226 RTCCertificateID(s->fingerprint), timestamp_us); |
| 211 stats->fingerprint = s->fingerprint; | 227 certificate_stats->fingerprint = s->fingerprint; |
| 212 stats->fingerprint_algorithm = s->fingerprint_algorithm; | 228 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm; |
| 213 stats->base64_certificate = s->base64_certificate; | 229 certificate_stats->base64_certificate = s->base64_certificate; |
| 214 if (prev_stats) | 230 if (prev_certificate_stats) |
| 215 prev_stats->issuer_certificate_id = stats->id(); | 231 prev_certificate_stats->issuer_certificate_id = certificate_stats->id(); |
| 216 report->AddStats(std::unique_ptr<RTCCertificateStats>(stats)); | 232 report->AddStats(std::unique_ptr<RTCCertificateStats>(certificate_stats)); |
| 217 prev_stats = stats; | 233 prev_certificate_stats = certificate_stats; |
| 218 } | 234 } |
| 219 } | 235 } |
| 220 | 236 |
| 221 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( | 237 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( |
| 222 int64_t timestamp_us, const SessionStats& session_stats, | 238 int64_t timestamp_us, const SessionStats& session_stats, |
| 223 RTCStatsReport* report) const { | 239 RTCStatsReport* report) const { |
| 224 RTC_DCHECK(signaling_thread_->IsCurrent()); | 240 RTC_DCHECK(signaling_thread_->IsCurrent()); |
| 225 for (const auto& transport_stats : session_stats.transport_stats) { | 241 for (const auto& transport_stats : session_stats.transport_stats) { |
| 226 for (const auto& channel_stats : transport_stats.second.channel_stats) { | 242 for (const auto& channel_stats : transport_stats.second.channel_stats) { |
| 227 for (const cricket::ConnectionInfo& info : | 243 for (const cricket::ConnectionInfo& info : |
| 228 channel_stats.connection_infos) { | 244 channel_stats.connection_infos) { |
| 229 const std::string& id = "RTCIceCandidatePair_" + | |
| 230 info.local_candidate.id() + "_" + info.remote_candidate.id(); | |
| 231 std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats( | 245 std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats( |
| 232 new RTCIceCandidatePairStats(id, timestamp_us)); | 246 new RTCIceCandidatePairStats(RTCIceCandidatePairStatsID(info), |
| 247 timestamp_us)); | |
| 233 | 248 |
| 234 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, | 249 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, |
| 235 // crbug.com/633550. | 250 // crbug.com/633550. |
| 236 | 251 |
| 237 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to | 252 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to |
| 238 // RTCTransportStats which does not exist yet: crbug.com/653873. | 253 // RTCTransportStats which does not exist yet: crbug.com/653873. |
| 239 | 254 |
| 240 // TODO(hbos): There could be other candidates that are not paired with | 255 // TODO(hbos): There could be other candidates that are not paired with |
| 241 // anything. We don't have a complete list. Local candidates come from | 256 // anything. We don't have a complete list. Local candidates come from |
| 242 // Port objects, and prflx candidates (both local and remote) are only | 257 // Port objects, and prflx candidates (both local and remote) are only |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 // There is always just one |RTCPeerConnectionStats| so its |id| can be a | 345 // There is always just one |RTCPeerConnectionStats| so its |id| can be a |
| 331 // constant. | 346 // constant. |
| 332 std::unique_ptr<RTCPeerConnectionStats> stats( | 347 std::unique_ptr<RTCPeerConnectionStats> stats( |
| 333 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); | 348 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); |
| 334 stats->data_channels_opened = data_channels_opened; | 349 stats->data_channels_opened = data_channels_opened; |
| 335 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - | 350 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - |
| 336 data_channels_opened; | 351 data_channels_opened; |
| 337 report->AddStats(std::move(stats)); | 352 report->AddStats(std::move(stats)); |
| 338 } | 353 } |
| 339 | 354 |
| 355 void RTCStatsCollector::ProduceTransportStats_s( | |
| 356 int64_t timestamp_us, const SessionStats& session_stats, | |
| 357 const std::map<std::string, CertificateStatsPair>& certificate_stats_map, | |
| 358 RTCStatsReport* report) const { | |
| 359 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
| 360 for (const auto& transport : session_stats.transport_stats) { | |
|
Taylor Brandstetter
2016/10/17 21:19:03
Actually, if I understand the spec correctly, ther
hbos
2016/10/19 16:30:00
Thanks. Code updated.
If this is the case then RT
Taylor Brandstetter
2016/10/19 19:03:06
You will always have 1 for RTP, and 0 or 1 for RTC
| |
| 361 std::unique_ptr<RTCTransportStats> transport_stats( | |
| 362 new RTCTransportStats("RTCTransport_" + transport.second.transport_name, | |
| 363 timestamp_us)); | |
| 364 transport_stats->bytes_sent = 0; | |
| 365 transport_stats->bytes_received = 0; | |
| 366 transport_stats->active_connection = false; | |
| 367 for (const auto& channel_stats : transport.second.channel_stats) { | |
| 368 for (const cricket::ConnectionInfo& info : | |
| 369 channel_stats.connection_infos) { | |
| 370 *transport_stats->bytes_sent += info.sent_total_bytes; | |
| 371 *transport_stats->bytes_received += info.recv_total_bytes; | |
| 372 if (info.best_connection) { | |
| 373 transport_stats->active_connection = true; | |
| 374 transport_stats->selected_candidate_pair_id = | |
| 375 RTCIceCandidatePairStatsID(info); | |
| 376 } | |
| 377 } | |
| 378 } | |
| 379 // TODO(hbos): Set transport_stats->rtcp_transport_stats_id. | |
| 380 // crbug.com/653873 | |
|
Taylor Brandstetter
2016/10/17 21:19:03
There's no real reason why this couldn't be done i
hbos
2016/10/19 16:30:00
Done.
| |
| 381 const auto& certificate_stats_it = certificate_stats_map.find( | |
| 382 transport.second.transport_name); | |
| 383 RTC_DCHECK(certificate_stats_it != certificate_stats_map.cend()); | |
| 384 if (certificate_stats_it->second.local) { | |
| 385 transport_stats->local_certificate_id = | |
| 386 RTCCertificateID(certificate_stats_it->second.local->fingerprint); | |
| 387 } | |
| 388 if (certificate_stats_it->second.remote) { | |
| 389 transport_stats->remote_certificate_id = | |
| 390 RTCCertificateID(certificate_stats_it->second.remote->fingerprint); | |
| 391 } | |
| 392 report->AddStats(std::move(transport_stats)); | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 std::map<std::string, RTCStatsCollector::CertificateStatsPair> | |
| 397 RTCStatsCollector::PrepareCertificateStatsMap_s( | |
| 398 const SessionStats& session_stats) const { | |
| 399 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
| 400 std::map<std::string, CertificateStatsPair> transport_certificates; | |
| 401 for (const auto& transport_stats : session_stats.transport_stats) { | |
| 402 CertificateStatsPair certificate_stats_pair; | |
| 403 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate; | |
| 404 if (pc_->session()->GetLocalCertificate( | |
| 405 transport_stats.second.transport_name, &local_certificate)) { | |
| 406 certificate_stats_pair.local = | |
| 407 local_certificate->ssl_certificate().GetStats(); | |
| 408 } | |
| 409 std::unique_ptr<rtc::SSLCertificate> remote_certificate = | |
| 410 pc_->session()->GetRemoteSSLCertificate( | |
| 411 transport_stats.second.transport_name); | |
| 412 if (remote_certificate) { | |
| 413 certificate_stats_pair.remote = remote_certificate->GetStats(); | |
| 414 } | |
| 415 transport_certificates.insert( | |
| 416 std::make_pair(transport_stats.second.transport_name, | |
| 417 std::move(certificate_stats_pair))); | |
| 418 } | |
| 419 return transport_certificates; | |
| 420 } | |
| 421 | |
| 340 } // namespace webrtc | 422 } // namespace webrtc |
| OLD | NEW |