Adding "is_standardized" flag to RTCStatsMember.

This will allow us to add unstandardized stats for the benefit of
native applications, and easily filter them out in chromium (without
having to maintain a whitelist that lists out every member
individually).

Unstandardized stats are declared as "RTCNonStandardStatsMember",
to make it clear in the declaration (in rtcstats_objects.h) whether
something is standardized or not.

Bug: webrtc:9410
Change-Id: I7c9804c261b7af96738e94dadeaa4b8a56b9ef2c
Reviewed-on: https://webrtc-review.googlesource.com/83743
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23760}
This commit is contained in:
Taylor Brandstetter
2018-06-25 13:42:44 -07:00
committed by Commit Bot
parent d059f2c446
commit e275174b1b
2 changed files with 40 additions and 5 deletions

View File

@ -211,6 +211,9 @@ class RTCStatsMemberInterface {
virtual bool is_sequence() const = 0; virtual bool is_sequence() const = 0;
virtual bool is_string() const = 0; virtual bool is_string() const = 0;
bool is_defined() const { return is_defined_; } 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 // Type and value comparator. The names are not compared. These operators are
// exposed for testing. // exposed for testing.
virtual bool operator==(const RTCStatsMemberInterface& other) const = 0; virtual bool operator==(const RTCStatsMemberInterface& other) const = 0;
@ -249,11 +252,12 @@ class RTCStatsMember : public RTCStatsMemberInterface {
static const Type kType; static const Type kType;
explicit RTCStatsMember(const char* name) explicit RTCStatsMember(const char* name)
: RTCStatsMemberInterface(name, false), value_() {} : RTCStatsMemberInterface(name, /*is_defined=*/false), value_() {}
RTCStatsMember(const char* name, const T& 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) 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<T>& other) explicit RTCStatsMember(const RTCStatsMember<T>& other)
: RTCStatsMemberInterface(other.name_, other.is_defined_), : RTCStatsMemberInterface(other.name_, other.is_defined_),
value_(other.value_) {} value_(other.value_) {}
@ -264,8 +268,9 @@ class RTCStatsMember : public RTCStatsMemberInterface {
Type type() const override { return kType; } Type type() const override { return kType; }
bool is_sequence() const override; bool is_sequence() const override;
bool is_string() const override; bool is_string() const override;
bool is_standardized() const override { return true; }
bool operator==(const RTCStatsMemberInterface& other) const override { bool operator==(const RTCStatsMemberInterface& other) const override {
if (type() != other.type()) if (type() != other.type() || is_standardized() != other.is_standardized())
return false; return false;
const RTCStatsMember<T>& other_t = const RTCStatsMember<T>& other_t =
static_cast<const RTCStatsMember<T>&>(other); static_cast<const RTCStatsMember<T>&>(other);
@ -291,7 +296,10 @@ class RTCStatsMember : public RTCStatsMemberInterface {
} }
T& operator=(const RTCStatsMember<T>& other) { T& operator=(const RTCStatsMember<T>& other) {
RTC_DCHECK(other.is_defined_); 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; is_defined_ = true;
return value_; return value_;
} }
@ -320,6 +328,26 @@ class RTCStatsMember : public RTCStatsMemberInterface {
T value_; 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 <typename T>
class RTCNonStandardStatsMember : public RTCStatsMember<T> {
public:
explicit RTCNonStandardStatsMember(const char* name)
: RTCStatsMember<T>(name) {}
RTCNonStandardStatsMember(const char* name, const T& value)
: RTCStatsMember<T>(name, value) {}
RTCNonStandardStatsMember(const char* name, T&& value)
: RTCStatsMember<T>(name, std::move(value)) {}
explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
: RTCStatsMember<T>(other) {}
explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
: RTCStatsMember<T>(std::move(other)) {}
bool is_standardized() const override { return false; }
};
} // namespace webrtc } // namespace webrtc
#endif // API_STATS_RTCSTATS_H_ #endif // API_STATS_RTCSTATS_H_

View File

@ -330,6 +330,13 @@ TEST(RTCStatsTest, RTCStatsPrintsValidJson) {
std::cout << stats.ToJson() << std::endl; std::cout << stats.ToJson() << std::endl;
} }
TEST(RTCStatsTest, IsStandardized) {
RTCStatsMember<int32_t> standardized("standardized");
RTCNonStandardStatsMember<int32_t> unstandardized("unstandardized");
EXPECT_TRUE(standardized.is_standardized());
EXPECT_FALSE(unstandardized.is_standardized());
}
// Death tests. // Death tests.
// Disabled on Android because death tests misbehave on Android, see // Disabled on Android because death tests misbehave on Android, see
// base/test/gtest_util.h. // base/test/gtest_util.h.