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" | 20 #include "webrtc/base/sslidentity.h" |
21 #include "webrtc/p2p/base/candidate.h" | 21 #include "webrtc/p2p/base/candidate.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 RTCIceCandidatePairStatsID(const cricket::ConnectionInfo& info) { | |
29 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" + | |
30 info.remote_candidate.id(); | |
31 } | |
32 | |
33 } // namespace | |
34 | |
26 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { | 35 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { |
27 if (type == cricket::LOCAL_PORT_TYPE) | 36 if (type == cricket::LOCAL_PORT_TYPE) |
28 return RTCIceCandidateType::kHost; | 37 return RTCIceCandidateType::kHost; |
29 if (type == cricket::STUN_PORT_TYPE) | 38 if (type == cricket::STUN_PORT_TYPE) |
30 return RTCIceCandidateType::kSrflx; | 39 return RTCIceCandidateType::kSrflx; |
31 if (type == cricket::PRFLX_PORT_TYPE) | 40 if (type == cricket::PRFLX_PORT_TYPE) |
32 return RTCIceCandidateType::kPrflx; | 41 return RTCIceCandidateType::kPrflx; |
33 if (type == cricket::RELAY_PORT_TYPE) | 42 if (type == cricket::RELAY_PORT_TYPE) |
34 return RTCIceCandidateType::kRelay; | 43 return RTCIceCandidateType::kRelay; |
35 RTC_NOTREACHED(); | 44 RTC_NOTREACHED(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 cached_report_ = nullptr; | 109 cached_report_ = nullptr; |
101 } | 110 } |
102 | 111 |
103 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( | 112 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( |
104 int64_t timestamp_us) { | 113 int64_t timestamp_us) { |
105 RTC_DCHECK(signaling_thread_->IsCurrent()); | 114 RTC_DCHECK(signaling_thread_->IsCurrent()); |
106 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); | 115 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
107 | 116 |
108 SessionStats session_stats; | 117 SessionStats session_stats; |
109 if (pc_->session()->GetTransportStats(&session_stats)) { | 118 if (pc_->session()->GetTransportStats(&session_stats)) { |
110 ProduceCertificateStats_s(timestamp_us, session_stats, report.get()); | 119 std::map<std::string, CertificateStatsPair> transport_certificates = |
111 ProduceIceCandidateAndPairStats_s(timestamp_us, session_stats, | 120 ProduceCertificateStats_s(timestamp_us, session_stats, report.get()); |
112 report.get()); | 121 ProduceIceCandidateAndPairStats_s( |
122 timestamp_us, session_stats, report.get()); | |
123 ProduceTransportStats_s( | |
124 timestamp_us, session_stats, transport_certificates, report.get()); | |
113 } | 125 } |
114 ProducePeerConnectionStats_s(timestamp_us, report.get()); | 126 ProducePeerConnectionStats_s(timestamp_us, report.get()); |
115 | 127 |
116 AddPartialResults(report); | 128 AddPartialResults(report); |
117 } | 129 } |
118 | 130 |
119 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( | 131 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( |
120 int64_t timestamp_us) { | 132 int64_t timestamp_us) { |
121 RTC_DCHECK(worker_thread_->IsCurrent()); | 133 RTC_DCHECK(worker_thread_->IsCurrent()); |
122 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); | 134 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 RTC_DCHECK(signaling_thread_->IsCurrent()); | 181 RTC_DCHECK(signaling_thread_->IsCurrent()); |
170 RTC_DCHECK(!callbacks_.empty()); | 182 RTC_DCHECK(!callbacks_.empty()); |
171 RTC_DCHECK(cached_report_); | 183 RTC_DCHECK(cached_report_); |
172 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback : | 184 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback : |
173 callbacks_) { | 185 callbacks_) { |
174 callback->OnStatsDelivered(cached_report_); | 186 callback->OnStatsDelivered(cached_report_); |
175 } | 187 } |
176 callbacks_.clear(); | 188 callbacks_.clear(); |
177 } | 189 } |
178 | 190 |
179 void RTCStatsCollector::ProduceCertificateStats_s( | 191 std::map<std::string, RTCStatsCollector::CertificateStatsPair> |
192 RTCStatsCollector::ProduceCertificateStats_s( | |
hta-webrtc
2016/10/12 22:52:35
I don't like this function. It's doing two things,
hbos
2016/10/17 19:33:13
Yes, that's much nicer. Done.
| |
180 int64_t timestamp_us, const SessionStats& session_stats, | 193 int64_t timestamp_us, const SessionStats& session_stats, |
181 RTCStatsReport* report) const { | 194 RTCStatsReport* report) const { |
182 RTC_DCHECK(signaling_thread_->IsCurrent()); | 195 RTC_DCHECK(signaling_thread_->IsCurrent()); |
196 std::map<std::string, CertificateStatsPair> transport_certificates; | |
183 for (const auto& transport_stats : session_stats.transport_stats) { | 197 for (const auto& transport_stats : session_stats.transport_stats) { |
198 CertificateStatsPair certificate_stats_pair; | |
184 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate; | 199 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate; |
185 if (pc_->session()->GetLocalCertificate( | 200 if (pc_->session()->GetLocalCertificate( |
186 transport_stats.second.transport_name, &local_certificate)) { | 201 transport_stats.second.transport_name, &local_certificate)) { |
187 ProduceCertificateStatsFromSSLCertificateAndChain_s( | 202 certificate_stats_pair.local = |
188 timestamp_us, local_certificate->ssl_certificate(), report); | 203 ProduceCertificateStatsFromSSLCertificateAndChain_s( |
204 timestamp_us, local_certificate->ssl_certificate(), report); | |
189 } | 205 } |
190 std::unique_ptr<rtc::SSLCertificate> remote_certificate = | 206 std::unique_ptr<rtc::SSLCertificate> remote_certificate = |
191 pc_->session()->GetRemoteSSLCertificate( | 207 pc_->session()->GetRemoteSSLCertificate( |
192 transport_stats.second.transport_name); | 208 transport_stats.second.transport_name); |
193 if (remote_certificate) { | 209 if (remote_certificate) { |
194 ProduceCertificateStatsFromSSLCertificateAndChain_s( | 210 certificate_stats_pair.remote = |
195 timestamp_us, *remote_certificate.get(), report); | 211 ProduceCertificateStatsFromSSLCertificateAndChain_s( |
212 timestamp_us, *remote_certificate.get(), report); | |
213 } | |
214 if (certificate_stats_pair.local && certificate_stats_pair.remote) { | |
215 transport_certificates.insert( | |
216 std::make_pair(transport_stats.second.transport_name, | |
217 std::move(certificate_stats_pair))); | |
196 } | 218 } |
197 } | 219 } |
220 return transport_certificates; | |
198 } | 221 } |
199 | 222 |
200 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateAndChain_s( | 223 RTCCertificateStats* |
224 RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateAndChain_s( | |
hta-webrtc
2016/10/12 22:52:35
This one too is now dual-function.
hbos
2016/10/17 19:33:13
Done.
| |
201 int64_t timestamp_us, const rtc::SSLCertificate& certificate, | 225 int64_t timestamp_us, const rtc::SSLCertificate& certificate, |
202 RTCStatsReport* report) const { | 226 RTCStatsReport* report) const { |
203 RTC_DCHECK(signaling_thread_->IsCurrent()); | 227 RTC_DCHECK(signaling_thread_->IsCurrent()); |
204 std::unique_ptr<rtc::SSLCertificateStats> ssl_stats = | 228 std::unique_ptr<rtc::SSLCertificateStats> ssl_stats = |
205 certificate.GetStats(); | 229 certificate.GetStats(); |
206 RTCCertificateStats* prev_stats = nullptr; | 230 RTCCertificateStats* first_certificate_stats = nullptr; |
231 RTCCertificateStats* prev_certificate_stats = nullptr; | |
207 for (rtc::SSLCertificateStats* s = ssl_stats.get(); s; | 232 for (rtc::SSLCertificateStats* s = ssl_stats.get(); s; |
208 s = s->issuer.get()) { | 233 s = s->issuer.get()) { |
209 RTCCertificateStats* stats = new RTCCertificateStats( | 234 RTCCertificateStats* certificate_stats = new RTCCertificateStats( |
210 "RTCCertificate_" + s->fingerprint, timestamp_us); | 235 "RTCCertificate_" + s->fingerprint, timestamp_us); |
211 stats->fingerprint = s->fingerprint; | 236 certificate_stats->fingerprint = s->fingerprint; |
212 stats->fingerprint_algorithm = s->fingerprint_algorithm; | 237 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm; |
213 stats->base64_certificate = s->base64_certificate; | 238 certificate_stats->base64_certificate = s->base64_certificate; |
214 if (prev_stats) | 239 if (prev_certificate_stats) |
215 prev_stats->issuer_certificate_id = stats->id(); | 240 prev_certificate_stats->issuer_certificate_id = certificate_stats->id(); |
216 report->AddStats(std::unique_ptr<RTCCertificateStats>(stats)); | 241 report->AddStats(std::unique_ptr<RTCCertificateStats>(certificate_stats)); |
217 prev_stats = stats; | 242 if (!first_certificate_stats) |
243 first_certificate_stats = certificate_stats; | |
244 prev_certificate_stats = certificate_stats; | |
218 } | 245 } |
246 RTC_DCHECK(first_certificate_stats); | |
247 return first_certificate_stats; | |
219 } | 248 } |
220 | 249 |
221 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( | 250 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( |
222 int64_t timestamp_us, const SessionStats& session_stats, | 251 int64_t timestamp_us, const SessionStats& session_stats, |
223 RTCStatsReport* report) const { | 252 RTCStatsReport* report) const { |
224 RTC_DCHECK(signaling_thread_->IsCurrent()); | 253 RTC_DCHECK(signaling_thread_->IsCurrent()); |
225 for (const auto& transport_stats : session_stats.transport_stats) { | 254 for (const auto& transport_stats : session_stats.transport_stats) { |
226 for (const auto& channel_stats : transport_stats.second.channel_stats) { | 255 for (const auto& channel_stats : transport_stats.second.channel_stats) { |
227 for (const cricket::ConnectionInfo& info : | 256 for (const cricket::ConnectionInfo& info : |
228 channel_stats.connection_infos) { | 257 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( | 258 std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats( |
232 new RTCIceCandidatePairStats(id, timestamp_us)); | 259 new RTCIceCandidatePairStats(RTCIceCandidatePairStatsID(info), |
260 timestamp_us)); | |
233 | 261 |
234 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, | 262 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, |
235 // crbug.com/633550. | 263 // crbug.com/633550. |
236 | 264 |
237 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to | 265 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to |
238 // RTCTransportStats which does not exist yet: crbug.com/653873. | 266 // RTCTransportStats which does not exist yet: crbug.com/653873. |
239 | 267 |
240 // TODO(hbos): There could be other candidates that are not paired with | 268 // 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 | 269 // anything. We don't have a complete list. Local candidates come from |
242 // Port objects, and prflx candidates (both local and remote) are only | 270 // 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 | 358 // There is always just one |RTCPeerConnectionStats| so its |id| can be a |
331 // constant. | 359 // constant. |
332 std::unique_ptr<RTCPeerConnectionStats> stats( | 360 std::unique_ptr<RTCPeerConnectionStats> stats( |
333 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); | 361 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); |
334 stats->data_channels_opened = data_channels_opened; | 362 stats->data_channels_opened = data_channels_opened; |
335 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - | 363 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - |
336 data_channels_opened; | 364 data_channels_opened; |
337 report->AddStats(std::move(stats)); | 365 report->AddStats(std::move(stats)); |
338 } | 366 } |
339 | 367 |
368 void RTCStatsCollector::ProduceTransportStats_s( | |
369 int64_t timestamp_us, const SessionStats& session_stats, | |
370 const std::map<std::string, CertificateStatsPair>& transport_certificates, | |
371 RTCStatsReport* report) const { | |
372 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
373 for (const auto& transport : session_stats.transport_stats) { | |
374 std::unique_ptr<RTCTransportStats> transport_stats( | |
375 new RTCTransportStats("RTCTransport_" + transport.second.transport_name, | |
376 timestamp_us)); | |
377 transport_stats->bytes_sent = 0; | |
378 transport_stats->bytes_received = 0; | |
379 transport_stats->active_connection = false; | |
380 for (const auto& channel_stats : transport.second.channel_stats) { | |
381 for (const cricket::ConnectionInfo& info : | |
382 channel_stats.connection_infos) { | |
383 *transport_stats->bytes_sent += info.sent_total_bytes; | |
384 *transport_stats->bytes_received += info.recv_total_bytes; | |
385 if (info.best_connection) { | |
386 transport_stats->active_connection = true; | |
387 transport_stats->selected_candidate_pair_id = | |
388 RTCIceCandidatePairStatsID(info); | |
389 } | |
390 } | |
391 } | |
392 // TODO(hbos): Set transport_stats->rtcp_transport_stats_id. | |
393 // crbug.com/653873 | |
394 const auto& it = transport_certificates.find( | |
395 transport.second.transport_name); | |
396 if (it != transport_certificates.end()) { | |
397 transport_stats->local_certificate_id = it->second.local->id(); | |
398 transport_stats->remote_certificate_id = it->second.remote->id();; | |
399 } | |
400 report->AddStats(std::move(transport_stats)); | |
401 } | |
402 } | |
403 | |
340 } // namespace webrtc | 404 } // namespace webrtc |
OLD | NEW |