blob: 535e6fb345b918254e71eaba9113d70cea68b0fe [file] [log] [blame]
hbos74e1a4f2016-09-15 23:33:01 -07001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef API_STATS_RTC_STATS_H_
12#define API_STATS_RTC_STATS_H_
hbos74e1a4f2016-09-15 23:33:01 -070013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
Byoungchan Lee0a52ede2021-05-22 08:41:02 +090017#include <map>
hbos74e1a4f2016-09-15 23:33:01 -070018#include <memory>
19#include <string>
20#include <utility>
21#include <vector>
22
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/checks.h"
Mirko Bonadei276827c2018-10-16 14:13:50 +020024#include "rtc_base/system/rtc_export.h"
Mirko Bonadei054f1852019-11-04 16:31:08 +010025#include "rtc_base/system/rtc_export_template.h"
hbos74e1a4f2016-09-15 23:33:01 -070026
27namespace webrtc {
28
29class RTCStatsMemberInterface;
30
31// Abstract base class for RTCStats-derived dictionaries, see
32// https://w3c.github.io/webrtc-stats/.
33//
34// All derived classes must have the following static variable defined:
35// static const char kType[];
36// It is used as a unique class identifier and a string representation of the
37// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
Artem Titov0e61fdd2021-07-25 21:50:14 +020038// Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
hbos74e1a4f2016-09-15 23:33:01 -070039// for details.
40//
41// Derived classes list their dictionary members, RTCStatsMember<T>, as public
42// fields, allowing the following:
43//
44// RTCFooStats foo("fooId", GetCurrentTime());
45// foo.bar = 42;
46// foo.baz = std::vector<std::string>();
47// foo.baz->push_back("hello world");
48// uint32_t x = *foo.bar;
49//
Artem Titov0e61fdd2021-07-25 21:50:14 +020050// Pointers to all the members are available with `Members`, allowing iteration:
hbos74e1a4f2016-09-15 23:33:01 -070051//
52// for (const RTCStatsMemberInterface* member : foo.Members()) {
53// printf("%s = %s\n", member->name(), member->ValueToString().c_str());
54// }
Mirko Bonadei276827c2018-10-16 14:13:50 +020055class RTC_EXPORT RTCStats {
hbos74e1a4f2016-09-15 23:33:01 -070056 public:
57 RTCStats(const std::string& id, int64_t timestamp_us)
58 : id_(id), timestamp_us_(timestamp_us) {}
59 RTCStats(std::string&& id, int64_t timestamp_us)
60 : id_(std::move(id)), timestamp_us_(timestamp_us) {}
61 virtual ~RTCStats() {}
62
63 virtual std::unique_ptr<RTCStats> copy() const = 0;
64
65 const std::string& id() const { return id_; }
66 // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
67 int64_t timestamp_us() const { return timestamp_us_; }
Artem Titov0e61fdd2021-07-25 21:50:14 +020068 // Returns the static member variable `kType` of the implementing class.
hbos74e1a4f2016-09-15 23:33:01 -070069 virtual const char* type() const = 0;
Artem Titov0e61fdd2021-07-25 21:50:14 +020070 // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
hbos67c8bc42016-10-25 04:31:23 -070071 // of this class. This allows for iteration of members. For a given class,
Artem Titov0e61fdd2021-07-25 21:50:14 +020072 // `Members` always returns the same members in the same order.
hbos74e1a4f2016-09-15 23:33:01 -070073 std::vector<const RTCStatsMemberInterface*> Members() const;
hbos67c8bc42016-10-25 04:31:23 -070074 // Checks if the two stats objects are of the same type and have the same
hbos0583b282016-11-30 01:50:14 -080075 // member values. Timestamps are not compared. These operators are exposed for
76 // testing.
hbos67c8bc42016-10-25 04:31:23 -070077 bool operator==(const RTCStats& other) const;
78 bool operator!=(const RTCStats& other) const;
hbos74e1a4f2016-09-15 23:33:01 -070079
ehmaldonado35a872c2017-07-28 07:29:12 -070080 // Creates a JSON readable string representation of the stats
81 // object, listing all of its members (names and values).
82 std::string ToJson() const;
hbos74e1a4f2016-09-15 23:33:01 -070083
Artem Titov0e61fdd2021-07-25 21:50:14 +020084 // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
85 // object is of type `T`.
Yves Gerey665174f2018-06-19 15:03:05 +020086 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -070087 const T& cast_to() const {
88 RTC_DCHECK_EQ(type(), T::kType);
89 return static_cast<const T&>(*this);
90 }
91
92 protected:
Artem Titov0e61fdd2021-07-25 21:50:14 +020093 // Gets a vector of all members of this `RTCStats` object, including members
94 // derived from parent classes. `additional_capacity` is how many more members
hbos74e1a4f2016-09-15 23:33:01 -070095 // shall be reserved in the vector (so that subclasses can allocate a vector
96 // with room for both parent and child members without it having to resize).
97 virtual std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 15:03:05 +020098 MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
hbos74e1a4f2016-09-15 23:33:01 -070099
100 std::string const id_;
101 int64_t timestamp_us_;
102};
103
Artem Titov0e61fdd2021-07-25 21:50:14 +0200104// All `RTCStats` classes should use these macros.
105// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
106// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
hbos74e1a4f2016-09-15 23:33:01 -0700107//
Artem Titov0e61fdd2021-07-25 21:50:14 +0200108// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
109// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
110// `MembersOfThisObjectAndAncestors`. The |...| argument is a list of addresses
hbosfc5e0502016-10-06 02:06:10 -0700111// to each member defined in the implementing class. The list must have at least
112// one member.
hbos74e1a4f2016-09-15 23:33:01 -0700113//
114// (Since class names need to be known to implement these methods this cannot be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200115// part of the base `RTCStats`. While these methods could be implemented using
hbos74e1a4f2016-09-15 23:33:01 -0700116// templates, that would only work for immediate subclasses. Subclasses of
117// subclasses also have to override these methods, resulting in boilerplate
Artem Titov0e61fdd2021-07-25 21:50:14 +0200118// code. Using a macro avoids this and works for any `RTCStats` class, including
hbos74e1a4f2016-09-15 23:33:01 -0700119// grandchildren.)
120//
121// Sample usage:
122//
123// rtcfoostats.h:
124// class RTCFooStats : public RTCStats {
125// public:
hbosfc5e0502016-10-06 02:06:10 -0700126// WEBRTC_RTCSTATS_DECL();
hbos74e1a4f2016-09-15 23:33:01 -0700127//
hbosfc5e0502016-10-06 02:06:10 -0700128// RTCFooStats(const std::string& id, int64_t timestamp_us);
hbos74e1a4f2016-09-15 23:33:01 -0700129//
130// RTCStatsMember<int32_t> foo;
131// RTCStatsMember<int32_t> bar;
132// };
133//
134// rtcfoostats.cc:
hbosfc5e0502016-10-06 02:06:10 -0700135// WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
136// &foo,
137// &bar);
hbos74e1a4f2016-09-15 23:33:01 -0700138//
hbosfc5e0502016-10-06 02:06:10 -0700139// RTCFooStats::RTCFooStats(const std::string& id, int64_t timestamp_us)
140// : RTCStats(id, timestamp_us),
141// foo("foo"),
142// bar("bar") {
143// }
144//
Yves Gerey665174f2018-06-19 15:03:05 +0200145#define WEBRTC_RTCSTATS_DECL() \
Yves Gerey665174f2018-06-19 15:03:05 +0200146 protected: \
147 std::vector<const webrtc::RTCStatsMemberInterface*> \
148 MembersOfThisObjectAndAncestors(size_t local_var_additional_capacity) \
149 const override; \
150 \
Nico Weber22f99252019-02-20 10:13:16 -0500151 public: \
152 static const char kType[]; \
153 \
154 std::unique_ptr<webrtc::RTCStats> copy() const override; \
155 const char* type() const override
hbosfc5e0502016-10-06 02:06:10 -0700156
157#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...) \
158 const char this_class::kType[] = type_str; \
159 \
160 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200161 return std::make_unique<this_class>(*this); \
hbosfc5e0502016-10-06 02:06:10 -0700162 } \
163 \
Yves Gerey665174f2018-06-19 15:03:05 +0200164 const char* this_class::type() const { return this_class::kType; } \
hbosfc5e0502016-10-06 02:06:10 -0700165 \
166 std::vector<const webrtc::RTCStatsMemberInterface*> \
167 this_class::MembersOfThisObjectAndAncestors( \
168 size_t local_var_additional_capacity) const { \
hbos74e1a4f2016-09-15 23:33:01 -0700169 const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
Yves Gerey665174f2018-06-19 15:03:05 +0200170 __VA_ARGS__}; \
hbos74e1a4f2016-09-15 23:33:01 -0700171 size_t local_var_members_count = \
172 sizeof(local_var_members) / sizeof(local_var_members[0]); \
Yves Gerey665174f2018-06-19 15:03:05 +0200173 std::vector<const webrtc::RTCStatsMemberInterface*> \
174 local_var_members_vec = parent_class::MembersOfThisObjectAndAncestors( \
hbos74e1a4f2016-09-15 23:33:01 -0700175 local_var_members_count + local_var_additional_capacity); \
176 RTC_DCHECK_GE( \
177 local_var_members_vec.capacity() - local_var_members_vec.size(), \
178 local_var_members_count + local_var_additional_capacity); \
179 local_var_members_vec.insert(local_var_members_vec.end(), \
180 &local_var_members[0], \
181 &local_var_members[local_var_members_count]); \
182 return local_var_members_vec; \
hbosfc5e0502016-10-06 02:06:10 -0700183 }
hbos74e1a4f2016-09-15 23:33:01 -0700184
Henrik Boström646fda02019-05-22 15:49:42 +0200185// A version of WEBRTC_RTCSTATS_IMPL() where "..." is omitted, used to avoid a
186// compile error on windows. This is used if the stats dictionary does not
187// declare any members of its own (but perhaps its parent dictionary does).
188#define WEBRTC_RTCSTATS_IMPL_NO_MEMBERS(this_class, parent_class, type_str) \
189 const char this_class::kType[] = type_str; \
190 \
191 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200192 return std::make_unique<this_class>(*this); \
Henrik Boström646fda02019-05-22 15:49:42 +0200193 } \
194 \
195 const char* this_class::type() const { return this_class::kType; } \
196 \
197 std::vector<const webrtc::RTCStatsMemberInterface*> \
198 this_class::MembersOfThisObjectAndAncestors( \
199 size_t local_var_additional_capacity) const { \
200 return parent_class::MembersOfThisObjectAndAncestors(0); \
201 }
202
Jakob Ivarsson22936222019-03-22 11:29:49 +0100203// Non-standard stats members can be exposed to the JavaScript API in Chrome
204// e.g. through origin trials. The group ID can be used by the blink layer to
205// determine if a stats member should be exposed or not. Multiple non-standard
206// stats members can share the same group ID so that they are exposed together.
207enum class NonStandardGroupId {
Jakob Ivarssonaa023e22019-03-27 10:17:31 +0100208 // Group ID used for testing purposes only.
209 kGroupIdForTesting,
Jakob Ivarsson22936222019-03-22 11:29:49 +0100210 // I2E:
211 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
212 kRtcAudioJitterBufferMaxPackets,
213 // I2E:
214 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
215 kRtcStatsRelativePacketArrivalDelay,
216};
217
Artem Titov0e61fdd2021-07-25 21:50:14 +0200218// Interface for `RTCStats` members, which have a name and a value of a type
219// defined in a subclass. Only the types listed in `Type` are supported, these
Artem Titovcfea2182021-08-10 01:22:31 +0200220// are implemented by `RTCStatsMember<T>`. The value of a member may be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200221// undefined, the value can only be read if `is_defined`.
hbos74e1a4f2016-09-15 23:33:01 -0700222class RTCStatsMemberInterface {
223 public:
224 // Member value types.
225 enum Type {
Yves Gerey665174f2018-06-19 15:03:05 +0200226 kBool, // bool
227 kInt32, // int32_t
228 kUint32, // uint32_t
229 kInt64, // int64_t
230 kUint64, // uint64_t
231 kDouble, // double
232 kString, // std::string
hbos74e1a4f2016-09-15 23:33:01 -0700233
Yves Gerey665174f2018-06-19 15:03:05 +0200234 kSequenceBool, // std::vector<bool>
235 kSequenceInt32, // std::vector<int32_t>
236 kSequenceUint32, // std::vector<uint32_t>
237 kSequenceInt64, // std::vector<int64_t>
238 kSequenceUint64, // std::vector<uint64_t>
239 kSequenceDouble, // std::vector<double>
240 kSequenceString, // std::vector<std::string>
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900241
242 kMapStringUint64, // std::map<std::string, uint64_t>
243 kMapStringDouble, // std::map<std::string, double>
hbos74e1a4f2016-09-15 23:33:01 -0700244 };
245
246 virtual ~RTCStatsMemberInterface() {}
247
248 const char* name() const { return name_; }
249 virtual Type type() const = 0;
250 virtual bool is_sequence() const = 0;
251 virtual bool is_string() const = 0;
252 bool is_defined() const { return is_defined_; }
Taylor Brandstettere2751742018-06-25 13:42:44 -0700253 // Is this part of the stats spec? Used so that chromium can easily filter
254 // out anything unstandardized.
255 virtual bool is_standardized() const = 0;
Jakob Ivarsson22936222019-03-22 11:29:49 +0100256 // Non-standard stats members can have group IDs in order to be exposed in
257 // JavaScript through experiments. Standardized stats have no group IDs.
258 virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
hbos67c8bc42016-10-25 04:31:23 -0700259 // Type and value comparator. The names are not compared. These operators are
260 // exposed for testing.
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900261 bool operator==(const RTCStatsMemberInterface& other) const {
262 return IsEqual(other);
263 }
hbos67c8bc42016-10-25 04:31:23 -0700264 bool operator!=(const RTCStatsMemberInterface& other) const {
265 return !(*this == other);
266 }
hbos74e1a4f2016-09-15 23:33:01 -0700267 virtual std::string ValueToString() const = 0;
ehmaldonado35a872c2017-07-28 07:29:12 -0700268 // This is the same as ValueToString except for kInt64 and kUint64 types,
269 // where the value is represented as a double instead of as an integer.
270 // Since JSON stores numbers as floating point numbers, very large integers
271 // cannot be accurately represented, so we prefer to display them as doubles
272 // instead.
273 virtual std::string ValueToJson() const = 0;
hbos74e1a4f2016-09-15 23:33:01 -0700274
Yves Gerey665174f2018-06-19 15:03:05 +0200275 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -0700276 const T& cast_to() const {
Mirko Bonadei054f1852019-11-04 16:31:08 +0100277 RTC_DCHECK_EQ(type(), T::StaticType());
hbos74e1a4f2016-09-15 23:33:01 -0700278 return static_cast<const T&>(*this);
279 }
280
281 protected:
282 RTCStatsMemberInterface(const char* name, bool is_defined)
283 : name_(name), is_defined_(is_defined) {}
284
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900285 virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
286
hbos74e1a4f2016-09-15 23:33:01 -0700287 const char* const name_;
288 bool is_defined_;
289};
290
Artem Titov0e61fdd2021-07-25 21:50:14 +0200291// Template implementation of `RTCStatsMemberInterface`.
Mirko Bonadei054f1852019-11-04 16:31:08 +0100292// The supported types are the ones described by
Artem Titovcfea2182021-08-10 01:22:31 +0200293// `RTCStatsMemberInterface::Type`.
Yves Gerey665174f2018-06-19 15:03:05 +0200294template <typename T>
Mirko Bonadei1e6aa1f2019-11-05 17:20:58 +0100295class RTCStatsMember : public RTCStatsMemberInterface {
hbos74e1a4f2016-09-15 23:33:01 -0700296 public:
hbos74e1a4f2016-09-15 23:33:01 -0700297 explicit RTCStatsMember(const char* name)
Taylor Brandstettere2751742018-06-25 13:42:44 -0700298 : RTCStatsMemberInterface(name, /*is_defined=*/false), value_() {}
hbos74e1a4f2016-09-15 23:33:01 -0700299 RTCStatsMember(const char* name, const T& value)
Taylor Brandstettere2751742018-06-25 13:42:44 -0700300 : RTCStatsMemberInterface(name, /*is_defined=*/true), value_(value) {}
hbos74e1a4f2016-09-15 23:33:01 -0700301 RTCStatsMember(const char* name, T&& value)
Taylor Brandstettere2751742018-06-25 13:42:44 -0700302 : RTCStatsMemberInterface(name, /*is_defined=*/true),
303 value_(std::move(value)) {}
hbos74e1a4f2016-09-15 23:33:01 -0700304 explicit RTCStatsMember(const RTCStatsMember<T>& other)
305 : RTCStatsMemberInterface(other.name_, other.is_defined_),
306 value_(other.value_) {}
307 explicit RTCStatsMember(RTCStatsMember<T>&& other)
308 : RTCStatsMemberInterface(other.name_, other.is_defined_),
309 value_(std::move(other.value_)) {}
310
Mirko Bonadei054f1852019-11-04 16:31:08 +0100311 static Type StaticType();
312 Type type() const override { return StaticType(); }
hbos74e1a4f2016-09-15 23:33:01 -0700313 bool is_sequence() const override;
314 bool is_string() const override;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700315 bool is_standardized() const override { return true; }
hbos74e1a4f2016-09-15 23:33:01 -0700316 std::string ValueToString() const override;
ehmaldonado35a872c2017-07-28 07:29:12 -0700317 std::string ValueToJson() const override;
hbos74e1a4f2016-09-15 23:33:01 -0700318
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000319 template <typename U>
320 inline T ValueOrDefault(U default_value) const {
321 if (is_defined()) {
322 return *(*this);
323 }
324 return default_value;
325 }
326
hbos74e1a4f2016-09-15 23:33:01 -0700327 // Assignment operators.
328 T& operator=(const T& value) {
329 value_ = value;
330 is_defined_ = true;
331 return value_;
332 }
333 T& operator=(const T&& value) {
334 value_ = std::move(value);
335 is_defined_ = true;
336 return value_;
337 }
hbos74e1a4f2016-09-15 23:33:01 -0700338
339 // Value getters.
340 T& operator*() {
341 RTC_DCHECK(is_defined_);
342 return value_;
343 }
344 const T& operator*() const {
345 RTC_DCHECK(is_defined_);
346 return value_;
347 }
348
349 // Value getters, arrow operator.
350 T* operator->() {
351 RTC_DCHECK(is_defined_);
352 return &value_;
353 }
354 const T* operator->() const {
355 RTC_DCHECK(is_defined_);
356 return &value_;
357 }
358
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900359 protected:
360 bool IsEqual(const RTCStatsMemberInterface& other) const override {
361 if (type() != other.type() || is_standardized() != other.is_standardized())
362 return false;
363 const RTCStatsMember<T>& other_t =
364 static_cast<const RTCStatsMember<T>&>(other);
365 if (!is_defined_)
366 return !other_t.is_defined();
367 if (!other.is_defined())
368 return false;
369 return value_ == other_t.value_;
370 }
371
hbos74e1a4f2016-09-15 23:33:01 -0700372 private:
373 T value_;
374};
375
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900376namespace rtc_stats_internal {
377
378typedef std::map<std::string, uint64_t> MapStringUint64;
379typedef std::map<std::string, double> MapStringDouble;
380
381} // namespace rtc_stats_internal
382
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100383#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
384 template <> \
385 RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
386 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100387 RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100388 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100389 RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100390 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100391 RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100392 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100393 RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100394 extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100395 RTCStatsMember<T>
396
397WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
398WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
399WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
400WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
401WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
402WEBRTC_DECLARE_RTCSTATSMEMBER(double);
403WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
404WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
405WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
406WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
407WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
408WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
409WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
410WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900411WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
412WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
Mirko Bonadei054f1852019-11-04 16:31:08 +0100413
Taylor Brandstettere2751742018-06-25 13:42:44 -0700414// Using inheritance just so that it's obvious from the member's declaration
415// whether it's standardized or not.
416template <typename T>
Mirko Bonadei759f1612019-11-13 11:18:31 +0100417class RTCNonStandardStatsMember : public RTCStatsMember<T> {
Taylor Brandstettere2751742018-06-25 13:42:44 -0700418 public:
419 explicit RTCNonStandardStatsMember(const char* name)
420 : RTCStatsMember<T>(name) {}
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100421 RTCNonStandardStatsMember(const char* name,
422 std::initializer_list<NonStandardGroupId> group_ids)
423 : RTCStatsMember<T>(name), group_ids_(group_ids) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700424 RTCNonStandardStatsMember(const char* name, const T& value)
425 : RTCStatsMember<T>(name, value) {}
426 RTCNonStandardStatsMember(const char* name, T&& value)
427 : RTCStatsMember<T>(name, std::move(value)) {}
428 explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100429 : RTCStatsMember<T>(other), group_ids_(other.group_ids_) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700430 explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
Mirko Bonadei759f1612019-11-13 11:18:31 +0100431 : RTCStatsMember<T>(std::move(other)),
432 group_ids_(std::move(other.group_ids_)) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700433
434 bool is_standardized() const override { return false; }
Ruslan Burakov8af88962018-11-22 17:21:10 +0100435
Jakob Ivarsson22936222019-03-22 11:29:49 +0100436 std::vector<NonStandardGroupId> group_ids() const override {
437 return group_ids_;
438 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100439
Ruslan Burakov8af88962018-11-22 17:21:10 +0100440 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
441 T& operator=(const T&& value) {
442 return RTCStatsMember<T>::operator=(std::move(value));
443 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100444
445 private:
446 std::vector<NonStandardGroupId> group_ids_;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700447};
Mirko Bonadei759f1612019-11-13 11:18:31 +0100448
449extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
450 RTCNonStandardStatsMember<bool>;
451extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
452 RTCNonStandardStatsMember<int32_t>;
453extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
454 RTCNonStandardStatsMember<uint32_t>;
455extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
456 RTCNonStandardStatsMember<int64_t>;
457extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
458 RTCNonStandardStatsMember<uint64_t>;
459extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
460 RTCNonStandardStatsMember<double>;
461extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
462 RTCNonStandardStatsMember<std::string>;
463extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
464 RTCNonStandardStatsMember<std::vector<bool>>;
465extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
466 RTCNonStandardStatsMember<std::vector<int32_t>>;
467extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
468 RTCNonStandardStatsMember<std::vector<uint32_t>>;
469extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
470 RTCNonStandardStatsMember<std::vector<int64_t>>;
471extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
472 RTCNonStandardStatsMember<std::vector<uint64_t>>;
473extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
474 RTCNonStandardStatsMember<std::vector<double>>;
475extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
476 RTCNonStandardStatsMember<std::vector<std::string>>;
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900477extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
478 RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
479extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
480 RTCNonStandardStatsMember<std::map<std::string, double>>;
Mirko Bonadei759f1612019-11-13 11:18:31 +0100481
hbos74e1a4f2016-09-15 23:33:01 -0700482} // namespace webrtc
483
Steve Anton10542f22019-01-11 09:11:00 -0800484#endif // API_STATS_RTC_STATS_H_