blob: e22043df5c9696abcfc5e1eeab1f8e1e2cb7ec51 [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
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000218// Certain stat members should only be exposed to the JavaScript API in
219// certain circumstances as to avoid passive fingerprinting.
220enum class StatExposureCriteria : uint8_t {
221 // The stat should always be exposed. This is the default.
222 kAlways,
223 // The stat exposes hardware capabilities and thus should has limited exposure
224 // to JavaScript. The requirements for exposure are written in the spec at
225 // https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
226 kHardwareCapability,
227};
228
Artem Titov0e61fdd2021-07-25 21:50:14 +0200229// Interface for `RTCStats` members, which have a name and a value of a type
230// defined in a subclass. Only the types listed in `Type` are supported, these
Artem Titovcfea2182021-08-10 01:22:31 +0200231// are implemented by `RTCStatsMember<T>`. The value of a member may be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200232// undefined, the value can only be read if `is_defined`.
hbos74e1a4f2016-09-15 23:33:01 -0700233class RTCStatsMemberInterface {
234 public:
235 // Member value types.
236 enum Type {
Yves Gerey665174f2018-06-19 15:03:05 +0200237 kBool, // bool
238 kInt32, // int32_t
239 kUint32, // uint32_t
240 kInt64, // int64_t
241 kUint64, // uint64_t
242 kDouble, // double
243 kString, // std::string
hbos74e1a4f2016-09-15 23:33:01 -0700244
Yves Gerey665174f2018-06-19 15:03:05 +0200245 kSequenceBool, // std::vector<bool>
246 kSequenceInt32, // std::vector<int32_t>
247 kSequenceUint32, // std::vector<uint32_t>
248 kSequenceInt64, // std::vector<int64_t>
249 kSequenceUint64, // std::vector<uint64_t>
250 kSequenceDouble, // std::vector<double>
251 kSequenceString, // std::vector<std::string>
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900252
253 kMapStringUint64, // std::map<std::string, uint64_t>
254 kMapStringDouble, // std::map<std::string, double>
hbos74e1a4f2016-09-15 23:33:01 -0700255 };
256
257 virtual ~RTCStatsMemberInterface() {}
258
259 const char* name() const { return name_; }
260 virtual Type type() const = 0;
261 virtual bool is_sequence() const = 0;
262 virtual bool is_string() const = 0;
263 bool is_defined() const { return is_defined_; }
Taylor Brandstettere2751742018-06-25 13:42:44 -0700264 // Is this part of the stats spec? Used so that chromium can easily filter
265 // out anything unstandardized.
266 virtual bool is_standardized() const = 0;
Jakob Ivarsson22936222019-03-22 11:29:49 +0100267 // Non-standard stats members can have group IDs in order to be exposed in
268 // JavaScript through experiments. Standardized stats have no group IDs.
269 virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000270 // The conditions for exposing the statistic to JavaScript. Stats with
271 // criteria that is not kAlways has some restriction and should be filtered
272 // in accordance to the spec.
273 virtual StatExposureCriteria exposure_criteria() const {
274 return StatExposureCriteria::kAlways;
275 }
hbos67c8bc42016-10-25 04:31:23 -0700276 // Type and value comparator. The names are not compared. These operators are
277 // exposed for testing.
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900278 bool operator==(const RTCStatsMemberInterface& other) const {
279 return IsEqual(other);
280 }
hbos67c8bc42016-10-25 04:31:23 -0700281 bool operator!=(const RTCStatsMemberInterface& other) const {
282 return !(*this == other);
283 }
hbos74e1a4f2016-09-15 23:33:01 -0700284 virtual std::string ValueToString() const = 0;
ehmaldonado35a872c2017-07-28 07:29:12 -0700285 // This is the same as ValueToString except for kInt64 and kUint64 types,
286 // where the value is represented as a double instead of as an integer.
287 // Since JSON stores numbers as floating point numbers, very large integers
288 // cannot be accurately represented, so we prefer to display them as doubles
289 // instead.
290 virtual std::string ValueToJson() const = 0;
hbos74e1a4f2016-09-15 23:33:01 -0700291
Yves Gerey665174f2018-06-19 15:03:05 +0200292 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -0700293 const T& cast_to() const {
Mirko Bonadei054f1852019-11-04 16:31:08 +0100294 RTC_DCHECK_EQ(type(), T::StaticType());
hbos74e1a4f2016-09-15 23:33:01 -0700295 return static_cast<const T&>(*this);
296 }
297
298 protected:
299 RTCStatsMemberInterface(const char* name, bool is_defined)
300 : name_(name), is_defined_(is_defined) {}
301
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900302 virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
303
hbos74e1a4f2016-09-15 23:33:01 -0700304 const char* const name_;
305 bool is_defined_;
306};
307
Artem Titov0e61fdd2021-07-25 21:50:14 +0200308// Template implementation of `RTCStatsMemberInterface`.
Mirko Bonadei054f1852019-11-04 16:31:08 +0100309// The supported types are the ones described by
Artem Titovcfea2182021-08-10 01:22:31 +0200310// `RTCStatsMemberInterface::Type`.
Yves Gerey665174f2018-06-19 15:03:05 +0200311template <typename T>
Mirko Bonadei1e6aa1f2019-11-05 17:20:58 +0100312class RTCStatsMember : public RTCStatsMemberInterface {
hbos74e1a4f2016-09-15 23:33:01 -0700313 public:
hbos74e1a4f2016-09-15 23:33:01 -0700314 explicit RTCStatsMember(const char* name)
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000315 : RTCStatsMemberInterface(name,
316 /*is_defined=*/false),
317 value_() {}
hbos74e1a4f2016-09-15 23:33:01 -0700318 RTCStatsMember(const char* name, const T& value)
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000319 : RTCStatsMemberInterface(name,
320 /*is_defined=*/true),
321 value_(value) {}
hbos74e1a4f2016-09-15 23:33:01 -0700322 RTCStatsMember(const char* name, T&& value)
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000323 : RTCStatsMemberInterface(name,
324 /*is_defined=*/true),
Taylor Brandstettere2751742018-06-25 13:42:44 -0700325 value_(std::move(value)) {}
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000326 RTCStatsMember(const RTCStatsMember<T>& other)
hbos74e1a4f2016-09-15 23:33:01 -0700327 : RTCStatsMemberInterface(other.name_, other.is_defined_),
328 value_(other.value_) {}
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000329 RTCStatsMember(RTCStatsMember<T>&& other)
hbos74e1a4f2016-09-15 23:33:01 -0700330 : RTCStatsMemberInterface(other.name_, other.is_defined_),
331 value_(std::move(other.value_)) {}
332
Mirko Bonadei054f1852019-11-04 16:31:08 +0100333 static Type StaticType();
334 Type type() const override { return StaticType(); }
hbos74e1a4f2016-09-15 23:33:01 -0700335 bool is_sequence() const override;
336 bool is_string() const override;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700337 bool is_standardized() const override { return true; }
hbos74e1a4f2016-09-15 23:33:01 -0700338 std::string ValueToString() const override;
ehmaldonado35a872c2017-07-28 07:29:12 -0700339 std::string ValueToJson() const override;
hbos74e1a4f2016-09-15 23:33:01 -0700340
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000341 template <typename U>
342 inline T ValueOrDefault(U default_value) const {
343 if (is_defined()) {
344 return *(*this);
345 }
346 return default_value;
347 }
348
hbos74e1a4f2016-09-15 23:33:01 -0700349 // Assignment operators.
350 T& operator=(const T& value) {
351 value_ = value;
352 is_defined_ = true;
353 return value_;
354 }
355 T& operator=(const T&& value) {
356 value_ = std::move(value);
357 is_defined_ = true;
358 return value_;
359 }
hbos74e1a4f2016-09-15 23:33:01 -0700360
361 // Value getters.
362 T& operator*() {
363 RTC_DCHECK(is_defined_);
364 return value_;
365 }
366 const T& operator*() const {
367 RTC_DCHECK(is_defined_);
368 return value_;
369 }
370
371 // Value getters, arrow operator.
372 T* operator->() {
373 RTC_DCHECK(is_defined_);
374 return &value_;
375 }
376 const T* operator->() const {
377 RTC_DCHECK(is_defined_);
378 return &value_;
379 }
380
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900381 protected:
382 bool IsEqual(const RTCStatsMemberInterface& other) const override {
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000383 if (type() != other.type() ||
384 is_standardized() != other.is_standardized() ||
385 exposure_criteria() != other.exposure_criteria())
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900386 return false;
387 const RTCStatsMember<T>& other_t =
388 static_cast<const RTCStatsMember<T>&>(other);
389 if (!is_defined_)
390 return !other_t.is_defined();
391 if (!other.is_defined())
392 return false;
393 return value_ == other_t.value_;
394 }
395
hbos74e1a4f2016-09-15 23:33:01 -0700396 private:
397 T value_;
398};
399
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900400namespace rtc_stats_internal {
401
402typedef std::map<std::string, uint64_t> MapStringUint64;
403typedef std::map<std::string, double> MapStringDouble;
404
405} // namespace rtc_stats_internal
406
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100407#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
408 template <> \
409 RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
410 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100411 RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100412 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100413 RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100414 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100415 RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100416 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100417 RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100418 extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100419 RTCStatsMember<T>
420
421WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
422WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
423WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
424WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
425WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
426WEBRTC_DECLARE_RTCSTATSMEMBER(double);
427WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
428WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
429WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
430WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
431WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
432WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
433WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
434WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900435WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
436WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
Mirko Bonadei054f1852019-11-04 16:31:08 +0100437
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000438// For stats with restricted exposure.
439template <typename T, StatExposureCriteria E>
440class RTCRestrictedStatsMember : public RTCStatsMember<T> {
441 public:
442 explicit RTCRestrictedStatsMember(const char* name)
443 : RTCStatsMember<T>(name) {}
444 RTCRestrictedStatsMember(const char* name, const T& value)
445 : RTCStatsMember<T>(name, value) {}
446 RTCRestrictedStatsMember(const char* name, T&& value)
447 : RTCStatsMember<T>(name, std::move(value)) {}
448 RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T, E>& other)
449 : RTCStatsMember<T>(other) {}
450 RTCRestrictedStatsMember(RTCRestrictedStatsMember<T, E>&& other)
451 : RTCStatsMember<T>(std::move(other)) {}
452
453 StatExposureCriteria exposure_criteria() const override { return E; }
454
455 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
456 T& operator=(const T&& value) {
457 return RTCStatsMember<T>::operator=(std::move(value));
458 }
459
460 private:
461 static_assert(E != StatExposureCriteria::kAlways,
462 "kAlways is the default exposure criteria. Use "
463 "RTCStatMember<T> instead.");
464};
465
466extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
467 RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
468extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
469 RTCRestrictedStatsMember<int32_t,
470 StatExposureCriteria::kHardwareCapability>;
471extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
472 RTCRestrictedStatsMember<uint32_t,
473 StatExposureCriteria::kHardwareCapability>;
474extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
475 RTCRestrictedStatsMember<int64_t,
476 StatExposureCriteria::kHardwareCapability>;
477extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
478 RTCRestrictedStatsMember<uint64_t,
479 StatExposureCriteria::kHardwareCapability>;
480extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
481 RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
482extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
483 RTCRestrictedStatsMember<std::string,
484 StatExposureCriteria::kHardwareCapability>;
485extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
486 RTCRestrictedStatsMember<std::vector<bool>,
487 StatExposureCriteria::kHardwareCapability>;
488extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
489 RTCRestrictedStatsMember<std::vector<int32_t>,
490 StatExposureCriteria::kHardwareCapability>;
491extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
492 RTCRestrictedStatsMember<std::vector<uint32_t>,
493 StatExposureCriteria::kHardwareCapability>;
494extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
495 RTCRestrictedStatsMember<std::vector<int64_t>,
496 StatExposureCriteria::kHardwareCapability>;
497extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
498 RTCRestrictedStatsMember<std::vector<uint64_t>,
499 StatExposureCriteria::kHardwareCapability>;
500extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
501 RTCRestrictedStatsMember<std::vector<double>,
502 StatExposureCriteria::kHardwareCapability>;
503extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
504 RTCRestrictedStatsMember<std::vector<std::string>,
505 StatExposureCriteria::kHardwareCapability>;
506extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
507 RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
508 StatExposureCriteria::kHardwareCapability>;
509extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
510 RTCRestrictedStatsMember<std::map<std::string, double>,
511 StatExposureCriteria::kHardwareCapability>;
512
Taylor Brandstettere2751742018-06-25 13:42:44 -0700513// Using inheritance just so that it's obvious from the member's declaration
514// whether it's standardized or not.
515template <typename T>
Mirko Bonadei759f1612019-11-13 11:18:31 +0100516class RTCNonStandardStatsMember : public RTCStatsMember<T> {
Taylor Brandstettere2751742018-06-25 13:42:44 -0700517 public:
518 explicit RTCNonStandardStatsMember(const char* name)
519 : RTCStatsMember<T>(name) {}
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100520 RTCNonStandardStatsMember(const char* name,
521 std::initializer_list<NonStandardGroupId> group_ids)
522 : RTCStatsMember<T>(name), group_ids_(group_ids) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700523 RTCNonStandardStatsMember(const char* name, const T& value)
524 : RTCStatsMember<T>(name, value) {}
525 RTCNonStandardStatsMember(const char* name, T&& value)
526 : RTCStatsMember<T>(name, std::move(value)) {}
527 explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100528 : RTCStatsMember<T>(other), group_ids_(other.group_ids_) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700529 explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
Mirko Bonadei759f1612019-11-13 11:18:31 +0100530 : RTCStatsMember<T>(std::move(other)),
531 group_ids_(std::move(other.group_ids_)) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700532
533 bool is_standardized() const override { return false; }
Ruslan Burakov8af88962018-11-22 17:21:10 +0100534
Jakob Ivarsson22936222019-03-22 11:29:49 +0100535 std::vector<NonStandardGroupId> group_ids() const override {
536 return group_ids_;
537 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100538
Ruslan Burakov8af88962018-11-22 17:21:10 +0100539 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
540 T& operator=(const T&& value) {
541 return RTCStatsMember<T>::operator=(std::move(value));
542 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100543
544 private:
545 std::vector<NonStandardGroupId> group_ids_;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700546};
Mirko Bonadei759f1612019-11-13 11:18:31 +0100547
548extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
549 RTCNonStandardStatsMember<bool>;
550extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
551 RTCNonStandardStatsMember<int32_t>;
552extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
553 RTCNonStandardStatsMember<uint32_t>;
554extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
555 RTCNonStandardStatsMember<int64_t>;
556extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
557 RTCNonStandardStatsMember<uint64_t>;
558extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
559 RTCNonStandardStatsMember<double>;
560extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
561 RTCNonStandardStatsMember<std::string>;
562extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
563 RTCNonStandardStatsMember<std::vector<bool>>;
564extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
565 RTCNonStandardStatsMember<std::vector<int32_t>>;
566extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
567 RTCNonStandardStatsMember<std::vector<uint32_t>>;
568extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
569 RTCNonStandardStatsMember<std::vector<int64_t>>;
570extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
571 RTCNonStandardStatsMember<std::vector<uint64_t>>;
572extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
573 RTCNonStandardStatsMember<std::vector<double>>;
574extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
575 RTCNonStandardStatsMember<std::vector<std::string>>;
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900576extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
577 RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
578extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
579 RTCNonStandardStatsMember<std::map<std::string, double>>;
Mirko Bonadei759f1612019-11-13 11:18:31 +0100580
hbos74e1a4f2016-09-15 23:33:01 -0700581} // namespace webrtc
582
Steve Anton10542f22019-01-11 09:11:00 -0800583#endif // API_STATS_RTC_STATS_H_