blob: abe2a5bcbf64cd4d0558fc2928d315e76d884742 [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
Philipp Hancke8e7a1052022-10-13 13:14:01 +020023#include "absl/types/optional.h"
Philipp Hanckeb81823a2023-01-04 15:17:42 +010024#include "api/units/timestamp.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "rtc_base/checks.h"
Mirko Bonadei276827c2018-10-16 14:13:50 +020026#include "rtc_base/system/rtc_export.h"
Mirko Bonadei054f1852019-11-04 16:31:08 +010027#include "rtc_base/system/rtc_export_template.h"
hbos74e1a4f2016-09-15 23:33:01 -070028
29namespace webrtc {
30
31class RTCStatsMemberInterface;
32
33// Abstract base class for RTCStats-derived dictionaries, see
34// https://w3c.github.io/webrtc-stats/.
35//
36// All derived classes must have the following static variable defined:
37// static const char kType[];
38// It is used as a unique class identifier and a string representation of the
39// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
Artem Titov0e61fdd2021-07-25 21:50:14 +020040// Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
hbos74e1a4f2016-09-15 23:33:01 -070041// for details.
42//
43// Derived classes list their dictionary members, RTCStatsMember<T>, as public
44// fields, allowing the following:
45//
Philipp Hanckeb81823a2023-01-04 15:17:42 +010046// RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
hbos74e1a4f2016-09-15 23:33:01 -070047// foo.bar = 42;
48// foo.baz = std::vector<std::string>();
49// foo.baz->push_back("hello world");
50// uint32_t x = *foo.bar;
51//
Artem Titov0e61fdd2021-07-25 21:50:14 +020052// Pointers to all the members are available with `Members`, allowing iteration:
hbos74e1a4f2016-09-15 23:33:01 -070053//
54// for (const RTCStatsMemberInterface* member : foo.Members()) {
55// printf("%s = %s\n", member->name(), member->ValueToString().c_str());
56// }
Mirko Bonadei276827c2018-10-16 14:13:50 +020057class RTC_EXPORT RTCStats {
hbos74e1a4f2016-09-15 23:33:01 -070058 public:
Philipp Hanckeb81823a2023-01-04 15:17:42 +010059 RTCStats(const std::string& id, Timestamp timestamp)
60 : id_(id), timestamp_(timestamp) {}
Philipp Hancke7a5de442023-01-02 13:20:45 +010061 RTCStats(std::string id, int64_t timestamp_us)
Philipp Hanckeb81823a2023-01-04 15:17:42 +010062 : RTCStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
63
hbos74e1a4f2016-09-15 23:33:01 -070064 virtual ~RTCStats() {}
65
66 virtual std::unique_ptr<RTCStats> copy() const = 0;
67
68 const std::string& id() const { return id_; }
69 // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
Philipp Hanckeb81823a2023-01-04 15:17:42 +010070 int64_t timestamp_us() const { return timestamp_.us(); }
71 Timestamp timestamp() const { return timestamp_; }
72
Artem Titov0e61fdd2021-07-25 21:50:14 +020073 // Returns the static member variable `kType` of the implementing class.
hbos74e1a4f2016-09-15 23:33:01 -070074 virtual const char* type() const = 0;
Artem Titov0e61fdd2021-07-25 21:50:14 +020075 // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
hbos67c8bc42016-10-25 04:31:23 -070076 // of this class. This allows for iteration of members. For a given class,
Artem Titov0e61fdd2021-07-25 21:50:14 +020077 // `Members` always returns the same members in the same order.
hbos74e1a4f2016-09-15 23:33:01 -070078 std::vector<const RTCStatsMemberInterface*> Members() const;
hbos67c8bc42016-10-25 04:31:23 -070079 // Checks if the two stats objects are of the same type and have the same
hbos0583b282016-11-30 01:50:14 -080080 // member values. Timestamps are not compared. These operators are exposed for
81 // testing.
hbos67c8bc42016-10-25 04:31:23 -070082 bool operator==(const RTCStats& other) const;
83 bool operator!=(const RTCStats& other) const;
hbos74e1a4f2016-09-15 23:33:01 -070084
ehmaldonado35a872c2017-07-28 07:29:12 -070085 // Creates a JSON readable string representation of the stats
86 // object, listing all of its members (names and values).
87 std::string ToJson() const;
hbos74e1a4f2016-09-15 23:33:01 -070088
Artem Titov0e61fdd2021-07-25 21:50:14 +020089 // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
90 // object is of type `T`.
Yves Gerey665174f2018-06-19 15:03:05 +020091 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -070092 const T& cast_to() const {
93 RTC_DCHECK_EQ(type(), T::kType);
94 return static_cast<const T&>(*this);
95 }
96
97 protected:
Artem Titov0e61fdd2021-07-25 21:50:14 +020098 // Gets a vector of all members of this `RTCStats` object, including members
99 // derived from parent classes. `additional_capacity` is how many more members
hbos74e1a4f2016-09-15 23:33:01 -0700100 // shall be reserved in the vector (so that subclasses can allocate a vector
101 // with room for both parent and child members without it having to resize).
102 virtual std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 15:03:05 +0200103 MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
hbos74e1a4f2016-09-15 23:33:01 -0700104
105 std::string const id_;
Philipp Hanckeb81823a2023-01-04 15:17:42 +0100106 Timestamp timestamp_;
hbos74e1a4f2016-09-15 23:33:01 -0700107};
108
Artem Titov0e61fdd2021-07-25 21:50:14 +0200109// All `RTCStats` classes should use these macros.
110// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
111// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
hbos74e1a4f2016-09-15 23:33:01 -0700112//
Artem Titov0e61fdd2021-07-25 21:50:14 +0200113// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
114// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
115// `MembersOfThisObjectAndAncestors`. The |...| argument is a list of addresses
hbosfc5e0502016-10-06 02:06:10 -0700116// to each member defined in the implementing class. The list must have at least
117// one member.
hbos74e1a4f2016-09-15 23:33:01 -0700118//
119// (Since class names need to be known to implement these methods this cannot be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200120// part of the base `RTCStats`. While these methods could be implemented using
hbos74e1a4f2016-09-15 23:33:01 -0700121// templates, that would only work for immediate subclasses. Subclasses of
122// subclasses also have to override these methods, resulting in boilerplate
Artem Titov0e61fdd2021-07-25 21:50:14 +0200123// code. Using a macro avoids this and works for any `RTCStats` class, including
hbos74e1a4f2016-09-15 23:33:01 -0700124// grandchildren.)
125//
126// Sample usage:
127//
128// rtcfoostats.h:
129// class RTCFooStats : public RTCStats {
130// public:
hbosfc5e0502016-10-06 02:06:10 -0700131// WEBRTC_RTCSTATS_DECL();
hbos74e1a4f2016-09-15 23:33:01 -0700132//
hbosfc5e0502016-10-06 02:06:10 -0700133// RTCFooStats(const std::string& id, int64_t timestamp_us);
hbos74e1a4f2016-09-15 23:33:01 -0700134//
135// RTCStatsMember<int32_t> foo;
136// RTCStatsMember<int32_t> bar;
137// };
138//
139// rtcfoostats.cc:
hbosfc5e0502016-10-06 02:06:10 -0700140// WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
141// &foo,
142// &bar);
hbos74e1a4f2016-09-15 23:33:01 -0700143//
hbosfc5e0502016-10-06 02:06:10 -0700144// RTCFooStats::RTCFooStats(const std::string& id, int64_t timestamp_us)
145// : RTCStats(id, timestamp_us),
146// foo("foo"),
147// bar("bar") {
148// }
149//
Yves Gerey665174f2018-06-19 15:03:05 +0200150#define WEBRTC_RTCSTATS_DECL() \
Yves Gerey665174f2018-06-19 15:03:05 +0200151 protected: \
152 std::vector<const webrtc::RTCStatsMemberInterface*> \
153 MembersOfThisObjectAndAncestors(size_t local_var_additional_capacity) \
154 const override; \
155 \
Nico Weber22f99252019-02-20 10:13:16 -0500156 public: \
157 static const char kType[]; \
158 \
159 std::unique_ptr<webrtc::RTCStats> copy() const override; \
160 const char* type() const override
hbosfc5e0502016-10-06 02:06:10 -0700161
162#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...) \
163 const char this_class::kType[] = type_str; \
164 \
165 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200166 return std::make_unique<this_class>(*this); \
hbosfc5e0502016-10-06 02:06:10 -0700167 } \
168 \
Yves Gerey665174f2018-06-19 15:03:05 +0200169 const char* this_class::type() const { return this_class::kType; } \
hbosfc5e0502016-10-06 02:06:10 -0700170 \
171 std::vector<const webrtc::RTCStatsMemberInterface*> \
172 this_class::MembersOfThisObjectAndAncestors( \
173 size_t local_var_additional_capacity) const { \
hbos74e1a4f2016-09-15 23:33:01 -0700174 const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
Yves Gerey665174f2018-06-19 15:03:05 +0200175 __VA_ARGS__}; \
hbos74e1a4f2016-09-15 23:33:01 -0700176 size_t local_var_members_count = \
177 sizeof(local_var_members) / sizeof(local_var_members[0]); \
Yves Gerey665174f2018-06-19 15:03:05 +0200178 std::vector<const webrtc::RTCStatsMemberInterface*> \
179 local_var_members_vec = parent_class::MembersOfThisObjectAndAncestors( \
hbos74e1a4f2016-09-15 23:33:01 -0700180 local_var_members_count + local_var_additional_capacity); \
181 RTC_DCHECK_GE( \
182 local_var_members_vec.capacity() - local_var_members_vec.size(), \
183 local_var_members_count + local_var_additional_capacity); \
184 local_var_members_vec.insert(local_var_members_vec.end(), \
185 &local_var_members[0], \
186 &local_var_members[local_var_members_count]); \
187 return local_var_members_vec; \
hbosfc5e0502016-10-06 02:06:10 -0700188 }
hbos74e1a4f2016-09-15 23:33:01 -0700189
Henrik Boström646fda02019-05-22 15:49:42 +0200190// A version of WEBRTC_RTCSTATS_IMPL() where "..." is omitted, used to avoid a
191// compile error on windows. This is used if the stats dictionary does not
192// declare any members of its own (but perhaps its parent dictionary does).
193#define WEBRTC_RTCSTATS_IMPL_NO_MEMBERS(this_class, parent_class, type_str) \
194 const char this_class::kType[] = type_str; \
195 \
196 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200197 return std::make_unique<this_class>(*this); \
Henrik Boström646fda02019-05-22 15:49:42 +0200198 } \
199 \
200 const char* this_class::type() const { return this_class::kType; } \
201 \
202 std::vector<const webrtc::RTCStatsMemberInterface*> \
203 this_class::MembersOfThisObjectAndAncestors( \
204 size_t local_var_additional_capacity) const { \
205 return parent_class::MembersOfThisObjectAndAncestors(0); \
206 }
207
Jakob Ivarsson22936222019-03-22 11:29:49 +0100208// Non-standard stats members can be exposed to the JavaScript API in Chrome
209// e.g. through origin trials. The group ID can be used by the blink layer to
210// determine if a stats member should be exposed or not. Multiple non-standard
211// stats members can share the same group ID so that they are exposed together.
212enum class NonStandardGroupId {
Jakob Ivarssonaa023e22019-03-27 10:17:31 +0100213 // Group ID used for testing purposes only.
214 kGroupIdForTesting,
Jakob Ivarsson22936222019-03-22 11:29:49 +0100215 // I2E:
216 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
217 kRtcAudioJitterBufferMaxPackets,
218 // I2E:
219 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
220 kRtcStatsRelativePacketArrivalDelay,
221};
222
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000223// Certain stat members should only be exposed to the JavaScript API in
224// certain circumstances as to avoid passive fingerprinting.
225enum class StatExposureCriteria : uint8_t {
226 // The stat should always be exposed. This is the default.
227 kAlways,
228 // The stat exposes hardware capabilities and thus should has limited exposure
229 // to JavaScript. The requirements for exposure are written in the spec at
230 // https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
231 kHardwareCapability,
232};
233
Artem Titov0e61fdd2021-07-25 21:50:14 +0200234// Interface for `RTCStats` members, which have a name and a value of a type
235// defined in a subclass. Only the types listed in `Type` are supported, these
Artem Titovcfea2182021-08-10 01:22:31 +0200236// are implemented by `RTCStatsMember<T>`. The value of a member may be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200237// undefined, the value can only be read if `is_defined`.
hbos74e1a4f2016-09-15 23:33:01 -0700238class RTCStatsMemberInterface {
239 public:
240 // Member value types.
241 enum Type {
Yves Gerey665174f2018-06-19 15:03:05 +0200242 kBool, // bool
243 kInt32, // int32_t
244 kUint32, // uint32_t
245 kInt64, // int64_t
246 kUint64, // uint64_t
247 kDouble, // double
248 kString, // std::string
hbos74e1a4f2016-09-15 23:33:01 -0700249
Yves Gerey665174f2018-06-19 15:03:05 +0200250 kSequenceBool, // std::vector<bool>
251 kSequenceInt32, // std::vector<int32_t>
252 kSequenceUint32, // std::vector<uint32_t>
253 kSequenceInt64, // std::vector<int64_t>
254 kSequenceUint64, // std::vector<uint64_t>
255 kSequenceDouble, // std::vector<double>
256 kSequenceString, // std::vector<std::string>
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900257
258 kMapStringUint64, // std::map<std::string, uint64_t>
259 kMapStringDouble, // std::map<std::string, double>
hbos74e1a4f2016-09-15 23:33:01 -0700260 };
261
262 virtual ~RTCStatsMemberInterface() {}
263
264 const char* name() const { return name_; }
265 virtual Type type() const = 0;
266 virtual bool is_sequence() const = 0;
267 virtual bool is_string() const = 0;
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200268 virtual bool is_defined() const = 0;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700269 // Is this part of the stats spec? Used so that chromium can easily filter
270 // out anything unstandardized.
271 virtual bool is_standardized() const = 0;
Jakob Ivarsson22936222019-03-22 11:29:49 +0100272 // Non-standard stats members can have group IDs in order to be exposed in
273 // JavaScript through experiments. Standardized stats have no group IDs.
274 virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000275 // The conditions for exposing the statistic to JavaScript. Stats with
276 // criteria that is not kAlways has some restriction and should be filtered
277 // in accordance to the spec.
278 virtual StatExposureCriteria exposure_criteria() const {
279 return StatExposureCriteria::kAlways;
280 }
hbos67c8bc42016-10-25 04:31:23 -0700281 // Type and value comparator. The names are not compared. These operators are
282 // exposed for testing.
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900283 bool operator==(const RTCStatsMemberInterface& other) const {
284 return IsEqual(other);
285 }
hbos67c8bc42016-10-25 04:31:23 -0700286 bool operator!=(const RTCStatsMemberInterface& other) const {
287 return !(*this == other);
288 }
hbos74e1a4f2016-09-15 23:33:01 -0700289 virtual std::string ValueToString() const = 0;
ehmaldonado35a872c2017-07-28 07:29:12 -0700290 // This is the same as ValueToString except for kInt64 and kUint64 types,
291 // where the value is represented as a double instead of as an integer.
292 // Since JSON stores numbers as floating point numbers, very large integers
293 // cannot be accurately represented, so we prefer to display them as doubles
294 // instead.
295 virtual std::string ValueToJson() const = 0;
hbos74e1a4f2016-09-15 23:33:01 -0700296
Yves Gerey665174f2018-06-19 15:03:05 +0200297 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -0700298 const T& cast_to() const {
Mirko Bonadei054f1852019-11-04 16:31:08 +0100299 RTC_DCHECK_EQ(type(), T::StaticType());
hbos74e1a4f2016-09-15 23:33:01 -0700300 return static_cast<const T&>(*this);
301 }
302
303 protected:
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200304 explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
hbos74e1a4f2016-09-15 23:33:01 -0700305
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900306 virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
307
hbos74e1a4f2016-09-15 23:33:01 -0700308 const char* const name_;
hbos74e1a4f2016-09-15 23:33:01 -0700309};
310
Artem Titov0e61fdd2021-07-25 21:50:14 +0200311// Template implementation of `RTCStatsMemberInterface`.
Mirko Bonadei054f1852019-11-04 16:31:08 +0100312// The supported types are the ones described by
Artem Titovcfea2182021-08-10 01:22:31 +0200313// `RTCStatsMemberInterface::Type`.
Yves Gerey665174f2018-06-19 15:03:05 +0200314template <typename T>
Mirko Bonadei1e6aa1f2019-11-05 17:20:58 +0100315class RTCStatsMember : public RTCStatsMemberInterface {
hbos74e1a4f2016-09-15 23:33:01 -0700316 public:
hbos74e1a4f2016-09-15 23:33:01 -0700317 explicit RTCStatsMember(const char* name)
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200318 : RTCStatsMemberInterface(name), value_() {}
hbos74e1a4f2016-09-15 23:33:01 -0700319 RTCStatsMember(const char* name, const T& value)
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200320 : RTCStatsMemberInterface(name), value_(value) {}
hbos74e1a4f2016-09-15 23:33:01 -0700321 RTCStatsMember(const char* name, T&& value)
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200322 : RTCStatsMemberInterface(name), value_(std::move(value)) {}
323 explicit RTCStatsMember(const RTCStatsMember<T>& other)
324 : RTCStatsMemberInterface(other.name_), value_(other.value_) {}
325 explicit RTCStatsMember(RTCStatsMember<T>&& other)
326 : RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
hbos74e1a4f2016-09-15 23:33:01 -0700327
Mirko Bonadei054f1852019-11-04 16:31:08 +0100328 static Type StaticType();
329 Type type() const override { return StaticType(); }
hbos74e1a4f2016-09-15 23:33:01 -0700330 bool is_sequence() const override;
331 bool is_string() const override;
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200332 bool is_defined() const override { return value_.has_value(); }
Taylor Brandstettere2751742018-06-25 13:42:44 -0700333 bool is_standardized() const override { return true; }
hbos74e1a4f2016-09-15 23:33:01 -0700334 std::string ValueToString() const override;
ehmaldonado35a872c2017-07-28 07:29:12 -0700335 std::string ValueToJson() const override;
hbos74e1a4f2016-09-15 23:33:01 -0700336
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000337 template <typename U>
338 inline T ValueOrDefault(U default_value) const {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200339 return value_.value_or(default_value);
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000340 }
341
hbos74e1a4f2016-09-15 23:33:01 -0700342 // Assignment operators.
343 T& operator=(const T& value) {
344 value_ = value;
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200345 return value_.value();
hbos74e1a4f2016-09-15 23:33:01 -0700346 }
347 T& operator=(const T&& value) {
348 value_ = std::move(value);
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200349 return value_.value();
hbos74e1a4f2016-09-15 23:33:01 -0700350 }
hbos74e1a4f2016-09-15 23:33:01 -0700351
352 // Value getters.
353 T& operator*() {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200354 RTC_DCHECK(value_);
355 return *value_;
hbos74e1a4f2016-09-15 23:33:01 -0700356 }
357 const T& operator*() const {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200358 RTC_DCHECK(value_);
359 return *value_;
hbos74e1a4f2016-09-15 23:33:01 -0700360 }
361
362 // Value getters, arrow operator.
363 T* operator->() {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200364 RTC_DCHECK(value_);
365 return &(*value_);
hbos74e1a4f2016-09-15 23:33:01 -0700366 }
367 const T* operator->() const {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200368 RTC_DCHECK(value_);
369 return &(*value_);
hbos74e1a4f2016-09-15 23:33:01 -0700370 }
371
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900372 protected:
373 bool IsEqual(const RTCStatsMemberInterface& other) const override {
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000374 if (type() != other.type() ||
375 is_standardized() != other.is_standardized() ||
376 exposure_criteria() != other.exposure_criteria())
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900377 return false;
378 const RTCStatsMember<T>& other_t =
379 static_cast<const RTCStatsMember<T>&>(other);
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900380 return value_ == other_t.value_;
381 }
382
hbos74e1a4f2016-09-15 23:33:01 -0700383 private:
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200384 absl::optional<T> value_;
hbos74e1a4f2016-09-15 23:33:01 -0700385};
386
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900387namespace rtc_stats_internal {
388
389typedef std::map<std::string, uint64_t> MapStringUint64;
390typedef std::map<std::string, double> MapStringDouble;
391
392} // namespace rtc_stats_internal
393
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100394#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
395 template <> \
396 RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
397 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100398 RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100399 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100400 RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100401 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100402 RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100403 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100404 RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100405 extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100406 RTCStatsMember<T>
407
408WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
409WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
410WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
411WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
412WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
413WEBRTC_DECLARE_RTCSTATSMEMBER(double);
414WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
415WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
416WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
417WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
418WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
419WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
420WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
421WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900422WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
423WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
Mirko Bonadei054f1852019-11-04 16:31:08 +0100424
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000425// For stats with restricted exposure.
426template <typename T, StatExposureCriteria E>
427class RTCRestrictedStatsMember : public RTCStatsMember<T> {
428 public:
429 explicit RTCRestrictedStatsMember(const char* name)
430 : RTCStatsMember<T>(name) {}
431 RTCRestrictedStatsMember(const char* name, const T& value)
432 : RTCStatsMember<T>(name, value) {}
433 RTCRestrictedStatsMember(const char* name, T&& value)
434 : RTCStatsMember<T>(name, std::move(value)) {}
435 RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T, E>& other)
436 : RTCStatsMember<T>(other) {}
437 RTCRestrictedStatsMember(RTCRestrictedStatsMember<T, E>&& other)
438 : RTCStatsMember<T>(std::move(other)) {}
439
440 StatExposureCriteria exposure_criteria() const override { return E; }
441
442 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
443 T& operator=(const T&& value) {
444 return RTCStatsMember<T>::operator=(std::move(value));
445 }
446
447 private:
448 static_assert(E != StatExposureCriteria::kAlways,
449 "kAlways is the default exposure criteria. Use "
450 "RTCStatMember<T> instead.");
451};
452
453extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
454 RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
455extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
456 RTCRestrictedStatsMember<int32_t,
457 StatExposureCriteria::kHardwareCapability>;
458extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
459 RTCRestrictedStatsMember<uint32_t,
460 StatExposureCriteria::kHardwareCapability>;
461extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
462 RTCRestrictedStatsMember<int64_t,
463 StatExposureCriteria::kHardwareCapability>;
464extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
465 RTCRestrictedStatsMember<uint64_t,
466 StatExposureCriteria::kHardwareCapability>;
467extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
468 RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
469extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
470 RTCRestrictedStatsMember<std::string,
471 StatExposureCriteria::kHardwareCapability>;
472extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
473 RTCRestrictedStatsMember<std::vector<bool>,
474 StatExposureCriteria::kHardwareCapability>;
475extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
476 RTCRestrictedStatsMember<std::vector<int32_t>,
477 StatExposureCriteria::kHardwareCapability>;
478extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
479 RTCRestrictedStatsMember<std::vector<uint32_t>,
480 StatExposureCriteria::kHardwareCapability>;
481extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
482 RTCRestrictedStatsMember<std::vector<int64_t>,
483 StatExposureCriteria::kHardwareCapability>;
484extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
485 RTCRestrictedStatsMember<std::vector<uint64_t>,
486 StatExposureCriteria::kHardwareCapability>;
487extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
488 RTCRestrictedStatsMember<std::vector<double>,
489 StatExposureCriteria::kHardwareCapability>;
490extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
491 RTCRestrictedStatsMember<std::vector<std::string>,
492 StatExposureCriteria::kHardwareCapability>;
493extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
494 RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
495 StatExposureCriteria::kHardwareCapability>;
496extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
497 RTCRestrictedStatsMember<std::map<std::string, double>,
498 StatExposureCriteria::kHardwareCapability>;
499
Taylor Brandstettere2751742018-06-25 13:42:44 -0700500// Using inheritance just so that it's obvious from the member's declaration
501// whether it's standardized or not.
502template <typename T>
Mirko Bonadei759f1612019-11-13 11:18:31 +0100503class RTCNonStandardStatsMember : public RTCStatsMember<T> {
Taylor Brandstettere2751742018-06-25 13:42:44 -0700504 public:
505 explicit RTCNonStandardStatsMember(const char* name)
506 : RTCStatsMember<T>(name) {}
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100507 RTCNonStandardStatsMember(const char* name,
508 std::initializer_list<NonStandardGroupId> group_ids)
509 : RTCStatsMember<T>(name), group_ids_(group_ids) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700510 RTCNonStandardStatsMember(const char* name, const T& value)
511 : RTCStatsMember<T>(name, value) {}
512 RTCNonStandardStatsMember(const char* name, T&& value)
513 : RTCStatsMember<T>(name, std::move(value)) {}
514 explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100515 : RTCStatsMember<T>(other), group_ids_(other.group_ids_) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700516 explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
Mirko Bonadei759f1612019-11-13 11:18:31 +0100517 : RTCStatsMember<T>(std::move(other)),
518 group_ids_(std::move(other.group_ids_)) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700519
520 bool is_standardized() const override { return false; }
Ruslan Burakov8af88962018-11-22 17:21:10 +0100521
Jakob Ivarsson22936222019-03-22 11:29:49 +0100522 std::vector<NonStandardGroupId> group_ids() const override {
523 return group_ids_;
524 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100525
Ruslan Burakov8af88962018-11-22 17:21:10 +0100526 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
527 T& operator=(const T&& value) {
528 return RTCStatsMember<T>::operator=(std::move(value));
529 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100530
531 private:
532 std::vector<NonStandardGroupId> group_ids_;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700533};
Mirko Bonadei759f1612019-11-13 11:18:31 +0100534
535extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
536 RTCNonStandardStatsMember<bool>;
537extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
538 RTCNonStandardStatsMember<int32_t>;
539extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
540 RTCNonStandardStatsMember<uint32_t>;
541extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
542 RTCNonStandardStatsMember<int64_t>;
543extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
544 RTCNonStandardStatsMember<uint64_t>;
545extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
546 RTCNonStandardStatsMember<double>;
547extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
548 RTCNonStandardStatsMember<std::string>;
549extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
550 RTCNonStandardStatsMember<std::vector<bool>>;
551extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
552 RTCNonStandardStatsMember<std::vector<int32_t>>;
553extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
554 RTCNonStandardStatsMember<std::vector<uint32_t>>;
555extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
556 RTCNonStandardStatsMember<std::vector<int64_t>>;
557extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
558 RTCNonStandardStatsMember<std::vector<uint64_t>>;
559extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
560 RTCNonStandardStatsMember<std::vector<double>>;
561extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
562 RTCNonStandardStatsMember<std::vector<std::string>>;
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900563extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
564 RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
565extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
566 RTCNonStandardStatsMember<std::map<std::string, double>>;
Mirko Bonadei759f1612019-11-13 11:18:31 +0100567
hbos74e1a4f2016-09-15 23:33:01 -0700568} // namespace webrtc
569
Steve Anton10542f22019-01-11 09:11:00 -0800570#endif // API_STATS_RTC_STATS_H_