Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(368)

Side by Side Diff: webrtc/api/rtcstatscollector.cc

Issue 2408363002: RTCTransportStats added. (Closed)
Patch Set: Addressed comments, RTP and RTCP Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
21 #include "webrtc/p2p/base/p2pconstants.h"
22 #include "webrtc/p2p/base/port.h" 22 #include "webrtc/p2p/base/port.h"
23 23
24 namespace webrtc { 24 namespace webrtc {
25 25
26 namespace {
27
28 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) {
29 return "RTCCertificate_" + fingerprint;
30 }
31
32 std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
33 const cricket::ConnectionInfo& info) {
34 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" +
35 info.remote_candidate.id();
36 }
37
38 std::string RTCTransportStatsIDFromTransportChannel(
39 const std::string& transport_name, int channel_component) {
40 return "RTCTransport_" + transport_name + "_" +
41 rtc::ToString<>(channel_component);
42 }
43
44 } // namespace
45
26 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { 46 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) {
27 if (type == cricket::LOCAL_PORT_TYPE) 47 if (type == cricket::LOCAL_PORT_TYPE)
28 return RTCIceCandidateType::kHost; 48 return RTCIceCandidateType::kHost;
29 if (type == cricket::STUN_PORT_TYPE) 49 if (type == cricket::STUN_PORT_TYPE)
30 return RTCIceCandidateType::kSrflx; 50 return RTCIceCandidateType::kSrflx;
31 if (type == cricket::PRFLX_PORT_TYPE) 51 if (type == cricket::PRFLX_PORT_TYPE)
32 return RTCIceCandidateType::kPrflx; 52 return RTCIceCandidateType::kPrflx;
33 if (type == cricket::RELAY_PORT_TYPE) 53 if (type == cricket::RELAY_PORT_TYPE)
34 return RTCIceCandidateType::kRelay; 54 return RTCIceCandidateType::kRelay;
35 RTC_NOTREACHED(); 55 RTC_NOTREACHED();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 cached_report_ = nullptr; 120 cached_report_ = nullptr;
101 } 121 }
102 122
103 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( 123 void RTCStatsCollector::ProducePartialResultsOnSignalingThread(
104 int64_t timestamp_us) { 124 int64_t timestamp_us) {
105 RTC_DCHECK(signaling_thread_->IsCurrent()); 125 RTC_DCHECK(signaling_thread_->IsCurrent());
106 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); 126 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create();
107 127
108 SessionStats session_stats; 128 SessionStats session_stats;
109 if (pc_->session()->GetTransportStats(&session_stats)) { 129 if (pc_->session()->GetTransportStats(&session_stats)) {
110 ProduceCertificateStats_s(timestamp_us, session_stats, report.get()); 130 std::map<std::string, CertificateStatsPair> transport_cert_stats =
111 ProduceIceCandidateAndPairStats_s(timestamp_us, session_stats, 131 PrepareTransportCertificateStats_s(session_stats);
112 report.get()); 132
133 ProduceCertificateStats_s(
134 timestamp_us, transport_cert_stats, report.get());
135 ProduceIceCandidateAndPairStats_s(
136 timestamp_us, session_stats, report.get());
137 ProduceTransportStats_s(
138 timestamp_us, session_stats, transport_cert_stats, report.get());
113 } 139 }
114 ProducePeerConnectionStats_s(timestamp_us, report.get()); 140 ProducePeerConnectionStats_s(timestamp_us, report.get());
115 141
116 AddPartialResults(report); 142 AddPartialResults(report);
117 } 143 }
118 144
119 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( 145 void RTCStatsCollector::ProducePartialResultsOnWorkerThread(
120 int64_t timestamp_us) { 146 int64_t timestamp_us) {
121 RTC_DCHECK(worker_thread_->IsCurrent()); 147 RTC_DCHECK(worker_thread_->IsCurrent());
122 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); 148 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 RTC_DCHECK(!callbacks_.empty()); 196 RTC_DCHECK(!callbacks_.empty());
171 RTC_DCHECK(cached_report_); 197 RTC_DCHECK(cached_report_);
172 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback : 198 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback :
173 callbacks_) { 199 callbacks_) {
174 callback->OnStatsDelivered(cached_report_); 200 callback->OnStatsDelivered(cached_report_);
175 } 201 }
176 callbacks_.clear(); 202 callbacks_.clear();
177 } 203 }
178 204
179 void RTCStatsCollector::ProduceCertificateStats_s( 205 void RTCStatsCollector::ProduceCertificateStats_s(
180 int64_t timestamp_us, const SessionStats& session_stats, 206 int64_t timestamp_us,
207 const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
181 RTCStatsReport* report) const { 208 RTCStatsReport* report) const {
182 RTC_DCHECK(signaling_thread_->IsCurrent()); 209 RTC_DCHECK(signaling_thread_->IsCurrent());
183 for (const auto& transport_stats : session_stats.transport_stats) { 210 for (const auto& kvp : transport_cert_stats) {
184 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate; 211 if (kvp.second.local) {
185 if (pc_->session()->GetLocalCertificate( 212 ProduceCertificateStatsFromSSLCertificateStats_s(
186 transport_stats.second.transport_name, &local_certificate)) { 213 timestamp_us, *kvp.second.local.get(), report);
187 ProduceCertificateStatsFromSSLCertificateAndChain_s(
188 timestamp_us, local_certificate->ssl_certificate(), report);
189 } 214 }
190 std::unique_ptr<rtc::SSLCertificate> remote_certificate = 215 if (kvp.second.remote) {
191 pc_->session()->GetRemoteSSLCertificate( 216 ProduceCertificateStatsFromSSLCertificateStats_s(
192 transport_stats.second.transport_name); 217 timestamp_us, *kvp.second.remote.get(), report);
193 if (remote_certificate) {
194 ProduceCertificateStatsFromSSLCertificateAndChain_s(
195 timestamp_us, *remote_certificate.get(), report);
196 } 218 }
197 } 219 }
198 } 220 }
199 221
200 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateAndChain_s( 222 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateStats_s(
201 int64_t timestamp_us, const rtc::SSLCertificate& certificate, 223 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats,
202 RTCStatsReport* report) const { 224 RTCStatsReport* report) const {
203 RTC_DCHECK(signaling_thread_->IsCurrent()); 225 RTC_DCHECK(signaling_thread_->IsCurrent());
204 std::unique_ptr<rtc::SSLCertificateStats> ssl_stats = 226 RTCCertificateStats* prev_certificate_stats = nullptr;
205 certificate.GetStats(); 227 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()) { 228 s = s->issuer.get()) {
209 RTCCertificateStats* stats = new RTCCertificateStats( 229 RTCCertificateStats* certificate_stats = new RTCCertificateStats(
210 "RTCCertificate_" + s->fingerprint, timestamp_us); 230 RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us);
211 stats->fingerprint = s->fingerprint; 231 certificate_stats->fingerprint = s->fingerprint;
212 stats->fingerprint_algorithm = s->fingerprint_algorithm; 232 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm;
213 stats->base64_certificate = s->base64_certificate; 233 certificate_stats->base64_certificate = s->base64_certificate;
214 if (prev_stats) 234 if (prev_certificate_stats)
215 prev_stats->issuer_certificate_id = stats->id(); 235 prev_certificate_stats->issuer_certificate_id = certificate_stats->id();
216 report->AddStats(std::unique_ptr<RTCCertificateStats>(stats)); 236 report->AddStats(std::unique_ptr<RTCCertificateStats>(certificate_stats));
217 prev_stats = stats; 237 prev_certificate_stats = certificate_stats;
218 } 238 }
219 } 239 }
220 240
221 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( 241 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s(
222 int64_t timestamp_us, const SessionStats& session_stats, 242 int64_t timestamp_us, const SessionStats& session_stats,
223 RTCStatsReport* report) const { 243 RTCStatsReport* report) const {
224 RTC_DCHECK(signaling_thread_->IsCurrent()); 244 RTC_DCHECK(signaling_thread_->IsCurrent());
225 for (const auto& transport_stats : session_stats.transport_stats) { 245 for (const auto& transport_stats : session_stats.transport_stats) {
226 for (const auto& channel_stats : transport_stats.second.channel_stats) { 246 for (const auto& channel_stats : transport_stats.second.channel_stats) {
227 for (const cricket::ConnectionInfo& info : 247 for (const cricket::ConnectionInfo& info :
228 channel_stats.connection_infos) { 248 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( 249 std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
232 new RTCIceCandidatePairStats(id, timestamp_us)); 250 new RTCIceCandidatePairStats(
251 RTCIceCandidatePairStatsIDFromConnectionInfo(info),
252 timestamp_us));
233 253
234 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, 254 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members,
235 // crbug.com/633550. 255 // crbug.com/633550.
236 256
237 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to 257 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to
238 // RTCTransportStats which does not exist yet: crbug.com/653873. 258 // RTCTransportStats which does not exist yet: crbug.com/653873.
239 259
240 // TODO(hbos): There could be other candidates that are not paired with 260 // 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 261 // anything. We don't have a complete list. Local candidates come from
242 // Port objects, and prflx candidates (both local and remote) are only 262 // Port objects, and prflx candidates (both local and remote) are only
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 // There is always just one |RTCPeerConnectionStats| so its |id| can be a 350 // There is always just one |RTCPeerConnectionStats| so its |id| can be a
331 // constant. 351 // constant.
332 std::unique_ptr<RTCPeerConnectionStats> stats( 352 std::unique_ptr<RTCPeerConnectionStats> stats(
333 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); 353 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us));
334 stats->data_channels_opened = data_channels_opened; 354 stats->data_channels_opened = data_channels_opened;
335 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - 355 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) -
336 data_channels_opened; 356 data_channels_opened;
337 report->AddStats(std::move(stats)); 357 report->AddStats(std::move(stats));
338 } 358 }
339 359
360 void RTCStatsCollector::ProduceTransportStats_s(
361 int64_t timestamp_us, const SessionStats& session_stats,
362 const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
363 RTCStatsReport* report) const {
364 RTC_DCHECK(signaling_thread_->IsCurrent());
365 for (const auto& transport : session_stats.transport_stats) {
366 // Get reference to RTCP channel, if it exists.
367 std::string rtcp_transport_stats_id;
368 for (const auto& channel_stats : transport.second.channel_stats) {
369 if (channel_stats.component ==
370 cricket::ICE_CANDIDATE_COMPONENT_RTCP) {
371 rtcp_transport_stats_id = RTCTransportStatsIDFromTransportChannel(
372 transport.second.transport_name, channel_stats.component);
373 break;
374 }
375 }
376
377 // Get reference to local and remote certificates of this transport, if they
378 // exist.
379 const auto& certificate_stats_it = transport_cert_stats.find(
380 transport.second.transport_name);
381 RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend());
382 std::string local_certificate_id;
383 if (certificate_stats_it->second.local) {
384 local_certificate_id = RTCCertificateIDFromFingerprint(
385 certificate_stats_it->second.local->fingerprint);
386 }
387 std::string remote_certificate_id;
388 if (certificate_stats_it->second.remote) {
389 remote_certificate_id = RTCCertificateIDFromFingerprint(
390 certificate_stats_it->second.remote->fingerprint);
391 }
392
393 // There is one transport stats for each channel.
394 for (const auto& channel_stats : transport.second.channel_stats) {
395 std::unique_ptr<RTCTransportStats> transport_stats(
396 new RTCTransportStats(
397 RTCTransportStatsIDFromTransportChannel(
398 transport.second.transport_name, channel_stats.component),
399 timestamp_us));
400 transport_stats->bytes_sent = 0;
401 transport_stats->bytes_received = 0;
402 transport_stats->active_connection = false;
403 for (const cricket::ConnectionInfo& info :
404 channel_stats.connection_infos) {
405 *transport_stats->bytes_sent += info.sent_total_bytes;
406 *transport_stats->bytes_received += info.recv_total_bytes;
407 if (info.best_connection) {
408 transport_stats->active_connection = true;
409 transport_stats->selected_candidate_pair_id =
410 RTCIceCandidatePairStatsIDFromConnectionInfo(info);
411 }
412 }
413 if (channel_stats.component != cricket::ICE_CANDIDATE_COMPONENT_RTCP &&
414 !rtcp_transport_stats_id.empty()) {
415 transport_stats->rtcp_transport_stats_id = rtcp_transport_stats_id;
416 }
417 if (!local_certificate_id.empty())
418 transport_stats->local_certificate_id = local_certificate_id;
419 if (!remote_certificate_id.empty())
420 transport_stats->remote_certificate_id = remote_certificate_id;
421 report->AddStats(std::move(transport_stats));
422 }
423 }
424 }
425
426 std::map<std::string, RTCStatsCollector::CertificateStatsPair>
427 RTCStatsCollector::PrepareTransportCertificateStats_s(
428 const SessionStats& session_stats) const {
429 RTC_DCHECK(signaling_thread_->IsCurrent());
430 std::map<std::string, CertificateStatsPair> transport_cert_stats;
431 for (const auto& transport_stats : session_stats.transport_stats) {
432 CertificateStatsPair certificate_stats_pair;
433 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate;
434 if (pc_->session()->GetLocalCertificate(
435 transport_stats.second.transport_name, &local_certificate)) {
436 certificate_stats_pair.local =
437 local_certificate->ssl_certificate().GetStats();
438 }
439 std::unique_ptr<rtc::SSLCertificate> remote_certificate =
440 pc_->session()->GetRemoteSSLCertificate(
441 transport_stats.second.transport_name);
442 if (remote_certificate) {
443 certificate_stats_pair.remote = remote_certificate->GetStats();
444 }
445 transport_cert_stats.insert(
446 std::make_pair(transport_stats.second.transport_name,
447 std::move(certificate_stats_pair)));
448 }
449 return transport_cert_stats;
450 }
451
340 } // namespace webrtc 452 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698