blob: 7dcbd134a1448c4b6f15eacae5b936a9e75a425d [file] [log] [blame]
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2014 The WebRTC project authors. All Rights Reserved.
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +00009 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#include "api/stats_types.h"
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +000012
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000013#include <string.h>
14
Steve Antona59dcc32019-03-25 13:53:07 -070015#include "absl/algorithm/container.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "rtc_base/ref_counted_object.h"
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000018
19// TODO(tommi): Could we have a static map of value name -> expected type
henrikg91d6ede2015-09-17 00:24:34 -070020// and use this to RTC_DCHECK on correct usage (somewhat strongly typed values)?
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000021// Alternatively, we could define the names+type in a separate document and
22// generate strongly typed inline C++ code that forces the correct type to be
23// used for a given name at compile time.
24
tommi@webrtc.org4b89aa02015-03-16 09:52:30 +000025using rtc::RefCountedObject;
tommi@webrtc.org8e327c42015-01-19 20:41:26 +000026
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +000027namespace webrtc {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000028namespace {
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +000029
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000030// The id of StatsReport of type kStatsReportTypeBwe.
31const char kStatsReportVideoBweId[] = "bweforvideo";
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000032
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000033// NOTE: These names need to be consistent with an external
34// specification (W3C Stats Identifiers).
35const char* InternalTypeToString(StatsReport::StatsType type) {
36 switch (type) {
37 case StatsReport::kStatsReportTypeSession:
38 return "googLibjingleSession";
39 case StatsReport::kStatsReportTypeBwe:
40 return "VideoBwe";
41 case StatsReport::kStatsReportTypeRemoteSsrc:
42 return "remoteSsrc";
43 case StatsReport::kStatsReportTypeSsrc:
44 return "ssrc";
45 case StatsReport::kStatsReportTypeTrack:
46 return "googTrack";
47 case StatsReport::kStatsReportTypeIceLocalCandidate:
48 return "localcandidate";
49 case StatsReport::kStatsReportTypeIceRemoteCandidate:
50 return "remotecandidate";
51 case StatsReport::kStatsReportTypeTransport:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +000052 return "transport";
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000053 case StatsReport::kStatsReportTypeComponent:
54 return "googComponent";
55 case StatsReport::kStatsReportTypeCandidatePair:
56 return "googCandidatePair";
57 case StatsReport::kStatsReportTypeCertificate:
58 return "googCertificate";
59 case StatsReport::kStatsReportTypeDataChannel:
60 return "datachannel";
61 }
nisseeb4ca4e2017-01-12 02:24:27 -080062 RTC_NOTREACHED();
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000063 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000064}
65
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000066class BandwidthEstimationId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000067 public:
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000068 BandwidthEstimationId()
69 : StatsReport::IdBase(StatsReport::kStatsReportTypeBwe) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000070 std::string ToString() const override { return kStatsReportVideoBweId; }
71};
tommi@webrtc.org8e327c42015-01-19 20:41:26 +000072
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000073class TypedId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000074 public:
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000075 TypedId(StatsReport::StatsType type, const std::string& id)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000076 : StatsReport::IdBase(type), id_(id) {}
tommi@webrtc.org8e327c42015-01-19 20:41:26 +000077
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000078 bool Equals(const IdBase& other) const override {
79 return IdBase::Equals(other) &&
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000080 static_cast<const TypedId&>(other).id_ == id_;
81 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000082
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000083 std::string ToString() const override {
84 return std::string(InternalTypeToString(type_)) + kSeparator + id_;
85 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000086
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +000087 protected:
88 const std::string id_;
89};
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +000090
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000091class TypedIntId : public StatsReport::IdBase {
decurtis@webrtc.org322a5642015-02-03 22:09:37 +000092 public:
93 TypedIntId(StatsReport::StatsType type, int id)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000094 : StatsReport::IdBase(type), id_(id) {}
decurtis@webrtc.org322a5642015-02-03 22:09:37 +000095
tommi@webrtc.orgd3900292015-03-12 16:35:55 +000096 bool Equals(const IdBase& other) const override {
97 return IdBase::Equals(other) &&
decurtis@webrtc.org322a5642015-02-03 22:09:37 +000098 static_cast<const TypedIntId&>(other).id_ == id_;
99 }
100
101 std::string ToString() const override {
Yves Gerey665174f2018-06-19 15:03:05 +0200102 return std::string(InternalTypeToString(type_)) + kSeparator +
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200103 rtc::ToString(id_);
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000104 }
105
106 protected:
107 const int id_;
108};
109
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000110class IdWithDirection : public TypedId {
111 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200112 IdWithDirection(StatsReport::StatsType type,
113 const std::string& id,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000114 StatsReport::Direction direction)
115 : TypedId(type, id), direction_(direction) {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000116
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000117 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000118 return TypedId::Equals(other) &&
119 static_cast<const IdWithDirection&>(other).direction_ == direction_;
120 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000121
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000122 std::string ToString() const override {
123 std::string ret(TypedId::ToString());
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000124 ret += kSeparator;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000125 ret += direction_ == StatsReport::kSend ? "send" : "recv";
126 return ret;
127 }
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000128
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000129 private:
130 const StatsReport::Direction direction_;
131};
132
133class CandidateId : public TypedId {
134 public:
135 CandidateId(bool local, const std::string& id)
Yves Gerey665174f2018-06-19 15:03:05 +0200136 : TypedId(local ? StatsReport::kStatsReportTypeIceLocalCandidate
137 : StatsReport::kStatsReportTypeIceRemoteCandidate,
138 id) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000139
Yves Gerey665174f2018-06-19 15:03:05 +0200140 std::string ToString() const override { return "Cand-" + id_; }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000141};
142
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000143class ComponentId : public StatsReport::IdBase {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000144 public:
145 ComponentId(const std::string& content_name, int component)
Yves Gerey665174f2018-06-19 15:03:05 +0200146 : ComponentId(StatsReport::kStatsReportTypeComponent,
147 content_name,
148 component) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000149
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000150 bool Equals(const IdBase& other) const override {
151 return IdBase::Equals(other) &&
Yves Gerey665174f2018-06-19 15:03:05 +0200152 static_cast<const ComponentId&>(other).component_ == component_ &&
153 static_cast<const ComponentId&>(other).content_name_ ==
154 content_name_;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000155 }
156
Yves Gerey665174f2018-06-19 15:03:05 +0200157 std::string ToString() const override { return ToString("Channel-"); }
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000158
159 protected:
Yves Gerey665174f2018-06-19 15:03:05 +0200160 ComponentId(StatsReport::StatsType type,
161 const std::string& content_name,
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000162 int component)
Yves Gerey665174f2018-06-19 15:03:05 +0200163 : IdBase(type), content_name_(content_name), component_(component) {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000164
165 std::string ToString(const char* prefix) const {
166 std::string ret(prefix);
167 ret += content_name_;
168 ret += '-';
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200169 ret += rtc::ToString(component_);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000170 return ret;
171 }
172
173 private:
174 const std::string content_name_;
175 const int component_;
176};
177
178class CandidatePairId : public ComponentId {
179 public:
180 CandidatePairId(const std::string& content_name, int component, int index)
Yves Gerey665174f2018-06-19 15:03:05 +0200181 : ComponentId(StatsReport::kStatsReportTypeCandidatePair,
182 content_name,
183 component),
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000184 index_(index) {}
185
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000186 bool Equals(const IdBase& other) const override {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000187 return ComponentId::Equals(other) &&
Yves Gerey665174f2018-06-19 15:03:05 +0200188 static_cast<const CandidatePairId&>(other).index_ == index_;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000189 }
190
191 std::string ToString() const override {
192 std::string ret(ComponentId::ToString("Conn-"));
193 ret += '-';
Jonas Olsson6b1985d2018-07-05 11:59:48 +0200194 ret += rtc::ToString(index_);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000195 return ret;
196 }
197
198 private:
199 const int index_;
200};
201
202} // namespace
203
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000204StatsReport::IdBase::IdBase(StatsType type) : type_(type) {}
205StatsReport::IdBase::~IdBase() {}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000206
Yves Gerey665174f2018-06-19 15:03:05 +0200207StatsReport::StatsType StatsReport::IdBase::type() const {
208 return type_;
209}
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000210
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000211bool StatsReport::IdBase::Equals(const IdBase& other) const {
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000212 return other.type_ == type_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000213}
214
Peter Boström0c4e06b2015-10-07 12:23:21 +0200215StatsReport::Value::Value(StatsValueName name, int64_t value, Type int_type)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000216 : name(name), type_(int_type) {
henrikg91d6ede2015-09-17 00:24:34 -0700217 RTC_DCHECK(type_ == kInt || type_ == kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000218 type_ == kInt ? value_.int_ = static_cast<int>(value) : value_.int64_ = value;
219}
220
221StatsReport::Value::Value(StatsValueName name, float f)
222 : name(name), type_(kFloat) {
223 value_.float_ = f;
224}
225
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000226StatsReport::Value::Value(StatsValueName name, const std::string& value)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000227 : name(name), type_(kString) {
228 value_.string_ = new std::string(value);
229}
230
231StatsReport::Value::Value(StatsValueName name, const char* value)
232 : name(name), type_(kStaticString) {
233 value_.static_string_ = value;
234}
235
236StatsReport::Value::Value(StatsValueName name, bool b)
237 : name(name), type_(kBool) {
238 value_.bool_ = b;
239}
240
241StatsReport::Value::Value(StatsValueName name, const Id& value)
242 : name(name), type_(kId) {
243 value_.id_ = new Id(value);
244}
245
246StatsReport::Value::~Value() {
247 switch (type_) {
248 case kInt:
249 case kInt64:
250 case kFloat:
251 case kBool:
252 case kStaticString:
253 break;
254 case kString:
255 delete value_.string_;
256 break;
257 case kId:
258 delete value_.id_;
259 break;
260 }
261}
262
263bool StatsReport::Value::Equals(const Value& other) const {
264 if (name != other.name)
265 return false;
266
267 // There's a 1:1 relation between a name and a type, so we don't have to
268 // check that.
henrikg91d6ede2015-09-17 00:24:34 -0700269 RTC_DCHECK_EQ(type_, other.type_);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000270
271 switch (type_) {
272 case kInt:
273 return value_.int_ == other.value_.int_;
274 case kInt64:
275 return value_.int64_ == other.value_.int64_;
276 case kFloat:
277 return value_.float_ == other.value_.float_;
278 case kStaticString: {
kwiberg5377bc72016-10-04 13:46:56 -0700279#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000280 if (value_.static_string_ != other.value_.static_string_) {
henrikg91d6ede2015-09-17 00:24:34 -0700281 RTC_DCHECK(strcmp(value_.static_string_, other.value_.static_string_) !=
282 0)
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000283 << "Duplicate global?";
284 }
285#endif
286 return value_.static_string_ == other.value_.static_string_;
287 }
288 case kString:
289 return *value_.string_ == *other.value_.string_;
290 case kBool:
291 return value_.bool_ == other.value_.bool_;
292 case kId:
293 return (*value_.id_)->Equals(*other.value_.id_);
294 }
295 RTC_NOTREACHED();
296 return false;
297}
298
299bool StatsReport::Value::operator==(const std::string& value) const {
300 return (type_ == kString && value_.string_->compare(value) == 0) ||
301 (type_ == kStaticString && value.compare(value_.static_string_) == 0);
302}
303
304bool StatsReport::Value::operator==(const char* value) const {
305 if (type_ == kString)
306 return value_.string_->compare(value) == 0;
307 if (type_ != kStaticString)
308 return false;
kwiberg5377bc72016-10-04 13:46:56 -0700309#if RTC_DCHECK_IS_ON
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000310 if (value_.static_string_ != value)
henrikg91d6ede2015-09-17 00:24:34 -0700311 RTC_DCHECK(strcmp(value_.static_string_, value) != 0)
312 << "Duplicate global?";
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000313#endif
314 return value == value_.static_string_;
315}
316
Peter Boström0c4e06b2015-10-07 12:23:21 +0200317bool StatsReport::Value::operator==(int64_t value) const {
Yves Gerey665174f2018-06-19 15:03:05 +0200318 return type_ == kInt ? value_.int_ == static_cast<int>(value)
319 : (type_ == kInt64 ? value_.int64_ == value : false);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000320}
321
322bool StatsReport::Value::operator==(bool value) const {
323 return type_ == kBool && value_.bool_ == value;
324}
325
326bool StatsReport::Value::operator==(float value) const {
327 return type_ == kFloat && value_.float_ == value;
328}
329
330bool StatsReport::Value::operator==(const Id& value) const {
331 return type_ == kId && (*value_.id_)->Equals(value);
332}
333
334int StatsReport::Value::int_val() const {
Ruslan Burakov2594f272019-03-12 11:10:57 +0100335 RTC_DCHECK_EQ(type_, kInt);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000336 return value_.int_;
337}
338
Peter Boström0c4e06b2015-10-07 12:23:21 +0200339int64_t StatsReport::Value::int64_val() const {
Ruslan Burakov2594f272019-03-12 11:10:57 +0100340 RTC_DCHECK_EQ(type_, kInt64);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000341 return value_.int64_;
342}
343
344float StatsReport::Value::float_val() const {
Ruslan Burakov2594f272019-03-12 11:10:57 +0100345 RTC_DCHECK_EQ(type_, kFloat);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000346 return value_.float_;
347}
348
349const char* StatsReport::Value::static_string_val() const {
Ruslan Burakov2594f272019-03-12 11:10:57 +0100350 RTC_DCHECK_EQ(type_, kStaticString);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000351 return value_.static_string_;
352}
353
354const std::string& StatsReport::Value::string_val() const {
Ruslan Burakov2594f272019-03-12 11:10:57 +0100355 RTC_DCHECK_EQ(type_, kString);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000356 return *value_.string_;
357}
358
359bool StatsReport::Value::bool_val() const {
Ruslan Burakov2594f272019-03-12 11:10:57 +0100360 RTC_DCHECK_EQ(type_, kBool);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000361 return value_.bool_;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000362}
363
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000364const char* StatsReport::Value::display_name() const {
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000365 switch (name) {
Minyue2a8a78c2016-04-07 16:48:15 +0200366 case kStatsValueNameAecDivergentFilterFraction:
367 return "aecDivergentFilterFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000368 case kStatsValueNameAudioOutputLevel:
369 return "audioOutputLevel";
370 case kStatsValueNameAudioInputLevel:
371 return "audioInputLevel";
372 case kStatsValueNameBytesSent:
373 return "bytesSent";
Steve Anton2dbc69f2017-08-24 17:15:13 -0700374 case kStatsValueNameConcealedSamples:
375 return "concealedSamples";
Gustaf Ullberg9a2e9062017-09-18 09:28:20 +0200376 case kStatsValueNameConcealmentEvents:
377 return "concealmentEvents";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000378 case kStatsValueNamePacketsSent:
379 return "packetsSent";
380 case kStatsValueNameBytesReceived:
381 return "bytesReceived";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000382 case kStatsValueNameLabel:
383 return "label";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000384 case kStatsValueNamePacketsReceived:
385 return "packetsReceived";
386 case kStatsValueNamePacketsLost:
387 return "packetsLost";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000388 case kStatsValueNameProtocol:
389 return "protocol";
Steve Anton2dbc69f2017-08-24 17:15:13 -0700390 case kStatsValueNameTotalSamplesReceived:
391 return "totalSamplesReceived";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000392 case kStatsValueNameTransportId:
393 return "transportId";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000394 case kStatsValueNameSelectedCandidatePairId:
395 return "selectedCandidatePairId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000396 case kStatsValueNameSsrc:
397 return "ssrc";
decurtis@webrtc.org487a4442015-01-15 22:55:07 +0000398 case kStatsValueNameState:
399 return "state";
400 case kStatsValueNameDataChannelId:
401 return "datachannelid";
sakale5ba44e2016-10-26 07:09:24 -0700402 case kStatsValueNameFramesDecoded:
403 return "framesDecoded";
sakal43536c32016-10-24 01:46:43 -0700404 case kStatsValueNameFramesEncoded:
405 return "framesEncoded";
Gustaf Ullbergb0a02072017-10-02 12:00:34 +0200406 case kStatsValueNameJitterBufferDelay:
407 return "jitterBufferDelay";
Peter Boströmb7d9a972015-12-18 16:01:11 +0100408 case kStatsValueNameCodecImplementationName:
409 return "codecImplementationName";
fippobec70ab2016-01-28 01:27:15 -0800410 case kStatsValueNameMediaType:
411 return "mediaType";
sakal87da4042016-10-31 06:53:47 -0700412 case kStatsValueNameQpSum:
413 return "qpSum";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000414 // 'goog' prefixed constants.
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200415 case kStatsValueNameAccelerateRate:
416 return "googAccelerateRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000417 case kStatsValueNameActiveConnection:
418 return "googActiveConnection";
419 case kStatsValueNameActualEncBitrate:
420 return "googActualEncBitrate";
421 case kStatsValueNameAvailableReceiveBandwidth:
422 return "googAvailableReceiveBandwidth";
423 case kStatsValueNameAvailableSendBandwidth:
424 return "googAvailableSendBandwidth";
425 case kStatsValueNameAvgEncodeMs:
426 return "googAvgEncodeMs";
427 case kStatsValueNameBucketDelay:
428 return "googBucketDelay";
429 case kStatsValueNameBandwidthLimitedResolution:
430 return "googBandwidthLimitedResolution";
zhihuang5ecf16c2016-06-01 17:09:15 -0700431 // STUN ping related attributes.
Qingsi Wang72a43a12018-02-20 16:03:18 -0800432 //
zhihuang5ecf16c2016-06-01 17:09:15 -0700433 // TODO(zhihuang) Rename these stats to follow the standards.
Qingsi Wang72a43a12018-02-20 16:03:18 -0800434 // Connectivity checks.
zhihuang5ecf16c2016-06-01 17:09:15 -0700435 case kStatsValueNameSentPingRequestsTotal:
436 return "requestsSent";
437 case kStatsValueNameSentPingRequestsBeforeFirstResponse:
438 return "consentRequestsSent";
439 case kStatsValueNameSentPingResponses:
440 return "responsesSent";
441 case kStatsValueNameRecvPingRequests:
442 return "requestsReceived";
443 case kStatsValueNameRecvPingResponses:
444 return "responsesReceived";
Qingsi Wang72a43a12018-02-20 16:03:18 -0800445 // STUN Keepalive pings.
446 case kStatsValueNameSentStunKeepaliveRequests:
447 return "stunKeepaliveRequestsSent";
448 case kStatsValueNameRecvStunKeepaliveResponses:
449 return "stunKeepaliveResponsesReceived";
450 case kStatsValueNameStunKeepaliveRttTotal:
451 return "stunKeepaliveRttTotal";
452 case kStatsValueNameStunKeepaliveRttSquaredTotal:
453 return "stunKeepaliveRttSquaredTotal";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000454
455 // Candidate related attributes. Values are taken from
456 // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
457 case kStatsValueNameCandidateIPAddress:
458 return "ipAddress";
459 case kStatsValueNameCandidateNetworkType:
460 return "networkType";
461 case kStatsValueNameCandidatePortNumber:
462 return "portNumber";
463 case kStatsValueNameCandidatePriority:
464 return "priority";
465 case kStatsValueNameCandidateTransportType:
466 return "transport";
467 case kStatsValueNameCandidateType:
468 return "candidateType";
469
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000470 case kStatsValueNameChannelId:
471 return "googChannelId";
472 case kStatsValueNameCodecName:
473 return "googCodecName";
474 case kStatsValueNameComponent:
475 return "googComponent";
476 case kStatsValueNameContentName:
477 return "googContentName";
ilnik2e1b40b2017-09-04 07:57:17 -0700478 case kStatsValueNameContentType:
479 return "googContentType";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000480 case kStatsValueNameCpuLimitedResolution:
481 return "googCpuLimitedResolution";
482 case kStatsValueNameDecodingCTSG:
483 return "googDecodingCTSG";
484 case kStatsValueNameDecodingCTN:
485 return "googDecodingCTN";
henrik.lundin63489782016-09-20 01:47:12 -0700486 case kStatsValueNameDecodingMutedOutput:
487 return "googDecodingMuted";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000488 case kStatsValueNameDecodingNormal:
489 return "googDecodingNormal";
490 case kStatsValueNameDecodingPLC:
491 return "googDecodingPLC";
Alex Narest5b5d97c2019-08-07 18:15:08 +0200492 case kStatsValueNameDecodingCodecPLC:
493 return "googDecodingCodecPLC";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000494 case kStatsValueNameDecodingCNG:
495 return "googDecodingCNG";
496 case kStatsValueNameDecodingPLCCNG:
497 return "googDecodingPLCCNG";
498 case kStatsValueNameDer:
499 return "googDerBase64";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000500 case kStatsValueNameDtlsCipher:
501 return "dtlsCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000502 case kStatsValueNameEchoDelayMedian:
503 return "googEchoCancellationEchoDelayMedian";
504 case kStatsValueNameEchoDelayStdDev:
505 return "googEchoCancellationEchoDelayStdDev";
506 case kStatsValueNameEchoReturnLoss:
507 return "googEchoCancellationReturnLoss";
508 case kStatsValueNameEchoReturnLossEnhancement:
509 return "googEchoCancellationReturnLossEnhancement";
510 case kStatsValueNameEncodeUsagePercent:
511 return "googEncodeUsagePercent";
512 case kStatsValueNameExpandRate:
513 return "googExpandRate";
514 case kStatsValueNameFingerprint:
515 return "googFingerprint";
516 case kStatsValueNameFingerprintAlgorithm:
517 return "googFingerprintAlgorithm";
518 case kStatsValueNameFirsReceived:
519 return "googFirsReceived";
520 case kStatsValueNameFirsSent:
521 return "googFirsSent";
Benjamin Wright514f0842018-12-10 09:55:17 -0800522 case kStatsValueNameFirstFrameReceivedToDecodedMs:
523 return "googFirstFrameReceivedToDecodedMs";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000524 case kStatsValueNameFrameHeightInput:
525 return "googFrameHeightInput";
526 case kStatsValueNameFrameHeightReceived:
527 return "googFrameHeightReceived";
528 case kStatsValueNameFrameHeightSent:
529 return "googFrameHeightSent";
530 case kStatsValueNameFrameRateReceived:
531 return "googFrameRateReceived";
532 case kStatsValueNameFrameRateDecoded:
533 return "googFrameRateDecoded";
534 case kStatsValueNameFrameRateOutput:
535 return "googFrameRateOutput";
536 case kStatsValueNameDecodeMs:
537 return "googDecodeMs";
538 case kStatsValueNameMaxDecodeMs:
539 return "googMaxDecodeMs";
540 case kStatsValueNameCurrentDelayMs:
541 return "googCurrentDelayMs";
542 case kStatsValueNameTargetDelayMs:
543 return "googTargetDelayMs";
544 case kStatsValueNameJitterBufferMs:
545 return "googJitterBufferMs";
546 case kStatsValueNameMinPlayoutDelayMs:
547 return "googMinPlayoutDelayMs";
548 case kStatsValueNameRenderDelayMs:
549 return "googRenderDelayMs";
550 case kStatsValueNameCaptureStartNtpTimeMs:
551 return "googCaptureStartNtpTimeMs";
552 case kStatsValueNameFrameRateInput:
553 return "googFrameRateInput";
554 case kStatsValueNameFrameRateSent:
555 return "googFrameRateSent";
556 case kStatsValueNameFrameWidthInput:
557 return "googFrameWidthInput";
558 case kStatsValueNameFrameWidthReceived:
559 return "googFrameWidthReceived";
560 case kStatsValueNameFrameWidthSent:
561 return "googFrameWidthSent";
Ã…sa Perssonc3ed6302017-11-16 14:04:52 +0100562 case kStatsValueNameHasEnteredLowResolution:
563 return "googHasEnteredLowResolution";
Ilya Nikolaevskiy70473fc2018-02-28 16:35:03 +0100564 case kStatsValueNameHugeFramesSent:
565 return "hugeFramesSent";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000566 case kStatsValueNameInitiator:
567 return "googInitiator";
ilnika79cc282017-08-23 05:24:10 -0700568 case kStatsValueNameInterframeDelayMaxMs:
569 return "googInterframeDelayMax";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000570 case kStatsValueNameIssuerId:
571 return "googIssuerId";
572 case kStatsValueNameJitterReceived:
573 return "googJitterReceived";
574 case kStatsValueNameLocalAddress:
575 return "googLocalAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000576 case kStatsValueNameLocalCandidateId:
577 return "localCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000578 case kStatsValueNameLocalCandidateType:
579 return "googLocalCandidateType";
580 case kStatsValueNameLocalCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000581 return "localCertificateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000582 case kStatsValueNameAdaptationChanges:
583 return "googAdaptationChanges";
584 case kStatsValueNameNacksReceived:
585 return "googNacksReceived";
586 case kStatsValueNameNacksSent:
587 return "googNacksSent";
Henrik Lundin8e6fd462015-06-02 09:24:52 +0200588 case kStatsValueNamePreemptiveExpandRate:
589 return "googPreemptiveExpandRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000590 case kStatsValueNamePlisReceived:
591 return "googPlisReceived";
592 case kStatsValueNamePlisSent:
593 return "googPlisSent";
594 case kStatsValueNamePreferredJitterBufferMs:
595 return "googPreferredJitterBufferMs";
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700596 case kStatsValueNameReceiving:
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000597 return "googReadable";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000598 case kStatsValueNameRemoteAddress:
599 return "googRemoteAddress";
guoweis@webrtc.org950c5182014-12-16 23:01:31 +0000600 case kStatsValueNameRemoteCandidateId:
601 return "remoteCandidateId";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000602 case kStatsValueNameRemoteCandidateType:
603 return "googRemoteCandidateType";
604 case kStatsValueNameRemoteCertificateId:
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000605 return "remoteCertificateId";
ivoc8c63a822016-10-21 04:10:03 -0700606 case kStatsValueNameResidualEchoLikelihood:
607 return "googResidualEchoLikelihood";
ivoc4e477a12017-01-15 08:29:46 -0800608 case kStatsValueNameResidualEchoLikelihoodRecentMax:
609 return "googResidualEchoLikelihoodRecentMax";
ivoce1198e02017-09-08 08:13:19 -0700610 case kStatsValueNameAnaBitrateActionCounter:
611 return "googAnaBitrateActionCounter";
612 case kStatsValueNameAnaChannelActionCounter:
613 return "googAnaChannelActionCounter";
614 case kStatsValueNameAnaDtxActionCounter:
615 return "googAnaDtxActionCounter";
616 case kStatsValueNameAnaFecActionCounter:
617 return "googAnaFecActionCounter";
ivoc0d0b9122017-09-08 13:24:21 -0700618 case kStatsValueNameAnaFrameLengthIncreaseCounter:
619 return "googAnaFrameLengthIncreaseCounter";
620 case kStatsValueNameAnaFrameLengthDecreaseCounter:
621 return "googAnaFrameLengthDecreaseCounter";
622 case kStatsValueNameAnaUplinkPacketLossFraction:
623 return "googAnaUplinkPacketLossFraction";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000624 case kStatsValueNameRetransmitBitrate:
625 return "googRetransmitBitrate";
626 case kStatsValueNameRtt:
627 return "googRtt";
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000628 case kStatsValueNameSecondaryDecodedRate:
629 return "googSecondaryDecodedRate";
minyue-webrtc0e320ec2017-08-28 13:51:27 +0200630 case kStatsValueNameSecondaryDiscardedRate:
631 return "googSecondaryDiscardedRate";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000632 case kStatsValueNameSendPacketsDiscarded:
633 return "packetsDiscardedOnSend";
minyue@webrtc.org652bc372015-02-18 23:50:46 +0000634 case kStatsValueNameSpeechExpandRate:
635 return "googSpeechExpandRate";
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000636 case kStatsValueNameSrtpCipher:
637 return "srtpCipher";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000638 case kStatsValueNameTargetEncBitrate:
639 return "googTargetEncBitrate";
zsteine76bd3a2017-07-14 12:17:49 -0700640 case kStatsValueNameTotalAudioEnergy:
641 return "totalAudioEnergy";
642 case kStatsValueNameTotalSamplesDuration:
643 return "totalSamplesDuration";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000644 case kStatsValueNameTransmitBitrate:
645 return "googTransmitBitrate";
646 case kStatsValueNameTransportType:
647 return "googTransportType";
648 case kStatsValueNameTrackId:
649 return "googTrackId";
ilnik2edc6842017-07-06 03:06:50 -0700650 case kStatsValueNameTimingFrameInfo:
651 return "googTimingFrameInfo";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000652 case kStatsValueNameTypingNoiseState:
653 return "googTypingNoiseState";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000654 case kStatsValueNameWritable:
655 return "googWritable";
Alex Narestbbeb1092019-08-16 11:49:04 +0200656 case kStatsValueNameAudioDeviceUnderrunCounter:
657 return "googAudioDeviceUnderrunCounter";
tommi@webrtc.orgc57310b2014-12-12 17:41:28 +0000658 }
659
660 return nullptr;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000661}
662
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000663std::string StatsReport::Value::ToString() const {
664 switch (type_) {
665 case kInt:
666 return rtc::ToString(value_.int_);
667 case kInt64:
668 return rtc::ToString(value_.int64_);
669 case kFloat:
670 return rtc::ToString(value_.float_);
671 case kStaticString:
672 return std::string(value_.static_string_);
673 case kString:
674 return *value_.string_;
675 case kBool:
676 return value_.bool_ ? "true" : "false";
677 case kId:
678 return (*value_.id_)->ToString();
679 }
680 RTC_NOTREACHED();
681 return std::string();
tommi@webrtc.orgafa6d162015-03-02 11:27:48 +0000682}
683
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000684StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
henrikg91d6ede2015-09-17 00:24:34 -0700685 RTC_DCHECK(id_.get());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000686}
687
ossu7bb87ee2017-01-23 04:56:25 -0800688StatsReport::~StatsReport() = default;
689
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000690// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000691StatsReport::Id StatsReport::NewBandwidthEstimationId() {
692 return Id(new RefCountedObject<BandwidthEstimationId>());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000693}
694
695// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000696StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
697 return Id(new RefCountedObject<TypedId>(type, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000698}
699
700// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000701StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
702 return Id(new RefCountedObject<TypedIntId>(type, id));
decurtis@webrtc.org322a5642015-02-03 22:09:37 +0000703}
704
705// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000706StatsReport::Id StatsReport::NewIdWithDirection(
Yves Gerey665174f2018-06-19 15:03:05 +0200707 StatsType type,
708 const std::string& id,
709 StatsReport::Direction direction) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000710 return Id(new RefCountedObject<IdWithDirection>(type, id, direction));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000711}
712
713// static
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000714StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
715 return Id(new RefCountedObject<CandidateId>(local, id));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000716}
717
718// static
Yves Gerey665174f2018-06-19 15:03:05 +0200719StatsReport::Id StatsReport::NewComponentId(const std::string& content_name,
720 int component) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000721 return Id(new RefCountedObject<ComponentId>(content_name, component));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000722}
723
724// static
Yves Gerey665174f2018-06-19 15:03:05 +0200725StatsReport::Id StatsReport::NewCandidatePairId(const std::string& content_name,
726 int component,
727 int index) {
728 return Id(
729 new RefCountedObject<CandidatePairId>(content_name, component, index));
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000730}
731
732const char* StatsReport::TypeToString() const {
733 return InternalTypeToString(id_->type());
734}
735
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000736void StatsReport::AddString(StatsReport::StatsValueName name,
737 const std::string& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000738 const Value* found = FindValue(name);
739 if (!found || !(*found == value))
740 values_[name] = ValuePtr(new Value(name, value));
741}
742
743void StatsReport::AddString(StatsReport::StatsValueName name,
744 const char* value) {
745 const Value* found = FindValue(name);
746 if (!found || !(*found == value))
747 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000748}
749
Peter Boström0c4e06b2015-10-07 12:23:21 +0200750void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000751 const Value* found = FindValue(name);
752 if (!found || !(*found == value))
753 values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000754}
755
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000756void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000757 const Value* found = FindValue(name);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200758 if (!found || !(*found == static_cast<int64_t>(value)))
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000759 values_[name] = ValuePtr(new Value(name, value, Value::kInt));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000760}
761
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000762void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000763 const Value* found = FindValue(name);
764 if (!found || !(*found == value))
765 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000766}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000767
768void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000769 const Value* found = FindValue(name);
770 if (!found || !(*found == value))
771 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.org8e327c42015-01-19 20:41:26 +0000772}
773
Yves Gerey665174f2018-06-19 15:03:05 +0200774void StatsReport::AddId(StatsReport::StatsValueName name, const Id& value) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000775 const Value* found = FindValue(name);
776 if (!found || !(*found == value))
777 values_[name] = ValuePtr(new Value(name, value));
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000778}
779
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000780const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
tommi@webrtc.org92f40182015-03-04 15:25:19 +0000781 Values::const_iterator it = values_.find(name);
782 return it == values_.end() ? nullptr : it->second.get();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000783}
784
Yves Gerey665174f2018-06-19 15:03:05 +0200785StatsCollection::StatsCollection() {}
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000786
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000787StatsCollection::~StatsCollection() {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200788 RTC_DCHECK(thread_checker_.IsCurrent());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000789 for (auto* r : list_)
790 delete r;
791}
792
793StatsCollection::const_iterator StatsCollection::begin() const {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200794 RTC_DCHECK(thread_checker_.IsCurrent());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000795 return list_.begin();
796}
797
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000798StatsCollection::const_iterator StatsCollection::end() const {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200799 RTC_DCHECK(thread_checker_.IsCurrent());
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000800 return list_.end();
801}
802
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000803size_t StatsCollection::size() const {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200804 RTC_DCHECK(thread_checker_.IsCurrent());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000805 return list_.size();
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000806}
807
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000808StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200809 RTC_DCHECK(thread_checker_.IsCurrent());
henrikg91d6ede2015-09-17 00:24:34 -0700810 RTC_DCHECK(Find(id) == nullptr);
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000811 StatsReport* report = new StatsReport(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000812 list_.push_back(report);
813 return report;
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000814}
815
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000816StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200817 RTC_DCHECK(thread_checker_.IsCurrent());
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000818 StatsReport* ret = Find(id);
819 return ret ? ret : InsertNew(id);
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000820}
821
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000822StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200823 RTC_DCHECK(thread_checker_.IsCurrent());
henrikg91d6ede2015-09-17 00:24:34 -0700824 RTC_DCHECK(id.get());
Steve Antona59dcc32019-03-25 13:53:07 -0700825 Container::iterator it = absl::c_find_if(
826 list_,
Yves Gerey665174f2018-06-19 15:03:05 +0200827 [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000828 if (it != end()) {
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000829 StatsReport* report = new StatsReport((*it)->id());
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000830 delete *it;
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000831 *it = report;
832 return report;
833 }
tommi@webrtc.orgd3900292015-03-12 16:35:55 +0000834 return InsertNew(id);
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000835}
836
deadbeef8d60a942017-02-27 14:47:33 -0800837// Looks for a report with the given |id|. If one is not found, null
tommi@webrtc.orgc9d155f2014-12-09 18:18:06 +0000838// will be returned.
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000839StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200840 RTC_DCHECK(thread_checker_.IsCurrent());
Steve Antona59dcc32019-03-25 13:53:07 -0700841 Container::iterator it = absl::c_find_if(
842 list_,
Yves Gerey665174f2018-06-19 15:03:05 +0200843 [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); });
tommi@webrtc.org4fb7e252015-01-21 11:36:18 +0000844 return it == list_.end() ? nullptr : *it;
845}
846
tommi@webrtc.org5c3ee4b2014-12-09 10:47:01 +0000847} // namespace webrtc