xref: /aosp_15_r20/external/webrtc/api/stats/rtc_stats.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef API_STATS_RTC_STATS_H_
12*d9f75844SAndroid Build Coastguard Worker #define API_STATS_RTC_STATS_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <map>
18*d9f75844SAndroid Build Coastguard Worker #include <memory>
19*d9f75844SAndroid Build Coastguard Worker #include <string>
20*d9f75844SAndroid Build Coastguard Worker #include <utility>
21*d9f75844SAndroid Build Coastguard Worker #include <vector>
22*d9f75844SAndroid Build Coastguard Worker 
23*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export_template.h"
27*d9f75844SAndroid Build Coastguard Worker 
28*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
29*d9f75844SAndroid Build Coastguard Worker 
30*d9f75844SAndroid Build Coastguard Worker class RTCStatsMemberInterface;
31*d9f75844SAndroid Build Coastguard Worker 
32*d9f75844SAndroid Build Coastguard Worker // Abstract base class for RTCStats-derived dictionaries, see
33*d9f75844SAndroid Build Coastguard Worker // https://w3c.github.io/webrtc-stats/.
34*d9f75844SAndroid Build Coastguard Worker //
35*d9f75844SAndroid Build Coastguard Worker // All derived classes must have the following static variable defined:
36*d9f75844SAndroid Build Coastguard Worker //   static const char kType[];
37*d9f75844SAndroid Build Coastguard Worker // It is used as a unique class identifier and a string representation of the
38*d9f75844SAndroid Build Coastguard Worker // class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
39*d9f75844SAndroid Build Coastguard Worker // Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
40*d9f75844SAndroid Build Coastguard Worker // for details.
41*d9f75844SAndroid Build Coastguard Worker //
42*d9f75844SAndroid Build Coastguard Worker // Derived classes list their dictionary members, RTCStatsMember<T>, as public
43*d9f75844SAndroid Build Coastguard Worker // fields, allowing the following:
44*d9f75844SAndroid Build Coastguard Worker //
45*d9f75844SAndroid Build Coastguard Worker // RTCFooStats foo("fooId", GetCurrentTime());
46*d9f75844SAndroid Build Coastguard Worker // foo.bar = 42;
47*d9f75844SAndroid Build Coastguard Worker // foo.baz = std::vector<std::string>();
48*d9f75844SAndroid Build Coastguard Worker // foo.baz->push_back("hello world");
49*d9f75844SAndroid Build Coastguard Worker // uint32_t x = *foo.bar;
50*d9f75844SAndroid Build Coastguard Worker //
51*d9f75844SAndroid Build Coastguard Worker // Pointers to all the members are available with `Members`, allowing iteration:
52*d9f75844SAndroid Build Coastguard Worker //
53*d9f75844SAndroid Build Coastguard Worker // for (const RTCStatsMemberInterface* member : foo.Members()) {
54*d9f75844SAndroid Build Coastguard Worker //   printf("%s = %s\n", member->name(), member->ValueToString().c_str());
55*d9f75844SAndroid Build Coastguard Worker // }
56*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT RTCStats {
57*d9f75844SAndroid Build Coastguard Worker  public:
RTCStats(const std::string & id,int64_t timestamp_us)58*d9f75844SAndroid Build Coastguard Worker   RTCStats(const std::string& id, int64_t timestamp_us)
59*d9f75844SAndroid Build Coastguard Worker       : id_(id), timestamp_us_(timestamp_us) {}
RTCStats(std::string && id,int64_t timestamp_us)60*d9f75844SAndroid Build Coastguard Worker   RTCStats(std::string&& id, int64_t timestamp_us)
61*d9f75844SAndroid Build Coastguard Worker       : id_(std::move(id)), timestamp_us_(timestamp_us) {}
~RTCStats()62*d9f75844SAndroid Build Coastguard Worker   virtual ~RTCStats() {}
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker   virtual std::unique_ptr<RTCStats> copy() const = 0;
65*d9f75844SAndroid Build Coastguard Worker 
id()66*d9f75844SAndroid Build Coastguard Worker   const std::string& id() const { return id_; }
67*d9f75844SAndroid Build Coastguard Worker   // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
timestamp_us()68*d9f75844SAndroid Build Coastguard Worker   int64_t timestamp_us() const { return timestamp_us_; }
69*d9f75844SAndroid Build Coastguard Worker   // Returns the static member variable `kType` of the implementing class.
70*d9f75844SAndroid Build Coastguard Worker   virtual const char* type() const = 0;
71*d9f75844SAndroid Build Coastguard Worker   // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
72*d9f75844SAndroid Build Coastguard Worker   // of this class. This allows for iteration of members. For a given class,
73*d9f75844SAndroid Build Coastguard Worker   // `Members` always returns the same members in the same order.
74*d9f75844SAndroid Build Coastguard Worker   std::vector<const RTCStatsMemberInterface*> Members() const;
75*d9f75844SAndroid Build Coastguard Worker   // Checks if the two stats objects are of the same type and have the same
76*d9f75844SAndroid Build Coastguard Worker   // member values. Timestamps are not compared. These operators are exposed for
77*d9f75844SAndroid Build Coastguard Worker   // testing.
78*d9f75844SAndroid Build Coastguard Worker   bool operator==(const RTCStats& other) const;
79*d9f75844SAndroid Build Coastguard Worker   bool operator!=(const RTCStats& other) const;
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker   // Creates a JSON readable string representation of the stats
82*d9f75844SAndroid Build Coastguard Worker   // object, listing all of its members (names and values).
83*d9f75844SAndroid Build Coastguard Worker   std::string ToJson() const;
84*d9f75844SAndroid Build Coastguard Worker 
85*d9f75844SAndroid Build Coastguard Worker   // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
86*d9f75844SAndroid Build Coastguard Worker   // object is of type `T`.
87*d9f75844SAndroid Build Coastguard Worker   template <typename T>
cast_to()88*d9f75844SAndroid Build Coastguard Worker   const T& cast_to() const {
89*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_EQ(type(), T::kType);
90*d9f75844SAndroid Build Coastguard Worker     return static_cast<const T&>(*this);
91*d9f75844SAndroid Build Coastguard Worker   }
92*d9f75844SAndroid Build Coastguard Worker 
93*d9f75844SAndroid Build Coastguard Worker  protected:
94*d9f75844SAndroid Build Coastguard Worker   // Gets a vector of all members of this `RTCStats` object, including members
95*d9f75844SAndroid Build Coastguard Worker   // derived from parent classes. `additional_capacity` is how many more members
96*d9f75844SAndroid Build Coastguard Worker   // shall be reserved in the vector (so that subclasses can allocate a vector
97*d9f75844SAndroid Build Coastguard Worker   // with room for both parent and child members without it having to resize).
98*d9f75844SAndroid Build Coastguard Worker   virtual std::vector<const RTCStatsMemberInterface*>
99*d9f75844SAndroid Build Coastguard Worker   MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker   std::string const id_;
102*d9f75844SAndroid Build Coastguard Worker   int64_t timestamp_us_;
103*d9f75844SAndroid Build Coastguard Worker };
104*d9f75844SAndroid Build Coastguard Worker 
105*d9f75844SAndroid Build Coastguard Worker // All `RTCStats` classes should use these macros.
106*d9f75844SAndroid Build Coastguard Worker // `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
107*d9f75844SAndroid Build Coastguard Worker // `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
108*d9f75844SAndroid Build Coastguard Worker //
109*d9f75844SAndroid Build Coastguard Worker // These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
110*d9f75844SAndroid Build Coastguard Worker // overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
111*d9f75844SAndroid Build Coastguard Worker // `MembersOfThisObjectAndAncestors`. The |...| argument is a list of addresses
112*d9f75844SAndroid Build Coastguard Worker // to each member defined in the implementing class. The list must have at least
113*d9f75844SAndroid Build Coastguard Worker // one member.
114*d9f75844SAndroid Build Coastguard Worker //
115*d9f75844SAndroid Build Coastguard Worker // (Since class names need to be known to implement these methods this cannot be
116*d9f75844SAndroid Build Coastguard Worker // part of the base `RTCStats`. While these methods could be implemented using
117*d9f75844SAndroid Build Coastguard Worker // templates, that would only work for immediate subclasses. Subclasses of
118*d9f75844SAndroid Build Coastguard Worker // subclasses also have to override these methods, resulting in boilerplate
119*d9f75844SAndroid Build Coastguard Worker // code. Using a macro avoids this and works for any `RTCStats` class, including
120*d9f75844SAndroid Build Coastguard Worker // grandchildren.)
121*d9f75844SAndroid Build Coastguard Worker //
122*d9f75844SAndroid Build Coastguard Worker // Sample usage:
123*d9f75844SAndroid Build Coastguard Worker //
124*d9f75844SAndroid Build Coastguard Worker // rtcfoostats.h:
125*d9f75844SAndroid Build Coastguard Worker //   class RTCFooStats : public RTCStats {
126*d9f75844SAndroid Build Coastguard Worker //    public:
127*d9f75844SAndroid Build Coastguard Worker //     WEBRTC_RTCSTATS_DECL();
128*d9f75844SAndroid Build Coastguard Worker //
129*d9f75844SAndroid Build Coastguard Worker //     RTCFooStats(const std::string& id, int64_t timestamp_us);
130*d9f75844SAndroid Build Coastguard Worker //
131*d9f75844SAndroid Build Coastguard Worker //     RTCStatsMember<int32_t> foo;
132*d9f75844SAndroid Build Coastguard Worker //     RTCStatsMember<int32_t> bar;
133*d9f75844SAndroid Build Coastguard Worker //   };
134*d9f75844SAndroid Build Coastguard Worker //
135*d9f75844SAndroid Build Coastguard Worker // rtcfoostats.cc:
136*d9f75844SAndroid Build Coastguard Worker //   WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
137*d9f75844SAndroid Build Coastguard Worker //       &foo,
138*d9f75844SAndroid Build Coastguard Worker //       &bar);
139*d9f75844SAndroid Build Coastguard Worker //
140*d9f75844SAndroid Build Coastguard Worker //   RTCFooStats::RTCFooStats(const std::string& id, int64_t timestamp_us)
141*d9f75844SAndroid Build Coastguard Worker //       : RTCStats(id, timestamp_us),
142*d9f75844SAndroid Build Coastguard Worker //         foo("foo"),
143*d9f75844SAndroid Build Coastguard Worker //         bar("bar") {
144*d9f75844SAndroid Build Coastguard Worker //   }
145*d9f75844SAndroid Build Coastguard Worker //
146*d9f75844SAndroid Build Coastguard Worker #define WEBRTC_RTCSTATS_DECL()                                          \
147*d9f75844SAndroid Build Coastguard Worker  protected:                                                             \
148*d9f75844SAndroid Build Coastguard Worker   std::vector<const webrtc::RTCStatsMemberInterface*>                   \
149*d9f75844SAndroid Build Coastguard Worker   MembersOfThisObjectAndAncestors(size_t local_var_additional_capacity) \
150*d9f75844SAndroid Build Coastguard Worker       const override;                                                   \
151*d9f75844SAndroid Build Coastguard Worker                                                                         \
152*d9f75844SAndroid Build Coastguard Worker  public:                                                                \
153*d9f75844SAndroid Build Coastguard Worker   static const char kType[];                                            \
154*d9f75844SAndroid Build Coastguard Worker                                                                         \
155*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::RTCStats> copy() const override;              \
156*d9f75844SAndroid Build Coastguard Worker   const char* type() const override
157*d9f75844SAndroid Build Coastguard Worker 
158*d9f75844SAndroid Build Coastguard Worker #define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...)          \
159*d9f75844SAndroid Build Coastguard Worker   const char this_class::kType[] = type_str;                                   \
160*d9f75844SAndroid Build Coastguard Worker                                                                                \
161*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::RTCStats> this_class::copy() const {                 \
162*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<this_class>(*this);                                \
163*d9f75844SAndroid Build Coastguard Worker   }                                                                            \
164*d9f75844SAndroid Build Coastguard Worker                                                                                \
165*d9f75844SAndroid Build Coastguard Worker   const char* this_class::type() const { return this_class::kType; }           \
166*d9f75844SAndroid Build Coastguard Worker                                                                                \
167*d9f75844SAndroid Build Coastguard Worker   std::vector<const webrtc::RTCStatsMemberInterface*>                          \
168*d9f75844SAndroid Build Coastguard Worker   this_class::MembersOfThisObjectAndAncestors(                                 \
169*d9f75844SAndroid Build Coastguard Worker       size_t local_var_additional_capacity) const {                            \
170*d9f75844SAndroid Build Coastguard Worker     const webrtc::RTCStatsMemberInterface* local_var_members[] = {             \
171*d9f75844SAndroid Build Coastguard Worker         __VA_ARGS__};                                                          \
172*d9f75844SAndroid Build Coastguard Worker     size_t local_var_members_count =                                           \
173*d9f75844SAndroid Build Coastguard Worker         sizeof(local_var_members) / sizeof(local_var_members[0]);              \
174*d9f75844SAndroid Build Coastguard Worker     std::vector<const webrtc::RTCStatsMemberInterface*>                        \
175*d9f75844SAndroid Build Coastguard Worker         local_var_members_vec = parent_class::MembersOfThisObjectAndAncestors( \
176*d9f75844SAndroid Build Coastguard Worker             local_var_members_count + local_var_additional_capacity);          \
177*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_GE(                                                             \
178*d9f75844SAndroid Build Coastguard Worker         local_var_members_vec.capacity() - local_var_members_vec.size(),       \
179*d9f75844SAndroid Build Coastguard Worker         local_var_members_count + local_var_additional_capacity);              \
180*d9f75844SAndroid Build Coastguard Worker     local_var_members_vec.insert(local_var_members_vec.end(),                  \
181*d9f75844SAndroid Build Coastguard Worker                                  &local_var_members[0],                        \
182*d9f75844SAndroid Build Coastguard Worker                                  &local_var_members[local_var_members_count]); \
183*d9f75844SAndroid Build Coastguard Worker     return local_var_members_vec;                                              \
184*d9f75844SAndroid Build Coastguard Worker   }
185*d9f75844SAndroid Build Coastguard Worker 
186*d9f75844SAndroid Build Coastguard Worker // A version of WEBRTC_RTCSTATS_IMPL() where "..." is omitted, used to avoid a
187*d9f75844SAndroid Build Coastguard Worker // compile error on windows. This is used if the stats dictionary does not
188*d9f75844SAndroid Build Coastguard Worker // declare any members of its own (but perhaps its parent dictionary does).
189*d9f75844SAndroid Build Coastguard Worker #define WEBRTC_RTCSTATS_IMPL_NO_MEMBERS(this_class, parent_class, type_str) \
190*d9f75844SAndroid Build Coastguard Worker   const char this_class::kType[] = type_str;                                \
191*d9f75844SAndroid Build Coastguard Worker                                                                             \
192*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::RTCStats> this_class::copy() const {              \
193*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<this_class>(*this);                             \
194*d9f75844SAndroid Build Coastguard Worker   }                                                                         \
195*d9f75844SAndroid Build Coastguard Worker                                                                             \
196*d9f75844SAndroid Build Coastguard Worker   const char* this_class::type() const { return this_class::kType; }        \
197*d9f75844SAndroid Build Coastguard Worker                                                                             \
198*d9f75844SAndroid Build Coastguard Worker   std::vector<const webrtc::RTCStatsMemberInterface*>                       \
199*d9f75844SAndroid Build Coastguard Worker   this_class::MembersOfThisObjectAndAncestors(                              \
200*d9f75844SAndroid Build Coastguard Worker       size_t local_var_additional_capacity) const {                         \
201*d9f75844SAndroid Build Coastguard Worker     return parent_class::MembersOfThisObjectAndAncestors(0);                \
202*d9f75844SAndroid Build Coastguard Worker   }
203*d9f75844SAndroid Build Coastguard Worker 
204*d9f75844SAndroid Build Coastguard Worker // Non-standard stats members can be exposed to the JavaScript API in Chrome
205*d9f75844SAndroid Build Coastguard Worker // e.g. through origin trials. The group ID can be used by the blink layer to
206*d9f75844SAndroid Build Coastguard Worker // determine if a stats member should be exposed or not. Multiple non-standard
207*d9f75844SAndroid Build Coastguard Worker // stats members can share the same group ID so that they are exposed together.
208*d9f75844SAndroid Build Coastguard Worker enum class NonStandardGroupId {
209*d9f75844SAndroid Build Coastguard Worker   // Group ID used for testing purposes only.
210*d9f75844SAndroid Build Coastguard Worker   kGroupIdForTesting,
211*d9f75844SAndroid Build Coastguard Worker   // I2E:
212*d9f75844SAndroid Build Coastguard Worker   // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
213*d9f75844SAndroid Build Coastguard Worker   kRtcAudioJitterBufferMaxPackets,
214*d9f75844SAndroid Build Coastguard Worker   // I2E:
215*d9f75844SAndroid Build Coastguard Worker   // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
216*d9f75844SAndroid Build Coastguard Worker   kRtcStatsRelativePacketArrivalDelay,
217*d9f75844SAndroid Build Coastguard Worker };
218*d9f75844SAndroid Build Coastguard Worker 
219*d9f75844SAndroid Build Coastguard Worker // Certain stat members should only be exposed to the JavaScript API in
220*d9f75844SAndroid Build Coastguard Worker // certain circumstances as to avoid passive fingerprinting.
221*d9f75844SAndroid Build Coastguard Worker enum class StatExposureCriteria : uint8_t {
222*d9f75844SAndroid Build Coastguard Worker   // The stat should always be exposed. This is the default.
223*d9f75844SAndroid Build Coastguard Worker   kAlways,
224*d9f75844SAndroid Build Coastguard Worker   // The stat exposes hardware capabilities and thus should has limited exposure
225*d9f75844SAndroid Build Coastguard Worker   // to JavaScript. The requirements for exposure are written in the spec at
226*d9f75844SAndroid Build Coastguard Worker   // https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
227*d9f75844SAndroid Build Coastguard Worker   kHardwareCapability,
228*d9f75844SAndroid Build Coastguard Worker };
229*d9f75844SAndroid Build Coastguard Worker 
230*d9f75844SAndroid Build Coastguard Worker // Interface for `RTCStats` members, which have a name and a value of a type
231*d9f75844SAndroid Build Coastguard Worker // defined in a subclass. Only the types listed in `Type` are supported, these
232*d9f75844SAndroid Build Coastguard Worker // are implemented by `RTCStatsMember<T>`. The value of a member may be
233*d9f75844SAndroid Build Coastguard Worker // undefined, the value can only be read if `is_defined`.
234*d9f75844SAndroid Build Coastguard Worker class RTCStatsMemberInterface {
235*d9f75844SAndroid Build Coastguard Worker  public:
236*d9f75844SAndroid Build Coastguard Worker   // Member value types.
237*d9f75844SAndroid Build Coastguard Worker   enum Type {
238*d9f75844SAndroid Build Coastguard Worker     kBool,    // bool
239*d9f75844SAndroid Build Coastguard Worker     kInt32,   // int32_t
240*d9f75844SAndroid Build Coastguard Worker     kUint32,  // uint32_t
241*d9f75844SAndroid Build Coastguard Worker     kInt64,   // int64_t
242*d9f75844SAndroid Build Coastguard Worker     kUint64,  // uint64_t
243*d9f75844SAndroid Build Coastguard Worker     kDouble,  // double
244*d9f75844SAndroid Build Coastguard Worker     kString,  // std::string
245*d9f75844SAndroid Build Coastguard Worker 
246*d9f75844SAndroid Build Coastguard Worker     kSequenceBool,    // std::vector<bool>
247*d9f75844SAndroid Build Coastguard Worker     kSequenceInt32,   // std::vector<int32_t>
248*d9f75844SAndroid Build Coastguard Worker     kSequenceUint32,  // std::vector<uint32_t>
249*d9f75844SAndroid Build Coastguard Worker     kSequenceInt64,   // std::vector<int64_t>
250*d9f75844SAndroid Build Coastguard Worker     kSequenceUint64,  // std::vector<uint64_t>
251*d9f75844SAndroid Build Coastguard Worker     kSequenceDouble,  // std::vector<double>
252*d9f75844SAndroid Build Coastguard Worker     kSequenceString,  // std::vector<std::string>
253*d9f75844SAndroid Build Coastguard Worker 
254*d9f75844SAndroid Build Coastguard Worker     kMapStringUint64,  // std::map<std::string, uint64_t>
255*d9f75844SAndroid Build Coastguard Worker     kMapStringDouble,  // std::map<std::string, double>
256*d9f75844SAndroid Build Coastguard Worker   };
257*d9f75844SAndroid Build Coastguard Worker 
~RTCStatsMemberInterface()258*d9f75844SAndroid Build Coastguard Worker   virtual ~RTCStatsMemberInterface() {}
259*d9f75844SAndroid Build Coastguard Worker 
name()260*d9f75844SAndroid Build Coastguard Worker   const char* name() const { return name_; }
261*d9f75844SAndroid Build Coastguard Worker   virtual Type type() const = 0;
262*d9f75844SAndroid Build Coastguard Worker   virtual bool is_sequence() const = 0;
263*d9f75844SAndroid Build Coastguard Worker   virtual bool is_string() const = 0;
264*d9f75844SAndroid Build Coastguard Worker   virtual bool is_defined() const = 0;
265*d9f75844SAndroid Build Coastguard Worker   // Is this part of the stats spec? Used so that chromium can easily filter
266*d9f75844SAndroid Build Coastguard Worker   // out anything unstandardized.
267*d9f75844SAndroid Build Coastguard Worker   virtual bool is_standardized() const = 0;
268*d9f75844SAndroid Build Coastguard Worker   // Non-standard stats members can have group IDs in order to be exposed in
269*d9f75844SAndroid Build Coastguard Worker   // JavaScript through experiments. Standardized stats have no group IDs.
group_ids()270*d9f75844SAndroid Build Coastguard Worker   virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
271*d9f75844SAndroid Build Coastguard Worker   // The conditions for exposing the statistic to JavaScript. Stats with
272*d9f75844SAndroid Build Coastguard Worker   // criteria that is not kAlways has some restriction and should be filtered
273*d9f75844SAndroid Build Coastguard Worker   // in accordance to the spec.
exposure_criteria()274*d9f75844SAndroid Build Coastguard Worker   virtual StatExposureCriteria exposure_criteria() const {
275*d9f75844SAndroid Build Coastguard Worker     return StatExposureCriteria::kAlways;
276*d9f75844SAndroid Build Coastguard Worker   }
277*d9f75844SAndroid Build Coastguard Worker   // Type and value comparator. The names are not compared. These operators are
278*d9f75844SAndroid Build Coastguard Worker   // exposed for testing.
279*d9f75844SAndroid Build Coastguard Worker   bool operator==(const RTCStatsMemberInterface& other) const {
280*d9f75844SAndroid Build Coastguard Worker     return IsEqual(other);
281*d9f75844SAndroid Build Coastguard Worker   }
282*d9f75844SAndroid Build Coastguard Worker   bool operator!=(const RTCStatsMemberInterface& other) const {
283*d9f75844SAndroid Build Coastguard Worker     return !(*this == other);
284*d9f75844SAndroid Build Coastguard Worker   }
285*d9f75844SAndroid Build Coastguard Worker   virtual std::string ValueToString() const = 0;
286*d9f75844SAndroid Build Coastguard Worker   // This is the same as ValueToString except for kInt64 and kUint64 types,
287*d9f75844SAndroid Build Coastguard Worker   // where the value is represented as a double instead of as an integer.
288*d9f75844SAndroid Build Coastguard Worker   // Since JSON stores numbers as floating point numbers, very large integers
289*d9f75844SAndroid Build Coastguard Worker   // cannot be accurately represented, so we prefer to display them as doubles
290*d9f75844SAndroid Build Coastguard Worker   // instead.
291*d9f75844SAndroid Build Coastguard Worker   virtual std::string ValueToJson() const = 0;
292*d9f75844SAndroid Build Coastguard Worker 
293*d9f75844SAndroid Build Coastguard Worker   template <typename T>
cast_to()294*d9f75844SAndroid Build Coastguard Worker   const T& cast_to() const {
295*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_EQ(type(), T::StaticType());
296*d9f75844SAndroid Build Coastguard Worker     return static_cast<const T&>(*this);
297*d9f75844SAndroid Build Coastguard Worker   }
298*d9f75844SAndroid Build Coastguard Worker 
299*d9f75844SAndroid Build Coastguard Worker  protected:
RTCStatsMemberInterface(const char * name)300*d9f75844SAndroid Build Coastguard Worker   explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
301*d9f75844SAndroid Build Coastguard Worker 
302*d9f75844SAndroid Build Coastguard Worker   virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
303*d9f75844SAndroid Build Coastguard Worker 
304*d9f75844SAndroid Build Coastguard Worker   const char* const name_;
305*d9f75844SAndroid Build Coastguard Worker };
306*d9f75844SAndroid Build Coastguard Worker 
307*d9f75844SAndroid Build Coastguard Worker // Template implementation of `RTCStatsMemberInterface`.
308*d9f75844SAndroid Build Coastguard Worker // The supported types are the ones described by
309*d9f75844SAndroid Build Coastguard Worker // `RTCStatsMemberInterface::Type`.
310*d9f75844SAndroid Build Coastguard Worker template <typename T>
311*d9f75844SAndroid Build Coastguard Worker class RTCStatsMember : public RTCStatsMemberInterface {
312*d9f75844SAndroid Build Coastguard Worker  public:
RTCStatsMember(const char * name)313*d9f75844SAndroid Build Coastguard Worker   explicit RTCStatsMember(const char* name)
314*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMemberInterface(name), value_() {}
RTCStatsMember(const char * name,const T & value)315*d9f75844SAndroid Build Coastguard Worker   RTCStatsMember(const char* name, const T& value)
316*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMemberInterface(name), value_(value) {}
RTCStatsMember(const char * name,T && value)317*d9f75844SAndroid Build Coastguard Worker   RTCStatsMember(const char* name, T&& value)
318*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMemberInterface(name), value_(std::move(value)) {}
RTCStatsMember(const RTCStatsMember<T> & other)319*d9f75844SAndroid Build Coastguard Worker   explicit RTCStatsMember(const RTCStatsMember<T>& other)
320*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMemberInterface(other.name_), value_(other.value_) {}
RTCStatsMember(RTCStatsMember<T> && other)321*d9f75844SAndroid Build Coastguard Worker   explicit RTCStatsMember(RTCStatsMember<T>&& other)
322*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
323*d9f75844SAndroid Build Coastguard Worker 
324*d9f75844SAndroid Build Coastguard Worker   static Type StaticType();
type()325*d9f75844SAndroid Build Coastguard Worker   Type type() const override { return StaticType(); }
326*d9f75844SAndroid Build Coastguard Worker   bool is_sequence() const override;
327*d9f75844SAndroid Build Coastguard Worker   bool is_string() const override;
is_defined()328*d9f75844SAndroid Build Coastguard Worker   bool is_defined() const override { return value_.has_value(); }
is_standardized()329*d9f75844SAndroid Build Coastguard Worker   bool is_standardized() const override { return true; }
330*d9f75844SAndroid Build Coastguard Worker   std::string ValueToString() const override;
331*d9f75844SAndroid Build Coastguard Worker   std::string ValueToJson() const override;
332*d9f75844SAndroid Build Coastguard Worker 
333*d9f75844SAndroid Build Coastguard Worker   template <typename U>
ValueOrDefault(U default_value)334*d9f75844SAndroid Build Coastguard Worker   inline T ValueOrDefault(U default_value) const {
335*d9f75844SAndroid Build Coastguard Worker     return value_.value_or(default_value);
336*d9f75844SAndroid Build Coastguard Worker   }
337*d9f75844SAndroid Build Coastguard Worker 
338*d9f75844SAndroid Build Coastguard Worker   // Assignment operators.
339*d9f75844SAndroid Build Coastguard Worker   T& operator=(const T& value) {
340*d9f75844SAndroid Build Coastguard Worker     value_ = value;
341*d9f75844SAndroid Build Coastguard Worker     return value_.value();
342*d9f75844SAndroid Build Coastguard Worker   }
343*d9f75844SAndroid Build Coastguard Worker   T& operator=(const T&& value) {
344*d9f75844SAndroid Build Coastguard Worker     value_ = std::move(value);
345*d9f75844SAndroid Build Coastguard Worker     return value_.value();
346*d9f75844SAndroid Build Coastguard Worker   }
347*d9f75844SAndroid Build Coastguard Worker 
348*d9f75844SAndroid Build Coastguard Worker   // Value getters.
349*d9f75844SAndroid Build Coastguard Worker   T& operator*() {
350*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(value_);
351*d9f75844SAndroid Build Coastguard Worker     return *value_;
352*d9f75844SAndroid Build Coastguard Worker   }
353*d9f75844SAndroid Build Coastguard Worker   const T& operator*() const {
354*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(value_);
355*d9f75844SAndroid Build Coastguard Worker     return *value_;
356*d9f75844SAndroid Build Coastguard Worker   }
357*d9f75844SAndroid Build Coastguard Worker 
358*d9f75844SAndroid Build Coastguard Worker   // Value getters, arrow operator.
359*d9f75844SAndroid Build Coastguard Worker   T* operator->() {
360*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(value_);
361*d9f75844SAndroid Build Coastguard Worker     return &(*value_);
362*d9f75844SAndroid Build Coastguard Worker   }
363*d9f75844SAndroid Build Coastguard Worker   const T* operator->() const {
364*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(value_);
365*d9f75844SAndroid Build Coastguard Worker     return &(*value_);
366*d9f75844SAndroid Build Coastguard Worker   }
367*d9f75844SAndroid Build Coastguard Worker 
368*d9f75844SAndroid Build Coastguard Worker  protected:
IsEqual(const RTCStatsMemberInterface & other)369*d9f75844SAndroid Build Coastguard Worker   bool IsEqual(const RTCStatsMemberInterface& other) const override {
370*d9f75844SAndroid Build Coastguard Worker     if (type() != other.type() ||
371*d9f75844SAndroid Build Coastguard Worker         is_standardized() != other.is_standardized() ||
372*d9f75844SAndroid Build Coastguard Worker         exposure_criteria() != other.exposure_criteria())
373*d9f75844SAndroid Build Coastguard Worker       return false;
374*d9f75844SAndroid Build Coastguard Worker     const RTCStatsMember<T>& other_t =
375*d9f75844SAndroid Build Coastguard Worker         static_cast<const RTCStatsMember<T>&>(other);
376*d9f75844SAndroid Build Coastguard Worker     return value_ == other_t.value_;
377*d9f75844SAndroid Build Coastguard Worker   }
378*d9f75844SAndroid Build Coastguard Worker 
379*d9f75844SAndroid Build Coastguard Worker  private:
380*d9f75844SAndroid Build Coastguard Worker   absl::optional<T> value_;
381*d9f75844SAndroid Build Coastguard Worker };
382*d9f75844SAndroid Build Coastguard Worker 
383*d9f75844SAndroid Build Coastguard Worker namespace rtc_stats_internal {
384*d9f75844SAndroid Build Coastguard Worker 
385*d9f75844SAndroid Build Coastguard Worker typedef std::map<std::string, uint64_t> MapStringUint64;
386*d9f75844SAndroid Build Coastguard Worker typedef std::map<std::string, double> MapStringDouble;
387*d9f75844SAndroid Build Coastguard Worker 
388*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc_stats_internal
389*d9f75844SAndroid Build Coastguard Worker 
390*d9f75844SAndroid Build Coastguard Worker #define WEBRTC_DECLARE_RTCSTATSMEMBER(T)                                    \
391*d9f75844SAndroid Build Coastguard Worker   template <>                                                               \
392*d9f75844SAndroid Build Coastguard Worker   RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
393*d9f75844SAndroid Build Coastguard Worker   template <>                                                               \
394*d9f75844SAndroid Build Coastguard Worker   RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const;                   \
395*d9f75844SAndroid Build Coastguard Worker   template <>                                                               \
396*d9f75844SAndroid Build Coastguard Worker   RTC_EXPORT bool RTCStatsMember<T>::is_string() const;                     \
397*d9f75844SAndroid Build Coastguard Worker   template <>                                                               \
398*d9f75844SAndroid Build Coastguard Worker   RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const;          \
399*d9f75844SAndroid Build Coastguard Worker   template <>                                                               \
400*d9f75844SAndroid Build Coastguard Worker   RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const;            \
401*d9f75844SAndroid Build Coastguard Worker   extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)             \
402*d9f75844SAndroid Build Coastguard Worker       RTCStatsMember<T>
403*d9f75844SAndroid Build Coastguard Worker 
404*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
405*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
406*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
407*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
408*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
409*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(double);
410*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
411*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
412*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
413*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
414*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
415*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
416*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
417*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
418*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
419*d9f75844SAndroid Build Coastguard Worker WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
420*d9f75844SAndroid Build Coastguard Worker 
421*d9f75844SAndroid Build Coastguard Worker // For stats with restricted exposure.
422*d9f75844SAndroid Build Coastguard Worker template <typename T, StatExposureCriteria E>
423*d9f75844SAndroid Build Coastguard Worker class RTCRestrictedStatsMember : public RTCStatsMember<T> {
424*d9f75844SAndroid Build Coastguard Worker  public:
RTCRestrictedStatsMember(const char * name)425*d9f75844SAndroid Build Coastguard Worker   explicit RTCRestrictedStatsMember(const char* name)
426*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name) {}
RTCRestrictedStatsMember(const char * name,const T & value)427*d9f75844SAndroid Build Coastguard Worker   RTCRestrictedStatsMember(const char* name, const T& value)
428*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name, value) {}
RTCRestrictedStatsMember(const char * name,T && value)429*d9f75844SAndroid Build Coastguard Worker   RTCRestrictedStatsMember(const char* name, T&& value)
430*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name, std::move(value)) {}
RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T,E> & other)431*d9f75844SAndroid Build Coastguard Worker   RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T, E>& other)
432*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(other) {}
RTCRestrictedStatsMember(RTCRestrictedStatsMember<T,E> && other)433*d9f75844SAndroid Build Coastguard Worker   RTCRestrictedStatsMember(RTCRestrictedStatsMember<T, E>&& other)
434*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(std::move(other)) {}
435*d9f75844SAndroid Build Coastguard Worker 
exposure_criteria()436*d9f75844SAndroid Build Coastguard Worker   StatExposureCriteria exposure_criteria() const override { return E; }
437*d9f75844SAndroid Build Coastguard Worker 
438*d9f75844SAndroid Build Coastguard Worker   T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
439*d9f75844SAndroid Build Coastguard Worker   T& operator=(const T&& value) {
440*d9f75844SAndroid Build Coastguard Worker     return RTCStatsMember<T>::operator=(std::move(value));
441*d9f75844SAndroid Build Coastguard Worker   }
442*d9f75844SAndroid Build Coastguard Worker 
443*d9f75844SAndroid Build Coastguard Worker  private:
444*d9f75844SAndroid Build Coastguard Worker   static_assert(E != StatExposureCriteria::kAlways,
445*d9f75844SAndroid Build Coastguard Worker                 "kAlways is the default exposure criteria. Use "
446*d9f75844SAndroid Build Coastguard Worker                 "RTCStatMember<T> instead.");
447*d9f75844SAndroid Build Coastguard Worker };
448*d9f75844SAndroid Build Coastguard Worker 
449*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
450*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
451*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
452*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<int32_t,
453*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
454*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
455*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<uint32_t,
456*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
457*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
458*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<int64_t,
459*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
460*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
461*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<uint64_t,
462*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
463*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
464*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
465*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
466*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::string,
467*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
468*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
469*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<bool>,
470*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
471*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
472*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<int32_t>,
473*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
474*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
475*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<uint32_t>,
476*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
477*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
478*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<int64_t>,
479*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
480*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
481*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<uint64_t>,
482*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
483*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
484*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<double>,
485*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
486*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
487*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::vector<std::string>,
488*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
489*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
490*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
491*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
492*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
493*d9f75844SAndroid Build Coastguard Worker     RTCRestrictedStatsMember<std::map<std::string, double>,
494*d9f75844SAndroid Build Coastguard Worker                              StatExposureCriteria::kHardwareCapability>;
495*d9f75844SAndroid Build Coastguard Worker 
496*d9f75844SAndroid Build Coastguard Worker // Using inheritance just so that it's obvious from the member's declaration
497*d9f75844SAndroid Build Coastguard Worker // whether it's standardized or not.
498*d9f75844SAndroid Build Coastguard Worker template <typename T>
499*d9f75844SAndroid Build Coastguard Worker class RTCNonStandardStatsMember : public RTCStatsMember<T> {
500*d9f75844SAndroid Build Coastguard Worker  public:
RTCNonStandardStatsMember(const char * name)501*d9f75844SAndroid Build Coastguard Worker   explicit RTCNonStandardStatsMember(const char* name)
502*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name) {}
RTCNonStandardStatsMember(const char * name,std::initializer_list<NonStandardGroupId> group_ids)503*d9f75844SAndroid Build Coastguard Worker   RTCNonStandardStatsMember(const char* name,
504*d9f75844SAndroid Build Coastguard Worker                             std::initializer_list<NonStandardGroupId> group_ids)
505*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name), group_ids_(group_ids) {}
RTCNonStandardStatsMember(const char * name,const T & value)506*d9f75844SAndroid Build Coastguard Worker   RTCNonStandardStatsMember(const char* name, const T& value)
507*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name, value) {}
RTCNonStandardStatsMember(const char * name,T && value)508*d9f75844SAndroid Build Coastguard Worker   RTCNonStandardStatsMember(const char* name, T&& value)
509*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(name, std::move(value)) {}
RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T> & other)510*d9f75844SAndroid Build Coastguard Worker   explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
511*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(other), group_ids_(other.group_ids_) {}
RTCNonStandardStatsMember(RTCNonStandardStatsMember<T> && other)512*d9f75844SAndroid Build Coastguard Worker   explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
513*d9f75844SAndroid Build Coastguard Worker       : RTCStatsMember<T>(std::move(other)),
514*d9f75844SAndroid Build Coastguard Worker         group_ids_(std::move(other.group_ids_)) {}
515*d9f75844SAndroid Build Coastguard Worker 
is_standardized()516*d9f75844SAndroid Build Coastguard Worker   bool is_standardized() const override { return false; }
517*d9f75844SAndroid Build Coastguard Worker 
group_ids()518*d9f75844SAndroid Build Coastguard Worker   std::vector<NonStandardGroupId> group_ids() const override {
519*d9f75844SAndroid Build Coastguard Worker     return group_ids_;
520*d9f75844SAndroid Build Coastguard Worker   }
521*d9f75844SAndroid Build Coastguard Worker 
522*d9f75844SAndroid Build Coastguard Worker   T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
523*d9f75844SAndroid Build Coastguard Worker   T& operator=(const T&& value) {
524*d9f75844SAndroid Build Coastguard Worker     return RTCStatsMember<T>::operator=(std::move(value));
525*d9f75844SAndroid Build Coastguard Worker   }
526*d9f75844SAndroid Build Coastguard Worker 
527*d9f75844SAndroid Build Coastguard Worker  private:
528*d9f75844SAndroid Build Coastguard Worker   std::vector<NonStandardGroupId> group_ids_;
529*d9f75844SAndroid Build Coastguard Worker };
530*d9f75844SAndroid Build Coastguard Worker 
531*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
532*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<bool>;
533*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
534*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<int32_t>;
535*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
536*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<uint32_t>;
537*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
538*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<int64_t>;
539*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
540*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<uint64_t>;
541*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
542*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<double>;
543*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
544*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::string>;
545*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
546*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<bool>>;
547*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
548*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<int32_t>>;
549*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
550*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<uint32_t>>;
551*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
552*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<int64_t>>;
553*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
554*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<uint64_t>>;
555*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
556*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<double>>;
557*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
558*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::vector<std::string>>;
559*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
560*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
561*d9f75844SAndroid Build Coastguard Worker extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
562*d9f75844SAndroid Build Coastguard Worker     RTCNonStandardStatsMember<std::map<std::string, double>>;
563*d9f75844SAndroid Build Coastguard Worker 
564*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
565*d9f75844SAndroid Build Coastguard Worker 
566*d9f75844SAndroid Build Coastguard Worker #endif  // API_STATS_RTC_STATS_H_
567