Add exposure criteria to WebRTC stat members.
Recent WebRTC stats spec changes have added restrictions on what stats are available to JavaScript. This is done to reduce that fingerprinting surface of WebRTC getStats. For example, stats exposing hardware capabilities have requirements that must be met by the browser. See [1] for more details. This CL adds the types and the enumerations. Stats with these restrictions should not be added until Chromium has implemented filtering based on the stat type. [1] https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities Bug: webrtc:14546 Change-Id: I6dae5d4921c7a2bc828a4fc8f7d68e0c59f3be82 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/279043 Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38381}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
036b3fdea2
commit
6c733eed8e
@ -215,6 +215,17 @@ enum class NonStandardGroupId {
|
||||
kRtcStatsRelativePacketArrivalDelay,
|
||||
};
|
||||
|
||||
// Certain stat members should only be exposed to the JavaScript API in
|
||||
// certain circumstances as to avoid passive fingerprinting.
|
||||
enum class StatExposureCriteria : uint8_t {
|
||||
// The stat should always be exposed. This is the default.
|
||||
kAlways,
|
||||
// The stat exposes hardware capabilities and thus should has limited exposure
|
||||
// to JavaScript. The requirements for exposure are written in the spec at
|
||||
// https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
|
||||
kHardwareCapability,
|
||||
};
|
||||
|
||||
// Interface for `RTCStats` members, which have a name and a value of a type
|
||||
// defined in a subclass. Only the types listed in `Type` are supported, these
|
||||
// are implemented by `RTCStatsMember<T>`. The value of a member may be
|
||||
@ -256,6 +267,12 @@ class RTCStatsMemberInterface {
|
||||
// Non-standard stats members can have group IDs in order to be exposed in
|
||||
// JavaScript through experiments. Standardized stats have no group IDs.
|
||||
virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
|
||||
// The conditions for exposing the statistic to JavaScript. Stats with
|
||||
// criteria that is not kAlways has some restriction and should be filtered
|
||||
// in accordance to the spec.
|
||||
virtual StatExposureCriteria exposure_criteria() const {
|
||||
return StatExposureCriteria::kAlways;
|
||||
}
|
||||
// Type and value comparator. The names are not compared. These operators are
|
||||
// exposed for testing.
|
||||
bool operator==(const RTCStatsMemberInterface& other) const {
|
||||
@ -295,16 +312,21 @@ template <typename T>
|
||||
class RTCStatsMember : public RTCStatsMemberInterface {
|
||||
public:
|
||||
explicit RTCStatsMember(const char* name)
|
||||
: RTCStatsMemberInterface(name, /*is_defined=*/false), value_() {}
|
||||
: RTCStatsMemberInterface(name,
|
||||
/*is_defined=*/false),
|
||||
value_() {}
|
||||
RTCStatsMember(const char* name, const T& value)
|
||||
: RTCStatsMemberInterface(name, /*is_defined=*/true), value_(value) {}
|
||||
: RTCStatsMemberInterface(name,
|
||||
/*is_defined=*/true),
|
||||
value_(value) {}
|
||||
RTCStatsMember(const char* name, T&& value)
|
||||
: RTCStatsMemberInterface(name, /*is_defined=*/true),
|
||||
: RTCStatsMemberInterface(name,
|
||||
/*is_defined=*/true),
|
||||
value_(std::move(value)) {}
|
||||
explicit RTCStatsMember(const RTCStatsMember<T>& other)
|
||||
RTCStatsMember(const RTCStatsMember<T>& other)
|
||||
: RTCStatsMemberInterface(other.name_, other.is_defined_),
|
||||
value_(other.value_) {}
|
||||
explicit RTCStatsMember(RTCStatsMember<T>&& other)
|
||||
RTCStatsMember(RTCStatsMember<T>&& other)
|
||||
: RTCStatsMemberInterface(other.name_, other.is_defined_),
|
||||
value_(std::move(other.value_)) {}
|
||||
|
||||
@ -358,7 +380,9 @@ class RTCStatsMember : public RTCStatsMemberInterface {
|
||||
|
||||
protected:
|
||||
bool IsEqual(const RTCStatsMemberInterface& other) const override {
|
||||
if (type() != other.type() || is_standardized() != other.is_standardized())
|
||||
if (type() != other.type() ||
|
||||
is_standardized() != other.is_standardized() ||
|
||||
exposure_criteria() != other.exposure_criteria())
|
||||
return false;
|
||||
const RTCStatsMember<T>& other_t =
|
||||
static_cast<const RTCStatsMember<T>&>(other);
|
||||
@ -411,6 +435,81 @@ WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
|
||||
WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
|
||||
|
||||
// For stats with restricted exposure.
|
||||
template <typename T, StatExposureCriteria E>
|
||||
class RTCRestrictedStatsMember : public RTCStatsMember<T> {
|
||||
public:
|
||||
explicit RTCRestrictedStatsMember(const char* name)
|
||||
: RTCStatsMember<T>(name) {}
|
||||
RTCRestrictedStatsMember(const char* name, const T& value)
|
||||
: RTCStatsMember<T>(name, value) {}
|
||||
RTCRestrictedStatsMember(const char* name, T&& value)
|
||||
: RTCStatsMember<T>(name, std::move(value)) {}
|
||||
RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T, E>& other)
|
||||
: RTCStatsMember<T>(other) {}
|
||||
RTCRestrictedStatsMember(RTCRestrictedStatsMember<T, E>&& other)
|
||||
: RTCStatsMember<T>(std::move(other)) {}
|
||||
|
||||
StatExposureCriteria exposure_criteria() const override { return E; }
|
||||
|
||||
T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
|
||||
T& operator=(const T&& value) {
|
||||
return RTCStatsMember<T>::operator=(std::move(value));
|
||||
}
|
||||
|
||||
private:
|
||||
static_assert(E != StatExposureCriteria::kAlways,
|
||||
"kAlways is the default exposure criteria. Use "
|
||||
"RTCStatMember<T> instead.");
|
||||
};
|
||||
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<int32_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<uint32_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<int64_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<uint64_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::string,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<bool>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<int32_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<uint32_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<int64_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<uint64_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<double>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<std::string>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::map<std::string, double>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
|
||||
// Using inheritance just so that it's obvious from the member's declaration
|
||||
// whether it's standardized or not.
|
||||
template <typename T>
|
||||
|
||||
@ -289,6 +289,54 @@ WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble,
|
||||
MapToString(value_),
|
||||
MapToStringAsDouble(value_));
|
||||
|
||||
// Restricted members that expose hardware capabilites.
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<int32_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<uint32_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<int64_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<uint64_t,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::string,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<bool>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<int32_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<uint32_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<int64_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<uint64_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<double>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::vector<std::string>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
|
||||
RTCRestrictedStatsMember<std::map<std::string, double>,
|
||||
StatExposureCriteria::kHardwareCapability>;
|
||||
|
||||
template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
|
||||
RTCNonStandardStatsMember<bool>;
|
||||
template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT)
|
||||
|
||||
@ -503,6 +503,20 @@ TEST(RTCStatsTest, ValueToString) {
|
||||
EXPECT_EQ("{bar:0.25,foo:0.5}", stats.m_map_string_double.ValueToString());
|
||||
}
|
||||
|
||||
TEST(RTCStatsTest, RestrictedStatsTest) {
|
||||
RTCStatsMember<bool> unrestricted("unrestricted");
|
||||
EXPECT_EQ(unrestricted.exposure_criteria(), StatExposureCriteria::kAlways);
|
||||
RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>
|
||||
restricted("restricted");
|
||||
EXPECT_EQ(restricted.exposure_criteria(),
|
||||
StatExposureCriteria::kHardwareCapability);
|
||||
|
||||
unrestricted = true;
|
||||
restricted = true;
|
||||
EXPECT_NE(unrestricted, restricted)
|
||||
<< "These can not be equal as they have different exposure criteria.";
|
||||
}
|
||||
|
||||
TEST(RTCStatsTest, NonStandardGroupId) {
|
||||
auto group_id = NonStandardGroupId::kGroupIdForTesting;
|
||||
RTCNonStandardStatsMember<int32_t> with_group_id("stat", {group_id});
|
||||
|
||||
Reference in New Issue
Block a user