blob: 72775243c7a9a5f511ee51f660fd2f65d336c893 [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 Hanckee137c452023-01-10 13:06:02 +010061 ABSL_DEPRECATED("Use constructor with Timestamp instead")
Philipp Hancke7a5de442023-01-02 13:20:45 +010062 RTCStats(std::string id, int64_t timestamp_us)
Philipp Hanckeb81823a2023-01-04 15:17:42 +010063 : RTCStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
64
hbos74e1a4f2016-09-15 23:33:01 -070065 virtual ~RTCStats() {}
66
67 virtual std::unique_ptr<RTCStats> copy() const = 0;
68
69 const std::string& id() const { return id_; }
70 // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
Philipp Hanckee137c452023-01-10 13:06:02 +010071 ABSL_DEPRECATED("Use .timestamp().us() instead")
Philipp Hanckeb81823a2023-01-04 15:17:42 +010072 int64_t timestamp_us() const { return timestamp_.us(); }
73 Timestamp timestamp() const { return timestamp_; }
74
Artem Titov0e61fdd2021-07-25 21:50:14 +020075 // Returns the static member variable `kType` of the implementing class.
hbos74e1a4f2016-09-15 23:33:01 -070076 virtual const char* type() const = 0;
Artem Titov0e61fdd2021-07-25 21:50:14 +020077 // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
hbos67c8bc42016-10-25 04:31:23 -070078 // of this class. This allows for iteration of members. For a given class,
Artem Titov0e61fdd2021-07-25 21:50:14 +020079 // `Members` always returns the same members in the same order.
hbos74e1a4f2016-09-15 23:33:01 -070080 std::vector<const RTCStatsMemberInterface*> Members() const;
hbos67c8bc42016-10-25 04:31:23 -070081 // Checks if the two stats objects are of the same type and have the same
hbos0583b282016-11-30 01:50:14 -080082 // member values. Timestamps are not compared. These operators are exposed for
83 // testing.
hbos67c8bc42016-10-25 04:31:23 -070084 bool operator==(const RTCStats& other) const;
85 bool operator!=(const RTCStats& other) const;
hbos74e1a4f2016-09-15 23:33:01 -070086
ehmaldonado35a872c2017-07-28 07:29:12 -070087 // Creates a JSON readable string representation of the stats
88 // object, listing all of its members (names and values).
89 std::string ToJson() const;
hbos74e1a4f2016-09-15 23:33:01 -070090
Artem Titov0e61fdd2021-07-25 21:50:14 +020091 // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
92 // object is of type `T`.
Yves Gerey665174f2018-06-19 15:03:05 +020093 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -070094 const T& cast_to() const {
95 RTC_DCHECK_EQ(type(), T::kType);
96 return static_cast<const T&>(*this);
97 }
98
99 protected:
Artem Titov0e61fdd2021-07-25 21:50:14 +0200100 // Gets a vector of all members of this `RTCStats` object, including members
101 // derived from parent classes. `additional_capacity` is how many more members
hbos74e1a4f2016-09-15 23:33:01 -0700102 // shall be reserved in the vector (so that subclasses can allocate a vector
103 // with room for both parent and child members without it having to resize).
104 virtual std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 15:03:05 +0200105 MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
hbos74e1a4f2016-09-15 23:33:01 -0700106
107 std::string const id_;
Philipp Hanckeb81823a2023-01-04 15:17:42 +0100108 Timestamp timestamp_;
hbos74e1a4f2016-09-15 23:33:01 -0700109};
110
Artem Titov0e61fdd2021-07-25 21:50:14 +0200111// All `RTCStats` classes should use these macros.
112// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
113// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
hbos74e1a4f2016-09-15 23:33:01 -0700114//
Artem Titov0e61fdd2021-07-25 21:50:14 +0200115// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
116// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
117// `MembersOfThisObjectAndAncestors`. The |...| argument is a list of addresses
hbosfc5e0502016-10-06 02:06:10 -0700118// to each member defined in the implementing class. The list must have at least
119// one member.
hbos74e1a4f2016-09-15 23:33:01 -0700120//
121// (Since class names need to be known to implement these methods this cannot be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200122// part of the base `RTCStats`. While these methods could be implemented using
hbos74e1a4f2016-09-15 23:33:01 -0700123// templates, that would only work for immediate subclasses. Subclasses of
124// subclasses also have to override these methods, resulting in boilerplate
Artem Titov0e61fdd2021-07-25 21:50:14 +0200125// code. Using a macro avoids this and works for any `RTCStats` class, including
hbos74e1a4f2016-09-15 23:33:01 -0700126// grandchildren.)
127//
128// Sample usage:
129//
130// rtcfoostats.h:
131// class RTCFooStats : public RTCStats {
132// public:
hbosfc5e0502016-10-06 02:06:10 -0700133// WEBRTC_RTCSTATS_DECL();
hbos74e1a4f2016-09-15 23:33:01 -0700134//
hbosfc5e0502016-10-06 02:06:10 -0700135// RTCFooStats(const std::string& id, int64_t timestamp_us);
hbos74e1a4f2016-09-15 23:33:01 -0700136//
137// RTCStatsMember<int32_t> foo;
138// RTCStatsMember<int32_t> bar;
139// };
140//
141// rtcfoostats.cc:
hbosfc5e0502016-10-06 02:06:10 -0700142// WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
143// &foo,
144// &bar);
hbos74e1a4f2016-09-15 23:33:01 -0700145//
hbosfc5e0502016-10-06 02:06:10 -0700146// RTCFooStats::RTCFooStats(const std::string& id, int64_t timestamp_us)
147// : RTCStats(id, timestamp_us),
148// foo("foo"),
149// bar("bar") {
150// }
151//
Yves Gerey665174f2018-06-19 15:03:05 +0200152#define WEBRTC_RTCSTATS_DECL() \
Yves Gerey665174f2018-06-19 15:03:05 +0200153 protected: \
154 std::vector<const webrtc::RTCStatsMemberInterface*> \
155 MembersOfThisObjectAndAncestors(size_t local_var_additional_capacity) \
156 const override; \
157 \
Nico Weber22f99252019-02-20 10:13:16 -0500158 public: \
159 static const char kType[]; \
160 \
161 std::unique_ptr<webrtc::RTCStats> copy() const override; \
162 const char* type() const override
hbosfc5e0502016-10-06 02:06:10 -0700163
164#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...) \
165 const char this_class::kType[] = type_str; \
166 \
167 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200168 return std::make_unique<this_class>(*this); \
hbosfc5e0502016-10-06 02:06:10 -0700169 } \
170 \
Yves Gerey665174f2018-06-19 15:03:05 +0200171 const char* this_class::type() const { return this_class::kType; } \
hbosfc5e0502016-10-06 02:06:10 -0700172 \
173 std::vector<const webrtc::RTCStatsMemberInterface*> \
174 this_class::MembersOfThisObjectAndAncestors( \
175 size_t local_var_additional_capacity) const { \
hbos74e1a4f2016-09-15 23:33:01 -0700176 const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
Yves Gerey665174f2018-06-19 15:03:05 +0200177 __VA_ARGS__}; \
hbos74e1a4f2016-09-15 23:33:01 -0700178 size_t local_var_members_count = \
179 sizeof(local_var_members) / sizeof(local_var_members[0]); \
Yves Gerey665174f2018-06-19 15:03:05 +0200180 std::vector<const webrtc::RTCStatsMemberInterface*> \
181 local_var_members_vec = parent_class::MembersOfThisObjectAndAncestors( \
hbos74e1a4f2016-09-15 23:33:01 -0700182 local_var_members_count + local_var_additional_capacity); \
183 RTC_DCHECK_GE( \
184 local_var_members_vec.capacity() - local_var_members_vec.size(), \
185 local_var_members_count + local_var_additional_capacity); \
186 local_var_members_vec.insert(local_var_members_vec.end(), \
187 &local_var_members[0], \
188 &local_var_members[local_var_members_count]); \
189 return local_var_members_vec; \
hbosfc5e0502016-10-06 02:06:10 -0700190 }
hbos74e1a4f2016-09-15 23:33:01 -0700191
Henrik Boström646fda02019-05-22 15:49:42 +0200192// A version of WEBRTC_RTCSTATS_IMPL() where "..." is omitted, used to avoid a
193// compile error on windows. This is used if the stats dictionary does not
194// declare any members of its own (but perhaps its parent dictionary does).
195#define WEBRTC_RTCSTATS_IMPL_NO_MEMBERS(this_class, parent_class, type_str) \
196 const char this_class::kType[] = type_str; \
197 \
198 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200199 return std::make_unique<this_class>(*this); \
Henrik Boström646fda02019-05-22 15:49:42 +0200200 } \
201 \
202 const char* this_class::type() const { return this_class::kType; } \
203 \
204 std::vector<const webrtc::RTCStatsMemberInterface*> \
205 this_class::MembersOfThisObjectAndAncestors( \
206 size_t local_var_additional_capacity) const { \
207 return parent_class::MembersOfThisObjectAndAncestors(0); \
208 }
209
Jakob Ivarsson22936222019-03-22 11:29:49 +0100210// Non-standard stats members can be exposed to the JavaScript API in Chrome
211// e.g. through origin trials. The group ID can be used by the blink layer to
212// determine if a stats member should be exposed or not. Multiple non-standard
213// stats members can share the same group ID so that they are exposed together.
214enum class NonStandardGroupId {
Jakob Ivarssonaa023e22019-03-27 10:17:31 +0100215 // Group ID used for testing purposes only.
216 kGroupIdForTesting,
Jakob Ivarsson22936222019-03-22 11:29:49 +0100217 // I2E:
218 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
219 kRtcAudioJitterBufferMaxPackets,
220 // I2E:
221 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
222 kRtcStatsRelativePacketArrivalDelay,
223};
224
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000225// Certain stat members should only be exposed to the JavaScript API in
226// certain circumstances as to avoid passive fingerprinting.
227enum class StatExposureCriteria : uint8_t {
228 // The stat should always be exposed. This is the default.
229 kAlways,
230 // The stat exposes hardware capabilities and thus should has limited exposure
231 // to JavaScript. The requirements for exposure are written in the spec at
232 // https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
233 kHardwareCapability,
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000234 // The stat is non-standard so user agents should filter these.
235 kNonStandard,
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000236};
237
Artem Titov0e61fdd2021-07-25 21:50:14 +0200238// Interface for `RTCStats` members, which have a name and a value of a type
239// defined in a subclass. Only the types listed in `Type` are supported, these
Artem Titovcfea2182021-08-10 01:22:31 +0200240// are implemented by `RTCStatsMember<T>`. The value of a member may be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200241// undefined, the value can only be read if `is_defined`.
hbos74e1a4f2016-09-15 23:33:01 -0700242class RTCStatsMemberInterface {
243 public:
244 // Member value types.
245 enum Type {
Yves Gerey665174f2018-06-19 15:03:05 +0200246 kBool, // bool
247 kInt32, // int32_t
248 kUint32, // uint32_t
249 kInt64, // int64_t
250 kUint64, // uint64_t
251 kDouble, // double
252 kString, // std::string
hbos74e1a4f2016-09-15 23:33:01 -0700253
Yves Gerey665174f2018-06-19 15:03:05 +0200254 kSequenceBool, // std::vector<bool>
255 kSequenceInt32, // std::vector<int32_t>
256 kSequenceUint32, // std::vector<uint32_t>
257 kSequenceInt64, // std::vector<int64_t>
258 kSequenceUint64, // std::vector<uint64_t>
259 kSequenceDouble, // std::vector<double>
260 kSequenceString, // std::vector<std::string>
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900261
262 kMapStringUint64, // std::map<std::string, uint64_t>
263 kMapStringDouble, // std::map<std::string, double>
hbos74e1a4f2016-09-15 23:33:01 -0700264 };
265
266 virtual ~RTCStatsMemberInterface() {}
267
268 const char* name() const { return name_; }
269 virtual Type type() const = 0;
270 virtual bool is_sequence() const = 0;
271 virtual bool is_string() const = 0;
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200272 virtual bool is_defined() const = 0;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700273 // Is this part of the stats spec? Used so that chromium can easily filter
274 // out anything unstandardized.
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000275 bool is_standardized() const {
276 return exposure_criteria() != StatExposureCriteria::kNonStandard;
277 }
Jakob Ivarsson22936222019-03-22 11:29:49 +0100278 // Non-standard stats members can have group IDs in order to be exposed in
279 // JavaScript through experiments. Standardized stats have no group IDs.
280 virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000281 // The conditions for exposing the statistic to JavaScript. Stats with
282 // criteria that is not kAlways has some restriction and should be filtered
283 // in accordance to the spec.
284 virtual StatExposureCriteria exposure_criteria() const {
285 return StatExposureCriteria::kAlways;
286 }
hbos67c8bc42016-10-25 04:31:23 -0700287 // Type and value comparator. The names are not compared. These operators are
288 // exposed for testing.
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900289 bool operator==(const RTCStatsMemberInterface& other) const {
290 return IsEqual(other);
291 }
hbos67c8bc42016-10-25 04:31:23 -0700292 bool operator!=(const RTCStatsMemberInterface& other) const {
293 return !(*this == other);
294 }
hbos74e1a4f2016-09-15 23:33:01 -0700295 virtual std::string ValueToString() const = 0;
ehmaldonado35a872c2017-07-28 07:29:12 -0700296 // This is the same as ValueToString except for kInt64 and kUint64 types,
297 // where the value is represented as a double instead of as an integer.
298 // Since JSON stores numbers as floating point numbers, very large integers
299 // cannot be accurately represented, so we prefer to display them as doubles
300 // instead.
301 virtual std::string ValueToJson() const = 0;
hbos74e1a4f2016-09-15 23:33:01 -0700302
Yves Gerey665174f2018-06-19 15:03:05 +0200303 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -0700304 const T& cast_to() const {
Mirko Bonadei054f1852019-11-04 16:31:08 +0100305 RTC_DCHECK_EQ(type(), T::StaticType());
hbos74e1a4f2016-09-15 23:33:01 -0700306 return static_cast<const T&>(*this);
307 }
308
309 protected:
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200310 explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
hbos74e1a4f2016-09-15 23:33:01 -0700311
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900312 virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
313
hbos74e1a4f2016-09-15 23:33:01 -0700314 const char* const name_;
hbos74e1a4f2016-09-15 23:33:01 -0700315};
316
Artem Titov0e61fdd2021-07-25 21:50:14 +0200317// Template implementation of `RTCStatsMemberInterface`.
Mirko Bonadei054f1852019-11-04 16:31:08 +0100318// The supported types are the ones described by
Artem Titovcfea2182021-08-10 01:22:31 +0200319// `RTCStatsMemberInterface::Type`.
Yves Gerey665174f2018-06-19 15:03:05 +0200320template <typename T>
Mirko Bonadei1e6aa1f2019-11-05 17:20:58 +0100321class RTCStatsMember : public RTCStatsMemberInterface {
hbos74e1a4f2016-09-15 23:33:01 -0700322 public:
hbos74e1a4f2016-09-15 23:33:01 -0700323 explicit RTCStatsMember(const char* name)
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200324 : RTCStatsMemberInterface(name), value_() {}
hbos74e1a4f2016-09-15 23:33:01 -0700325 RTCStatsMember(const char* name, const T& value)
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200326 : RTCStatsMemberInterface(name), value_(value) {}
hbos74e1a4f2016-09-15 23:33:01 -0700327 RTCStatsMember(const char* name, T&& value)
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200328 : RTCStatsMemberInterface(name), value_(std::move(value)) {}
329 explicit RTCStatsMember(const RTCStatsMember<T>& other)
330 : RTCStatsMemberInterface(other.name_), value_(other.value_) {}
331 explicit RTCStatsMember(RTCStatsMember<T>&& other)
332 : RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
hbos74e1a4f2016-09-15 23:33:01 -0700333
Mirko Bonadei054f1852019-11-04 16:31:08 +0100334 static Type StaticType();
335 Type type() const override { return StaticType(); }
hbos74e1a4f2016-09-15 23:33:01 -0700336 bool is_sequence() const override;
337 bool is_string() const override;
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200338 bool is_defined() const override { return value_.has_value(); }
hbos74e1a4f2016-09-15 23:33:01 -0700339 std::string ValueToString() const override;
ehmaldonado35a872c2017-07-28 07:29:12 -0700340 std::string ValueToJson() const override;
hbos74e1a4f2016-09-15 23:33:01 -0700341
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000342 template <typename U>
343 inline T ValueOrDefault(U default_value) const {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200344 return value_.value_or(default_value);
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000345 }
346
hbos74e1a4f2016-09-15 23:33:01 -0700347 // Assignment operators.
348 T& operator=(const T& value) {
349 value_ = value;
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200350 return value_.value();
hbos74e1a4f2016-09-15 23:33:01 -0700351 }
352 T& operator=(const T&& value) {
353 value_ = std::move(value);
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200354 return value_.value();
hbos74e1a4f2016-09-15 23:33:01 -0700355 }
hbos74e1a4f2016-09-15 23:33:01 -0700356
357 // Value getters.
358 T& operator*() {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200359 RTC_DCHECK(value_);
360 return *value_;
hbos74e1a4f2016-09-15 23:33:01 -0700361 }
362 const T& operator*() const {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200363 RTC_DCHECK(value_);
364 return *value_;
hbos74e1a4f2016-09-15 23:33:01 -0700365 }
366
367 // Value getters, arrow operator.
368 T* operator->() {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200369 RTC_DCHECK(value_);
370 return &(*value_);
hbos74e1a4f2016-09-15 23:33:01 -0700371 }
372 const T* operator->() const {
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200373 RTC_DCHECK(value_);
374 return &(*value_);
hbos74e1a4f2016-09-15 23:33:01 -0700375 }
376
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900377 protected:
378 bool IsEqual(const RTCStatsMemberInterface& other) const override {
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000379 if (type() != other.type() ||
380 is_standardized() != other.is_standardized() ||
381 exposure_criteria() != other.exposure_criteria())
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900382 return false;
383 const RTCStatsMember<T>& other_t =
384 static_cast<const RTCStatsMember<T>&>(other);
Byoungchan Lee8c4601b2022-09-23 13:59:42 +0900385 return value_ == other_t.value_;
386 }
387
hbos74e1a4f2016-09-15 23:33:01 -0700388 private:
Philipp Hancke8e7a1052022-10-13 13:14:01 +0200389 absl::optional<T> value_;
hbos74e1a4f2016-09-15 23:33:01 -0700390};
391
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900392namespace rtc_stats_internal {
393
394typedef std::map<std::string, uint64_t> MapStringUint64;
395typedef std::map<std::string, double> MapStringDouble;
396
397} // namespace rtc_stats_internal
398
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100399#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
400 template <> \
401 RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
402 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100403 RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100404 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100405 RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100406 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100407 RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100408 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100409 RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100410 extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100411 RTCStatsMember<T>
412
413WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
414WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
415WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
416WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
417WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
418WEBRTC_DECLARE_RTCSTATSMEMBER(double);
419WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
420WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
421WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
422WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
423WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
424WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
425WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
426WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900427WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
428WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
Mirko Bonadei054f1852019-11-04 16:31:08 +0100429
Evan Shrubsole6c733ee2022-10-12 15:11:14 +0000430// For stats with restricted exposure.
431template <typename T, StatExposureCriteria E>
432class RTCRestrictedStatsMember : public RTCStatsMember<T> {
433 public:
434 explicit RTCRestrictedStatsMember(const char* name)
435 : RTCStatsMember<T>(name) {}
436 RTCRestrictedStatsMember(const char* name, const T& value)
437 : RTCStatsMember<T>(name, value) {}
438 RTCRestrictedStatsMember(const char* name, T&& value)
439 : RTCStatsMember<T>(name, std::move(value)) {}
440 RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T, E>& other)
441 : RTCStatsMember<T>(other) {}
442 RTCRestrictedStatsMember(RTCRestrictedStatsMember<T, E>&& other)
443 : RTCStatsMember<T>(std::move(other)) {}
444
445 StatExposureCriteria exposure_criteria() const override { return E; }
446
447 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
448 T& operator=(const T&& value) {
449 return RTCStatsMember<T>::operator=(std::move(value));
450 }
451
452 private:
453 static_assert(E != StatExposureCriteria::kAlways,
454 "kAlways is the default exposure criteria. Use "
455 "RTCStatMember<T> instead.");
456};
457
458extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
459 RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
460extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
461 RTCRestrictedStatsMember<int32_t,
462 StatExposureCriteria::kHardwareCapability>;
463extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
464 RTCRestrictedStatsMember<uint32_t,
465 StatExposureCriteria::kHardwareCapability>;
466extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
467 RTCRestrictedStatsMember<int64_t,
468 StatExposureCriteria::kHardwareCapability>;
469extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
470 RTCRestrictedStatsMember<uint64_t,
471 StatExposureCriteria::kHardwareCapability>;
472extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
473 RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
474extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
475 RTCRestrictedStatsMember<std::string,
476 StatExposureCriteria::kHardwareCapability>;
477extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
478 RTCRestrictedStatsMember<std::vector<bool>,
479 StatExposureCriteria::kHardwareCapability>;
480extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
481 RTCRestrictedStatsMember<std::vector<int32_t>,
482 StatExposureCriteria::kHardwareCapability>;
483extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
484 RTCRestrictedStatsMember<std::vector<uint32_t>,
485 StatExposureCriteria::kHardwareCapability>;
486extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
487 RTCRestrictedStatsMember<std::vector<int64_t>,
488 StatExposureCriteria::kHardwareCapability>;
489extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
490 RTCRestrictedStatsMember<std::vector<uint64_t>,
491 StatExposureCriteria::kHardwareCapability>;
492extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
493 RTCRestrictedStatsMember<std::vector<double>,
494 StatExposureCriteria::kHardwareCapability>;
495extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
496 RTCRestrictedStatsMember<std::vector<std::string>,
497 StatExposureCriteria::kHardwareCapability>;
498extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
499 RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
500 StatExposureCriteria::kHardwareCapability>;
501extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
502 RTCRestrictedStatsMember<std::map<std::string, double>,
503 StatExposureCriteria::kHardwareCapability>;
504
Taylor Brandstettere2751742018-06-25 13:42:44 -0700505// Using inheritance just so that it's obvious from the member's declaration
506// whether it's standardized or not.
507template <typename T>
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000508class RTCNonStandardStatsMember
509 : public RTCRestrictedStatsMember<T, StatExposureCriteria::kNonStandard> {
Taylor Brandstettere2751742018-06-25 13:42:44 -0700510 public:
511 explicit RTCNonStandardStatsMember(const char* name)
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000512 : RTCRestrictedStatsBase(name) {}
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100513 RTCNonStandardStatsMember(const char* name,
514 std::initializer_list<NonStandardGroupId> group_ids)
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000515 : RTCRestrictedStatsBase(name), group_ids_(group_ids) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700516 RTCNonStandardStatsMember(const char* name, const T& value)
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000517 : RTCRestrictedStatsBase(name, value) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700518 RTCNonStandardStatsMember(const char* name, T&& value)
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000519 : RTCRestrictedStatsBase(name, std::move(value)) {}
520 RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
521 : RTCRestrictedStatsBase(other), group_ids_(other.group_ids_) {}
522 RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
523 : RTCRestrictedStatsBase(std::move(other)),
Mirko Bonadei759f1612019-11-13 11:18:31 +0100524 group_ids_(std::move(other.group_ids_)) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700525
Jakob Ivarsson22936222019-03-22 11:29:49 +0100526 std::vector<NonStandardGroupId> group_ids() const override {
527 return group_ids_;
528 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100529
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000530 T& operator=(const T& value) {
531 return RTCRestrictedStatsMember<
532 T, StatExposureCriteria::kNonStandard>::operator=(value);
533 }
Ruslan Burakov8af88962018-11-22 17:21:10 +0100534 T& operator=(const T&& value) {
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000535 return RTCRestrictedStatsMember<
536 T, StatExposureCriteria::kNonStandard>::operator=(std::move(value));
Ruslan Burakov8af88962018-11-22 17:21:10 +0100537 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100538
539 private:
Evan Shrubsole7ef0c1a2022-10-31 11:05:33 +0000540 using RTCRestrictedStatsBase =
541 RTCRestrictedStatsMember<T, StatExposureCriteria::kNonStandard>;
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100542 std::vector<NonStandardGroupId> group_ids_;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700543};
Mirko Bonadei759f1612019-11-13 11:18:31 +0100544
545extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
546 RTCNonStandardStatsMember<bool>;
547extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
548 RTCNonStandardStatsMember<int32_t>;
549extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
550 RTCNonStandardStatsMember<uint32_t>;
551extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
552 RTCNonStandardStatsMember<int64_t>;
553extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
554 RTCNonStandardStatsMember<uint64_t>;
555extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
556 RTCNonStandardStatsMember<double>;
557extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
558 RTCNonStandardStatsMember<std::string>;
559extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
560 RTCNonStandardStatsMember<std::vector<bool>>;
561extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
562 RTCNonStandardStatsMember<std::vector<int32_t>>;
563extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
564 RTCNonStandardStatsMember<std::vector<uint32_t>>;
565extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
566 RTCNonStandardStatsMember<std::vector<int64_t>>;
567extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
568 RTCNonStandardStatsMember<std::vector<uint64_t>>;
569extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
570 RTCNonStandardStatsMember<std::vector<double>>;
571extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
572 RTCNonStandardStatsMember<std::vector<std::string>>;
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900573extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
574 RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
575extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
576 RTCNonStandardStatsMember<std::map<std::string, double>>;
Mirko Bonadei759f1612019-11-13 11:18:31 +0100577
hbos74e1a4f2016-09-15 23:33:01 -0700578} // namespace webrtc
579
Steve Anton10542f22019-01-11 09:11:00 -0800580#endif // API_STATS_RTC_STATS_H_