diff --git a/api/stats/rtcstats.h b/api/stats/rtcstats.h index 1ca7b2c529..1705f6ab58 100644 --- a/api/stats/rtcstats.h +++ b/api/stats/rtcstats.h @@ -211,6 +211,9 @@ class RTCStatsMemberInterface { virtual bool is_sequence() const = 0; virtual bool is_string() const = 0; bool is_defined() const { return is_defined_; } + // Is this part of the stats spec? Used so that chromium can easily filter + // out anything unstandardized. + virtual bool is_standardized() const = 0; // Type and value comparator. The names are not compared. These operators are // exposed for testing. virtual bool operator==(const RTCStatsMemberInterface& other) const = 0; @@ -249,11 +252,12 @@ class RTCStatsMember : public RTCStatsMemberInterface { static const Type kType; explicit RTCStatsMember(const char* name) - : RTCStatsMemberInterface(name, false), value_() {} + : RTCStatsMemberInterface(name, /*is_defined=*/false), value_() {} RTCStatsMember(const char* name, const T& value) - : RTCStatsMemberInterface(name, true), value_(value) {} + : RTCStatsMemberInterface(name, /*is_defined=*/true), value_(value) {} RTCStatsMember(const char* name, T&& value) - : RTCStatsMemberInterface(name, true), value_(std::move(value)) {} + : RTCStatsMemberInterface(name, /*is_defined=*/true), + value_(std::move(value)) {} explicit RTCStatsMember(const RTCStatsMember& other) : RTCStatsMemberInterface(other.name_, other.is_defined_), value_(other.value_) {} @@ -264,8 +268,9 @@ class RTCStatsMember : public RTCStatsMemberInterface { Type type() const override { return kType; } bool is_sequence() const override; bool is_string() const override; + bool is_standardized() const override { return true; } bool operator==(const RTCStatsMemberInterface& other) const override { - if (type() != other.type()) + if (type() != other.type() || is_standardized() != other.is_standardized()) return false; const RTCStatsMember& other_t = static_cast&>(other); @@ -291,7 +296,10 @@ class RTCStatsMember : public RTCStatsMemberInterface { } T& operator=(const RTCStatsMember& other) { RTC_DCHECK(other.is_defined_); - value_ = other.is_defined_; + // Shouldn't be attempting to assign an RTCNonStandardStatsMember to an + // RTCStatsMember or vice versa. + RTC_DCHECK(is_standardized() == other.is_standardized()); + value_ = other.value_; is_defined_ = true; return value_; } @@ -320,6 +328,26 @@ class RTCStatsMember : public RTCStatsMemberInterface { T value_; }; +// Same as above, but "is_standardized" returns false. +// +// Using inheritance just so that it's obvious from the member's declaration +// whether it's standardized or not. +template +class RTCNonStandardStatsMember : public RTCStatsMember { + public: + explicit RTCNonStandardStatsMember(const char* name) + : RTCStatsMember(name) {} + RTCNonStandardStatsMember(const char* name, const T& value) + : RTCStatsMember(name, value) {} + RTCNonStandardStatsMember(const char* name, T&& value) + : RTCStatsMember(name, std::move(value)) {} + explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember& other) + : RTCStatsMember(other) {} + explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember&& other) + : RTCStatsMember(std::move(other)) {} + + bool is_standardized() const override { return false; } +}; } // namespace webrtc #endif // API_STATS_RTCSTATS_H_ diff --git a/stats/rtcstats_unittest.cc b/stats/rtcstats_unittest.cc index a3f005d4e6..de3e18c4e0 100644 --- a/stats/rtcstats_unittest.cc +++ b/stats/rtcstats_unittest.cc @@ -330,6 +330,13 @@ TEST(RTCStatsTest, RTCStatsPrintsValidJson) { std::cout << stats.ToJson() << std::endl; } +TEST(RTCStatsTest, IsStandardized) { + RTCStatsMember standardized("standardized"); + RTCNonStandardStatsMember unstandardized("unstandardized"); + EXPECT_TRUE(standardized.is_standardized()); + EXPECT_FALSE(unstandardized.is_standardized()); +} + // Death tests. // Disabled on Android because death tests misbehave on Android, see // base/test/gtest_util.h.