xref: /aosp_15_r20/external/webrtc/stats/rtc_stats.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
3  *
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
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.
9  */
10 
11 #include "api/stats/rtc_stats.h"
12 
13 #include <cstdio>
14 
15 #include "rtc_base/arraysize.h"
16 #include "rtc_base/string_encode.h"
17 #include "rtc_base/strings/string_builder.h"
18 
19 namespace webrtc {
20 
21 namespace {
22 
23 // Produces "[a,b,c]". Works for non-vector `RTCStatsMemberInterface::Type`
24 // types.
25 template <typename T>
VectorToString(const std::vector<T> & vector)26 std::string VectorToString(const std::vector<T>& vector) {
27   rtc::StringBuilder sb;
28   sb << "[";
29   const char* separator = "";
30   for (const T& element : vector) {
31     sb << separator << rtc::ToString(element);
32     separator = ",";
33   }
34   sb << "]";
35   return sb.Release();
36 }
37 
38 // This overload is required because std::vector<bool> range loops don't
39 // return references but objects, causing -Wrange-loop-analysis diagnostics.
VectorToString(const std::vector<bool> & vector)40 std::string VectorToString(const std::vector<bool>& vector) {
41   rtc::StringBuilder sb;
42   sb << "[";
43   const char* separator = "";
44   for (bool element : vector) {
45     sb << separator << rtc::ToString(element);
46     separator = ",";
47   }
48   sb << "]";
49   return sb.Release();
50 }
51 
52 // Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and
53 // std::string element types.
54 template <typename T>
VectorOfStringsToString(const std::vector<T> & strings)55 std::string VectorOfStringsToString(const std::vector<T>& strings) {
56   rtc::StringBuilder sb;
57   sb << "[";
58   const char* separator = "";
59   for (const T& element : strings) {
60     sb << separator << "\"" << rtc::ToString(element) << "\"";
61     separator = ",";
62   }
63   sb << "]";
64   return sb.Release();
65 }
66 
67 template <typename T>
MapToString(const std::map<std::string,T> & map)68 std::string MapToString(const std::map<std::string, T>& map) {
69   rtc::StringBuilder sb;
70   sb << "{";
71   const char* separator = "";
72   for (const auto& element : map) {
73     sb << separator << rtc::ToString(element.first) << ":"
74        << rtc::ToString(element.second);
75     separator = ",";
76   }
77   sb << "}";
78   return sb.Release();
79 }
80 
81 template <typename T>
ToStringAsDouble(const T value)82 std::string ToStringAsDouble(const T value) {
83   // JSON represents numbers as floating point numbers with about 15 decimal
84   // digits of precision.
85   char buf[32];
86   const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g",
87                                 static_cast<double>(value));
88   RTC_DCHECK_LE(len, arraysize(buf));
89   return std::string(&buf[0], len);
90 }
91 
92 template <typename T>
VectorToStringAsDouble(const std::vector<T> & vector)93 std::string VectorToStringAsDouble(const std::vector<T>& vector) {
94   rtc::StringBuilder sb;
95   sb << "[";
96   const char* separator = "";
97   for (const T& element : vector) {
98     sb << separator << ToStringAsDouble<T>(element);
99     separator = ",";
100   }
101   sb << "]";
102   return sb.Release();
103 }
104 
105 template <typename T>
MapToStringAsDouble(const std::map<std::string,T> & map)106 std::string MapToStringAsDouble(const std::map<std::string, T>& map) {
107   rtc::StringBuilder sb;
108   sb << "{";
109   const char* separator = "";
110   for (const auto& element : map) {
111     sb << separator << "\"" << rtc::ToString(element.first)
112        << "\":" << ToStringAsDouble(element.second);
113     separator = ",";
114   }
115   sb << "}";
116   return sb.Release();
117 }
118 
119 }  // namespace
120 
operator ==(const RTCStats & other) const121 bool RTCStats::operator==(const RTCStats& other) const {
122   if (type() != other.type() || id() != other.id())
123     return false;
124   std::vector<const RTCStatsMemberInterface*> members = Members();
125   std::vector<const RTCStatsMemberInterface*> other_members = other.Members();
126   RTC_DCHECK_EQ(members.size(), other_members.size());
127   for (size_t i = 0; i < members.size(); ++i) {
128     const RTCStatsMemberInterface* member = members[i];
129     const RTCStatsMemberInterface* other_member = other_members[i];
130     RTC_DCHECK_EQ(member->type(), other_member->type());
131     RTC_DCHECK_EQ(member->name(), other_member->name());
132     if (*member != *other_member)
133       return false;
134   }
135   return true;
136 }
137 
operator !=(const RTCStats & other) const138 bool RTCStats::operator!=(const RTCStats& other) const {
139   return !(*this == other);
140 }
141 
ToJson() const142 std::string RTCStats::ToJson() const {
143   rtc::StringBuilder sb;
144   sb << "{\"type\":\"" << type()
145      << "\","
146         "\"id\":\""
147      << id_
148      << "\","
149         "\"timestamp\":"
150      << timestamp_us_;
151   for (const RTCStatsMemberInterface* member : Members()) {
152     if (member->is_defined()) {
153       sb << ",\"" << member->name() << "\":";
154       if (member->is_string())
155         sb << "\"" << member->ValueToJson() << "\"";
156       else
157         sb << member->ValueToJson();
158     }
159   }
160   sb << "}";
161   return sb.Release();
162 }
163 
Members() const164 std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const {
165   return MembersOfThisObjectAndAncestors(0);
166 }
167 
168 std::vector<const RTCStatsMemberInterface*>
MembersOfThisObjectAndAncestors(size_t additional_capacity) const169 RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const {
170   std::vector<const RTCStatsMemberInterface*> members;
171   members.reserve(additional_capacity);
172   return members;
173 }
174 
175 #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \
176   template <>                                                                  \
177   RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType() {              \
178     return type;                                                               \
179   }                                                                            \
180   template <>                                                                  \
181   bool RTCStatsMember<T>::is_sequence() const {                                \
182     return is_seq;                                                             \
183   }                                                                            \
184   template <>                                                                  \
185   bool RTCStatsMember<T>::is_string() const {                                  \
186     return is_str;                                                             \
187   }                                                                            \
188   template <>                                                                  \
189   std::string RTCStatsMember<T>::ValueToString() const {                       \
190     RTC_DCHECK(value_.has_value());                                            \
191     return to_str;                                                             \
192   }                                                                            \
193   template <>                                                                  \
194   std::string RTCStatsMember<T>::ValueToJson() const {                         \
195     RTC_DCHECK(value_.has_value());                                            \
196     return to_json;                                                            \
197   }                                                                            \
198   template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T>
199 
200 WEBRTC_DEFINE_RTCSTATSMEMBER(bool,
201                              kBool,
202                              false,
203                              false,
204                              rtc::ToString(*value_),
205                              rtc::ToString(*value_));
206 WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t,
207                              kInt32,
208                              false,
209                              false,
210                              rtc::ToString(*value_),
211                              rtc::ToString(*value_));
212 WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t,
213                              kUint32,
214                              false,
215                              false,
216                              rtc::ToString(*value_),
217                              rtc::ToString(*value_));
218 WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t,
219                              kInt64,
220                              false,
221                              false,
222                              rtc::ToString(*value_),
223                              ToStringAsDouble(*value_));
224 WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t,
225                              kUint64,
226                              false,
227                              false,
228                              rtc::ToString(*value_),
229                              ToStringAsDouble(*value_));
230 WEBRTC_DEFINE_RTCSTATSMEMBER(double,
231                              kDouble,
232                              false,
233                              false,
234                              rtc::ToString(*value_),
235                              ToStringAsDouble(*value_));
236 WEBRTC_DEFINE_RTCSTATSMEMBER(std::string,
237                              kString,
238                              false,
239                              true,
240                              *value_,
241                              *value_);
242 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<bool>,
243                              kSequenceBool,
244                              true,
245                              false,
246                              VectorToString(*value_),
247                              VectorToString(*value_));
248 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>,
249                              kSequenceInt32,
250                              true,
251                              false,
252                              VectorToString(*value_),
253                              VectorToString(*value_));
254 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>,
255                              kSequenceUint32,
256                              true,
257                              false,
258                              VectorToString(*value_),
259                              VectorToString(*value_));
260 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>,
261                              kSequenceInt64,
262                              true,
263                              false,
264                              VectorToString(*value_),
265                              VectorToStringAsDouble(*value_));
266 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>,
267                              kSequenceUint64,
268                              true,
269                              false,
270                              VectorToString(*value_),
271                              VectorToStringAsDouble(*value_));
272 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>,
273                              kSequenceDouble,
274                              true,
275                              false,
276                              VectorToString(*value_),
277                              VectorToStringAsDouble(*value_));
278 WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>,
279                              kSequenceString,
280                              true,
281                              false,
282                              VectorOfStringsToString(*value_),
283                              VectorOfStringsToString(*value_));
284 WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64,
285                              kMapStringUint64,
286                              false,
287                              false,
288                              MapToString(*value_),
289                              MapToStringAsDouble(*value_));
290 WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble,
291                              kMapStringDouble,
292                              false,
293                              false,
294                              MapToString(*value_),
295                              MapToStringAsDouble(*value_));
296 
297 // Restricted members that expose hardware capabilites.
298 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
299     RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
300 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
301     RTCRestrictedStatsMember<int32_t,
302                              StatExposureCriteria::kHardwareCapability>;
303 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
304     RTCRestrictedStatsMember<uint32_t,
305                              StatExposureCriteria::kHardwareCapability>;
306 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
307     RTCRestrictedStatsMember<int64_t,
308                              StatExposureCriteria::kHardwareCapability>;
309 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
310     RTCRestrictedStatsMember<uint64_t,
311                              StatExposureCriteria::kHardwareCapability>;
312 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
313     RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
314 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
315     RTCRestrictedStatsMember<std::string,
316                              StatExposureCriteria::kHardwareCapability>;
317 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
318     RTCRestrictedStatsMember<std::vector<bool>,
319                              StatExposureCriteria::kHardwareCapability>;
320 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
321     RTCRestrictedStatsMember<std::vector<int32_t>,
322                              StatExposureCriteria::kHardwareCapability>;
323 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
324     RTCRestrictedStatsMember<std::vector<uint32_t>,
325                              StatExposureCriteria::kHardwareCapability>;
326 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
327     RTCRestrictedStatsMember<std::vector<int64_t>,
328                              StatExposureCriteria::kHardwareCapability>;
329 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
330     RTCRestrictedStatsMember<std::vector<uint64_t>,
331                              StatExposureCriteria::kHardwareCapability>;
332 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
333     RTCRestrictedStatsMember<std::vector<double>,
334                              StatExposureCriteria::kHardwareCapability>;
335 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
336     RTCRestrictedStatsMember<std::vector<std::string>,
337                              StatExposureCriteria::kHardwareCapability>;
338 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
339     RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
340                              StatExposureCriteria::kHardwareCapability>;
341 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
342     RTCRestrictedStatsMember<std::map<std::string, double>,
343                              StatExposureCriteria::kHardwareCapability>;
344 
345 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
346     RTCNonStandardStatsMember<bool>;
347 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
348     RTCNonStandardStatsMember<int32_t>;
349 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
350     RTCNonStandardStatsMember<uint32_t>;
351 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
352     RTCNonStandardStatsMember<int64_t>;
353 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
354     RTCNonStandardStatsMember<uint64_t>;
355 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
356     RTCNonStandardStatsMember<double>;
357 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
358     RTCNonStandardStatsMember<std::string>;
359 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
360     RTCNonStandardStatsMember<std::vector<bool>>;
361 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
362     RTCNonStandardStatsMember<std::vector<int32_t>>;
363 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
364     RTCNonStandardStatsMember<std::vector<uint32_t>>;
365 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
366     RTCNonStandardStatsMember<std::vector<int64_t>>;
367 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
368     RTCNonStandardStatsMember<std::vector<uint64_t>>;
369 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
370     RTCNonStandardStatsMember<std::vector<double>>;
371 template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
372     RTCNonStandardStatsMember<std::vector<std::string>>;
373 
374 }  // namespace webrtc
375