From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- third_party/libwebrtc/stats/BUILD.gn | 76 ++ third_party/libwebrtc/stats/DEPS | 3 + third_party/libwebrtc/stats/OWNERS | 2 + third_party/libwebrtc/stats/g3doc/stats.md | 18 + third_party/libwebrtc/stats/rtc_stats.cc | 374 +++++++++ third_party/libwebrtc/stats/rtc_stats_report.cc | 140 ++++ .../libwebrtc/stats/rtc_stats_report_unittest.cc | 172 ++++ third_party/libwebrtc/stats/rtc_stats_unittest.cc | 549 ++++++++++++ third_party/libwebrtc/stats/rtcstats_objects.cc | 925 +++++++++++++++++++++ third_party/libwebrtc/stats/test/rtc_test_stats.cc | 80 ++ third_party/libwebrtc/stats/test/rtc_test_stats.h | 54 ++ 11 files changed, 2393 insertions(+) create mode 100644 third_party/libwebrtc/stats/BUILD.gn create mode 100644 third_party/libwebrtc/stats/DEPS create mode 100644 third_party/libwebrtc/stats/OWNERS create mode 100644 third_party/libwebrtc/stats/g3doc/stats.md create mode 100644 third_party/libwebrtc/stats/rtc_stats.cc create mode 100644 third_party/libwebrtc/stats/rtc_stats_report.cc create mode 100644 third_party/libwebrtc/stats/rtc_stats_report_unittest.cc create mode 100644 third_party/libwebrtc/stats/rtc_stats_unittest.cc create mode 100644 third_party/libwebrtc/stats/rtcstats_objects.cc create mode 100644 third_party/libwebrtc/stats/test/rtc_test_stats.cc create mode 100644 third_party/libwebrtc/stats/test/rtc_test_stats.h (limited to 'third_party/libwebrtc/stats') diff --git a/third_party/libwebrtc/stats/BUILD.gn b/third_party/libwebrtc/stats/BUILD.gn new file mode 100644 index 0000000000..b2a0c20473 --- /dev/null +++ b/third_party/libwebrtc/stats/BUILD.gn @@ -0,0 +1,76 @@ +# Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("../webrtc.gni") + +group("stats") { + deps = [ ":rtc_stats" ] +} + +rtc_library("rtc_stats") { + visibility = [ "*" ] + cflags = [] + sources = [ + "rtc_stats.cc", + "rtc_stats_report.cc", + "rtcstats_objects.cc", + ] + + deps = [ + "../api:rtc_stats_api", + "../rtc_base:checks", + "../rtc_base:macromagic", + "../rtc_base:stringutils", + ] +} + +rtc_library("rtc_stats_test_utils") { + visibility = [ "*" ] + cflags = [] + sources = [ + "test/rtc_test_stats.cc", + "test/rtc_test_stats.h", + ] + + deps = [ + ":rtc_stats", + "../api:rtc_stats_api", + "../rtc_base:checks", + "../rtc_base/system:rtc_export", + ] +} + +if (rtc_include_tests && !build_with_chromium) { + rtc_test("rtc_stats_unittests") { + testonly = true + sources = [ + "rtc_stats_report_unittest.cc", + "rtc_stats_unittest.cc", + ] + + deps = [ + ":rtc_stats", + ":rtc_stats_test_utils", + "../api:rtc_stats_api", + "../rtc_base:checks", + "../rtc_base:gunit_helpers", + "../rtc_base:rtc_json", + "../test:test_main", + "../test:test_support", + ] + + if (is_android) { + use_default_launcher = false + deps += [ + "//build/android/gtest_apk:native_test_instrumentation_test_runner_java", + "//testing/android/native_test:native_test_java", + "//testing/android/native_test:native_test_support", + ] + } + } +} diff --git a/third_party/libwebrtc/stats/DEPS b/third_party/libwebrtc/stats/DEPS new file mode 100644 index 0000000000..c3a5b96fc4 --- /dev/null +++ b/third_party/libwebrtc/stats/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+media", +] diff --git a/third_party/libwebrtc/stats/OWNERS b/third_party/libwebrtc/stats/OWNERS new file mode 100644 index 0000000000..7e98070d5d --- /dev/null +++ b/third_party/libwebrtc/stats/OWNERS @@ -0,0 +1,2 @@ +hbos@webrtc.org +hta@webrtc.org diff --git a/third_party/libwebrtc/stats/g3doc/stats.md b/third_party/libwebrtc/stats/g3doc/stats.md new file mode 100644 index 0000000000..25127dc36e --- /dev/null +++ b/third_party/libwebrtc/stats/g3doc/stats.md @@ -0,0 +1,18 @@ + + + +# getStats in WebRTC + +The WebRTC getStats API is specified in + https://w3c.github.io/webrtc-stats/ +and allows querying information about the current state of a RTCPeerConnection +API and some of its member objects. + +## Adding new statistics to Chrome + +When adding a new standardized `RTCStatsMember` it is necessary to add +it to the Chrome allowlist + chrome/test/data/webrtc/peerconnection_getstats.js +before landing the WebRTC change. This mechanism prevents the accidential +addition and exposure of non-standard attributes and is not required for +`RTCNonStandardStatsMember` which is not exposed to the web API. \ No newline at end of file diff --git a/third_party/libwebrtc/stats/rtc_stats.cc b/third_party/libwebrtc/stats/rtc_stats.cc new file mode 100644 index 0000000000..421d9690d7 --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats.cc @@ -0,0 +1,374 @@ +/* + * Copyright 2016 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/stats/rtc_stats.h" + +#include + +#include "rtc_base/arraysize.h" +#include "rtc_base/string_encode.h" +#include "rtc_base/strings/string_builder.h" + +namespace webrtc { + +namespace { + +// Produces "[a,b,c]". Works for non-vector `RTCStatsMemberInterface::Type` +// types. +template +std::string VectorToString(const std::vector& vector) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (const T& element : vector) { + sb << separator << rtc::ToString(element); + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +// This overload is required because std::vector range loops don't +// return references but objects, causing -Wrange-loop-analysis diagnostics. +std::string VectorToString(const std::vector& vector) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (bool element : vector) { + sb << separator << rtc::ToString(element); + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +// Produces "[\"a\",\"b\",\"c\"]". Works for vectors of both const char* and +// std::string element types. +template +std::string VectorOfStringsToString(const std::vector& strings) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (const T& element : strings) { + sb << separator << "\"" << rtc::ToString(element) << "\""; + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +template +std::string MapToString(const std::map& map) { + rtc::StringBuilder sb; + sb << "{"; + const char* separator = ""; + for (const auto& element : map) { + sb << separator << rtc::ToString(element.first) << ":" + << rtc::ToString(element.second); + separator = ","; + } + sb << "}"; + return sb.Release(); +} + +template +std::string ToStringAsDouble(const T value) { + // JSON represents numbers as floating point numbers with about 15 decimal + // digits of precision. + char buf[32]; + const int len = std::snprintf(&buf[0], arraysize(buf), "%.16g", + static_cast(value)); + RTC_DCHECK_LE(len, arraysize(buf)); + return std::string(&buf[0], len); +} + +template +std::string VectorToStringAsDouble(const std::vector& vector) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (const T& element : vector) { + sb << separator << ToStringAsDouble(element); + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +template +std::string MapToStringAsDouble(const std::map& map) { + rtc::StringBuilder sb; + sb << "{"; + const char* separator = ""; + for (const auto& element : map) { + sb << separator << "\"" << rtc::ToString(element.first) + << "\":" << ToStringAsDouble(element.second); + separator = ","; + } + sb << "}"; + return sb.Release(); +} + +} // namespace + +bool RTCStats::operator==(const RTCStats& other) const { + if (type() != other.type() || id() != other.id()) + return false; + std::vector members = Members(); + std::vector other_members = other.Members(); + RTC_DCHECK_EQ(members.size(), other_members.size()); + for (size_t i = 0; i < members.size(); ++i) { + const RTCStatsMemberInterface* member = members[i]; + const RTCStatsMemberInterface* other_member = other_members[i]; + RTC_DCHECK_EQ(member->type(), other_member->type()); + RTC_DCHECK_EQ(member->name(), other_member->name()); + if (*member != *other_member) + return false; + } + return true; +} + +bool RTCStats::operator!=(const RTCStats& other) const { + return !(*this == other); +} + +std::string RTCStats::ToJson() const { + rtc::StringBuilder sb; + sb << "{\"type\":\"" << type() + << "\"," + "\"id\":\"" + << id_ + << "\"," + "\"timestamp\":" + << timestamp_.us(); + for (const RTCStatsMemberInterface* member : Members()) { + if (member->is_defined()) { + sb << ",\"" << member->name() << "\":"; + if (member->is_string()) + sb << "\"" << member->ValueToJson() << "\""; + else + sb << member->ValueToJson(); + } + } + sb << "}"; + return sb.Release(); +} + +std::vector RTCStats::Members() const { + return MembersOfThisObjectAndAncestors(0); +} + +std::vector +RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const { + std::vector members; + members.reserve(additional_capacity); + return members; +} + +#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \ + template <> \ + RTCStatsMemberInterface::Type RTCStatsMember::StaticType() { \ + return type; \ + } \ + template <> \ + bool RTCStatsMember::is_sequence() const { \ + return is_seq; \ + } \ + template <> \ + bool RTCStatsMember::is_string() const { \ + return is_str; \ + } \ + template <> \ + std::string RTCStatsMember::ValueToString() const { \ + RTC_DCHECK(value_.has_value()); \ + return to_str; \ + } \ + template <> \ + std::string RTCStatsMember::ValueToJson() const { \ + RTC_DCHECK(value_.has_value()); \ + return to_json; \ + } \ + template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember + +WEBRTC_DEFINE_RTCSTATSMEMBER(bool, + kBool, + false, + false, + rtc::ToString(*value_), + rtc::ToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, + kInt32, + false, + false, + rtc::ToString(*value_), + rtc::ToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, + kUint32, + false, + false, + rtc::ToString(*value_), + rtc::ToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, + kInt64, + false, + false, + rtc::ToString(*value_), + ToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, + kUint64, + false, + false, + rtc::ToString(*value_), + ToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(double, + kDouble, + false, + false, + rtc::ToString(*value_), + ToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, + kString, + false, + true, + *value_, + *value_); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceBool, + true, + false, + VectorToString(*value_), + VectorToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceInt32, + true, + false, + VectorToString(*value_), + VectorToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceUint32, + true, + false, + VectorToString(*value_), + VectorToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceInt64, + true, + false, + VectorToString(*value_), + VectorToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceUint64, + true, + false, + VectorToString(*value_), + VectorToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceDouble, + true, + false, + VectorToString(*value_), + VectorToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, + kSequenceString, + true, + false, + VectorOfStringsToString(*value_), + VectorOfStringsToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64, + kMapStringUint64, + false, + false, + MapToString(*value_), + MapToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble, + kMapStringDouble, + false, + false, + MapToString(*value_), + MapToStringAsDouble(*value_)); + +// Restricted members that expose hardware capabilites. +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCRestrictedStatsMember, + StatExposureCriteria::kHardwareCapability>; + +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; +template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) + RTCNonStandardStatsMember>; + +} // namespace webrtc diff --git a/third_party/libwebrtc/stats/rtc_stats_report.cc b/third_party/libwebrtc/stats/rtc_stats_report.cc new file mode 100644 index 0000000000..f6fbd8c44d --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats_report.cc @@ -0,0 +1,140 @@ +/* + * Copyright 2016 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/stats/rtc_stats_report.h" + +#include +#include + +#include "rtc_base/checks.h" +#include "rtc_base/strings/string_builder.h" + +namespace webrtc { + +RTCStatsReport::ConstIterator::ConstIterator( + const rtc::scoped_refptr& report, + StatsMap::const_iterator it) + : report_(report), it_(it) {} + +RTCStatsReport::ConstIterator::ConstIterator(ConstIterator&& other) = default; + +RTCStatsReport::ConstIterator::~ConstIterator() {} + +RTCStatsReport::ConstIterator& RTCStatsReport::ConstIterator::operator++() { + ++it_; + return *this; +} + +RTCStatsReport::ConstIterator& RTCStatsReport::ConstIterator::operator++(int) { + return ++(*this); +} + +const RTCStats& RTCStatsReport::ConstIterator::operator*() const { + return *it_->second.get(); +} + +const RTCStats* RTCStatsReport::ConstIterator::operator->() const { + return it_->second.get(); +} + +bool RTCStatsReport::ConstIterator::operator==( + const RTCStatsReport::ConstIterator& other) const { + return it_ == other.it_; +} + +bool RTCStatsReport::ConstIterator::operator!=( + const RTCStatsReport::ConstIterator& other) const { + return !(*this == other); +} + +rtc::scoped_refptr RTCStatsReport::Create( + int64_t timestamp_us) { + return rtc::scoped_refptr(new RTCStatsReport(timestamp_us)); +} + +rtc::scoped_refptr RTCStatsReport::Create(Timestamp timestamp) { + return rtc::scoped_refptr(new RTCStatsReport(timestamp)); +} + +RTCStatsReport::RTCStatsReport(int64_t timestamp_us) + : RTCStatsReport(Timestamp::Micros(timestamp_us)) {} + +RTCStatsReport::RTCStatsReport(Timestamp timestamp) : timestamp_(timestamp) {} + +rtc::scoped_refptr RTCStatsReport::Copy() const { + rtc::scoped_refptr copy = Create(timestamp_); + for (auto it = stats_.begin(); it != stats_.end(); ++it) { + copy->AddStats(it->second->copy()); + } + return copy; +} + +void RTCStatsReport::AddStats(std::unique_ptr stats) { +#if RTC_DCHECK_IS_ON + auto result = +#endif + stats_.insert(std::make_pair(std::string(stats->id()), std::move(stats))); +#if RTC_DCHECK_IS_ON + RTC_DCHECK(result.second) + << "A stats object with ID \"" << result.first->second->id() << "\" is " + << "already present in this stats report."; +#endif +} + +const RTCStats* RTCStatsReport::Get(const std::string& id) const { + StatsMap::const_iterator it = stats_.find(id); + if (it != stats_.cend()) + return it->second.get(); + return nullptr; +} + +std::unique_ptr RTCStatsReport::Take(const std::string& id) { + StatsMap::iterator it = stats_.find(id); + if (it == stats_.end()) + return nullptr; + std::unique_ptr stats = std::move(it->second); + stats_.erase(it); + return stats; +} + +void RTCStatsReport::TakeMembersFrom(rtc::scoped_refptr other) { + for (StatsMap::iterator it = other->stats_.begin(); it != other->stats_.end(); + ++it) { + AddStats(std::unique_ptr(it->second.release())); + } + other->stats_.clear(); +} + +RTCStatsReport::ConstIterator RTCStatsReport::begin() const { + return ConstIterator(rtc::scoped_refptr(this), + stats_.cbegin()); +} + +RTCStatsReport::ConstIterator RTCStatsReport::end() const { + return ConstIterator(rtc::scoped_refptr(this), + stats_.cend()); +} + +std::string RTCStatsReport::ToJson() const { + if (begin() == end()) { + return ""; + } + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (ConstIterator it = begin(); it != end(); ++it) { + sb << separator << it->ToJson(); + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/stats/rtc_stats_report_unittest.cc b/third_party/libwebrtc/stats/rtc_stats_report_unittest.cc new file mode 100644 index 0000000000..b69da62f08 --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats_report_unittest.cc @@ -0,0 +1,172 @@ +/* + * Copyright 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/stats/rtc_stats_report.h" + +#include "api/stats/rtc_stats.h" +#include "rtc_base/checks.h" +#include "test/gtest.h" + +namespace webrtc { + +class RTCTestStats1 : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCTestStats1(const std::string& id, Timestamp timestamp) + : RTCStats(id, timestamp), integer("integer") {} + + RTCStatsMember integer; +}; + +WEBRTC_RTCSTATS_IMPL(RTCTestStats1, RTCStats, "test-stats-1", &integer) + +class RTCTestStats2 : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCTestStats2(const std::string& id, Timestamp timestamp) + : RTCStats(id, timestamp), number("number") {} + + RTCStatsMember number; +}; + +WEBRTC_RTCSTATS_IMPL(RTCTestStats2, RTCStats, "test-stats-2", &number) + +class RTCTestStats3 : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCTestStats3(const std::string& id, Timestamp timestamp) + : RTCStats(id, timestamp), string("string") {} + + RTCStatsMember string; +}; + +WEBRTC_RTCSTATS_IMPL(RTCTestStats3, RTCStats, "test-stats-3", &string) + +TEST(RTCStatsReport, AddAndGetStats) { + rtc::scoped_refptr report = + RTCStatsReport::Create(Timestamp::Micros(1337)); + EXPECT_EQ(report->timestamp_us(), 1337u); + EXPECT_EQ(report->timestamp().us_or(-1), 1337u); + EXPECT_EQ(report->size(), static_cast(0)); + report->AddStats( + std::unique_ptr(new RTCTestStats1("a0", Timestamp::Micros(1)))); + report->AddStats( + std::unique_ptr(new RTCTestStats1("a1", Timestamp::Micros(2)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("b0", Timestamp::Micros(4)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("b1", Timestamp::Micros(8)))); + report->AddStats(std::unique_ptr( + new RTCTestStats1("a2", Timestamp::Micros(16)))); + report->AddStats(std::unique_ptr( + new RTCTestStats2("b2", Timestamp::Micros(32)))); + EXPECT_EQ(report->size(), static_cast(6)); + + EXPECT_EQ(report->Get("missing"), nullptr); + EXPECT_EQ(report->Get("a0")->id(), "a0"); + EXPECT_EQ(report->Get("b2")->id(), "b2"); + + std::vector a = report->GetStatsOfType(); + EXPECT_EQ(a.size(), static_cast(3)); + int64_t mask = 0; + for (const RTCTestStats1* stats : a) + mask |= stats->timestamp().us(); + EXPECT_EQ(mask, static_cast(1 | 2 | 16)); + + std::vector b = report->GetStatsOfType(); + EXPECT_EQ(b.size(), static_cast(3)); + mask = 0; + for (const RTCTestStats2* stats : b) + mask |= stats->timestamp().us(); + EXPECT_EQ(mask, static_cast(4 | 8 | 32)); + + EXPECT_EQ(report->GetStatsOfType().size(), + static_cast(0)); +} + +TEST(RTCStatsReport, StatsOrder) { + rtc::scoped_refptr report = + RTCStatsReport::Create(Timestamp::Micros(1337)); + EXPECT_EQ(report->timestamp().us(), 1337u); + EXPECT_EQ(report->timestamp().us_or(-1), 1337u); + report->AddStats( + std::unique_ptr(new RTCTestStats1("C", Timestamp::Micros(2)))); + report->AddStats( + std::unique_ptr(new RTCTestStats1("D", Timestamp::Micros(3)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("B", Timestamp::Micros(1)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("A", Timestamp::Micros(0)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("E", Timestamp::Micros(4)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("F", Timestamp::Micros(5)))); + report->AddStats( + std::unique_ptr(new RTCTestStats2("G", Timestamp::Micros(6)))); + int64_t i = 0; + for (const RTCStats& stats : *report) { + EXPECT_EQ(stats.timestamp().us(), i); + ++i; + } + EXPECT_EQ(i, static_cast(7)); +} + +TEST(RTCStatsReport, Take) { + rtc::scoped_refptr report = + RTCStatsReport::Create(Timestamp::Zero()); + report->AddStats( + std::unique_ptr(new RTCTestStats1("A", Timestamp::Micros(1)))); + report->AddStats( + std::unique_ptr(new RTCTestStats1("B", Timestamp::Micros(2)))); + EXPECT_TRUE(report->Get("A")); + EXPECT_EQ(report->size(), 2u); + auto a = report->Take("A"); + EXPECT_TRUE(a); + EXPECT_EQ(report->size(), 1u); + EXPECT_FALSE(report->Get("A")); + EXPECT_FALSE(report->Take("A")); +} + +TEST(RTCStatsReport, TakeMembersFrom) { + rtc::scoped_refptr a = + RTCStatsReport::Create(Timestamp::Micros(1337)); + EXPECT_EQ(a->timestamp().us(), 1337u); + EXPECT_EQ(a->timestamp().us_or(-1), 1337u); + a->AddStats( + std::unique_ptr(new RTCTestStats1("B", Timestamp::Micros(1)))); + a->AddStats( + std::unique_ptr(new RTCTestStats1("C", Timestamp::Micros(2)))); + a->AddStats( + std::unique_ptr(new RTCTestStats1("E", Timestamp::Micros(4)))); + rtc::scoped_refptr b = + RTCStatsReport::Create(Timestamp::Micros(1338)); + EXPECT_EQ(b->timestamp_us(), 1338u); + EXPECT_EQ(b->timestamp().us_or(-1), 1338u); + b->AddStats( + std::unique_ptr(new RTCTestStats1("A", Timestamp::Micros(0)))); + b->AddStats( + std::unique_ptr(new RTCTestStats1("D", Timestamp::Micros(3)))); + b->AddStats( + std::unique_ptr(new RTCTestStats1("F", Timestamp::Micros(5)))); + + a->TakeMembersFrom(b); + EXPECT_EQ(b->size(), static_cast(0)); + int64_t i = 0; + for (const RTCStats& stats : *a) { + EXPECT_EQ(stats.timestamp().us(), i); + ++i; + } + EXPECT_EQ(i, static_cast(6)); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/stats/rtc_stats_unittest.cc b/third_party/libwebrtc/stats/rtc_stats_unittest.cc new file mode 100644 index 0000000000..84b9a63ed4 --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats_unittest.cc @@ -0,0 +1,549 @@ +/* + * Copyright 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/stats/rtc_stats.h" + +#include +#include +#include +#include + +#include "rtc_base/checks.h" +#include "rtc_base/strings/json.h" +#include "stats/test/rtc_test_stats.h" +#include "test/gtest.h" + +namespace webrtc { + +namespace { + +// JSON stores numbers as floating point numbers with 53 significant bits, which +// amounts to about 15.95 decimal digits. Thus, when comparing large numbers +// processed by JSON, that's all the precision we should expect. +const double JSON_EPSILON = 1e-15; + +// We do this since Google Test doesn't support relative error. +// This is computed as follows: +// If |a - b| / |a| < EPS, then |a - b| < |a| * EPS, so |a| * EPS is the +// maximum expected error. +double GetExpectedError(const double expected_value) { + return JSON_EPSILON * fabs(expected_value); +} + +} // namespace + +class RTCChildStats : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCChildStats(const std::string& id, Timestamp timestamp) + : RTCStats(id, timestamp), child_int("childInt") {} + + RTCStatsMember child_int; +}; + +WEBRTC_RTCSTATS_IMPL(RTCChildStats, RTCStats, "child-stats", &child_int) + +class RTCGrandChildStats : public RTCChildStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCGrandChildStats(const std::string& id, Timestamp timestamp) + : RTCChildStats(id, timestamp), grandchild_int("grandchildInt") {} + + RTCStatsMember grandchild_int; +}; + +WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats, + RTCChildStats, + "grandchild-stats", + &grandchild_int) + +TEST(RTCStatsTest, RTCStatsAndMembers) { + RTCTestStats stats("testId", Timestamp::Micros(42)); + EXPECT_EQ(stats.id(), "testId"); + EXPECT_EQ(stats.timestamp().us(), static_cast(42)); + std::vector members = stats.Members(); + EXPECT_EQ(members.size(), static_cast(16)); + for (const RTCStatsMemberInterface* member : members) { + EXPECT_FALSE(member->is_defined()); + } + stats.m_bool = true; + stats.m_int32 = 123; + stats.m_uint32 = 123; + stats.m_int64 = 123; + stats.m_uint64 = 123; + stats.m_double = 123.0; + stats.m_string = std::string("123"); + + std::vector sequence_bool; + sequence_bool.push_back(true); + std::vector sequence_int32; + sequence_int32.push_back(static_cast(1)); + std::vector sequence_uint32; + sequence_uint32.push_back(static_cast(2)); + std::vector sequence_int64; + sequence_int64.push_back(static_cast(3)); + std::vector sequence_uint64; + sequence_uint64.push_back(static_cast(4)); + std::vector sequence_double; + sequence_double.push_back(5.0); + std::vector sequence_string; + sequence_string.push_back(std::string("six")); + + std::map map_string_uint64{{"seven", 8}}; + std::map map_string_double{{"nine", 10.0}}; + + stats.m_sequence_bool = sequence_bool; + stats.m_sequence_int32 = sequence_int32; + stats.m_sequence_uint32 = sequence_uint32; + EXPECT_FALSE(stats.m_sequence_int64.is_defined()); + stats.m_sequence_int64 = sequence_int64; + stats.m_sequence_uint64 = sequence_uint64; + stats.m_sequence_double = sequence_double; + stats.m_sequence_string = sequence_string; + stats.m_map_string_uint64 = map_string_uint64; + stats.m_map_string_double = map_string_double; + for (const RTCStatsMemberInterface* member : members) { + EXPECT_TRUE(member->is_defined()); + } + EXPECT_EQ(*stats.m_bool, true); + EXPECT_EQ(*stats.m_int32, static_cast(123)); + EXPECT_EQ(*stats.m_uint32, static_cast(123)); + EXPECT_EQ(*stats.m_int64, static_cast(123)); + EXPECT_EQ(*stats.m_uint64, static_cast(123)); + EXPECT_EQ(*stats.m_double, 123.0); + EXPECT_EQ(*stats.m_string, std::string("123")); + EXPECT_EQ(*stats.m_sequence_bool, sequence_bool); + EXPECT_EQ(*stats.m_sequence_int32, sequence_int32); + EXPECT_EQ(*stats.m_sequence_uint32, sequence_uint32); + EXPECT_EQ(*stats.m_sequence_int64, sequence_int64); + EXPECT_EQ(*stats.m_sequence_uint64, sequence_uint64); + EXPECT_EQ(*stats.m_sequence_double, sequence_double); + EXPECT_EQ(*stats.m_sequence_string, sequence_string); + EXPECT_EQ(*stats.m_map_string_uint64, map_string_uint64); + EXPECT_EQ(*stats.m_map_string_double, map_string_double); + + int32_t numbers[] = {4, 8, 15, 16, 23, 42}; + std::vector numbers_sequence(&numbers[0], &numbers[6]); + stats.m_sequence_int32->clear(); + stats.m_sequence_int32->insert(stats.m_sequence_int32->end(), + numbers_sequence.begin(), + numbers_sequence.end()); + EXPECT_EQ(*stats.m_sequence_int32, numbers_sequence); +} + +TEST(RTCStatsTest, EqualityOperator) { + RTCTestStats empty_stats("testId", Timestamp::Micros(123)); + EXPECT_EQ(empty_stats, empty_stats); + + RTCTestStats stats_with_all_values = empty_stats; + stats_with_all_values.m_bool = true; + stats_with_all_values.m_int32 = 123; + stats_with_all_values.m_uint32 = 123; + stats_with_all_values.m_int64 = 123; + stats_with_all_values.m_uint64 = 123; + stats_with_all_values.m_double = 123.0; + stats_with_all_values.m_string = "123"; + stats_with_all_values.m_sequence_bool = std::vector(); + stats_with_all_values.m_sequence_int32 = std::vector(); + stats_with_all_values.m_sequence_uint32 = std::vector(); + stats_with_all_values.m_sequence_int64 = std::vector(); + stats_with_all_values.m_sequence_uint64 = std::vector(); + stats_with_all_values.m_sequence_double = std::vector(); + stats_with_all_values.m_sequence_string = std::vector(); + stats_with_all_values.m_map_string_uint64 = std::map(); + stats_with_all_values.m_map_string_double = std::map(); + EXPECT_NE(stats_with_all_values, empty_stats); + EXPECT_EQ(stats_with_all_values, stats_with_all_values); + EXPECT_NE(stats_with_all_values.m_int32, stats_with_all_values.m_uint32); + + RTCTestStats one_member_different[] = { + stats_with_all_values, stats_with_all_values, stats_with_all_values, + stats_with_all_values, stats_with_all_values, stats_with_all_values, + stats_with_all_values, stats_with_all_values, stats_with_all_values, + stats_with_all_values, stats_with_all_values, stats_with_all_values, + stats_with_all_values, stats_with_all_values, + }; + for (size_t i = 0; i < 14; ++i) { + EXPECT_EQ(stats_with_all_values, one_member_different[i]); + } + one_member_different[0].m_bool = false; + one_member_different[1].m_int32 = 321; + one_member_different[2].m_uint32 = 321; + one_member_different[3].m_int64 = 321; + one_member_different[4].m_uint64 = 321; + one_member_different[5].m_double = 321.0; + one_member_different[6].m_string = "321"; + one_member_different[7].m_sequence_bool->push_back(false); + one_member_different[8].m_sequence_int32->push_back(321); + one_member_different[9].m_sequence_uint32->push_back(321); + one_member_different[10].m_sequence_int64->push_back(321); + one_member_different[11].m_sequence_uint64->push_back(321); + one_member_different[12].m_sequence_double->push_back(321.0); + one_member_different[13].m_sequence_string->push_back("321"); + (*one_member_different[13].m_map_string_uint64)["321"] = 321; + (*one_member_different[13].m_map_string_double)["321"] = 321.0; + for (size_t i = 0; i < 14; ++i) { + EXPECT_NE(stats_with_all_values, one_member_different[i]); + } + + RTCTestStats empty_stats_different_id("testId2", Timestamp::Micros(123)); + EXPECT_NE(empty_stats, empty_stats_different_id); + RTCTestStats empty_stats_different_timestamp("testId", + Timestamp::Micros(321)); + EXPECT_EQ(empty_stats, empty_stats_different_timestamp); + + RTCChildStats child("childId", Timestamp::Micros(42)); + RTCGrandChildStats grandchild("grandchildId", Timestamp::Micros(42)); + EXPECT_NE(child, grandchild); + + RTCChildStats stats_with_defined_member("leId", Timestamp::Micros(0)); + stats_with_defined_member.child_int = 0; + RTCChildStats stats_with_undefined_member("leId", Timestamp::Micros(0)); + EXPECT_NE(stats_with_defined_member, stats_with_undefined_member); + EXPECT_NE(stats_with_undefined_member, stats_with_defined_member); +} + +TEST(RTCStatsTest, RTCStatsGrandChild) { + RTCGrandChildStats stats("grandchild", Timestamp::Micros(0.0)); + stats.child_int = 1; + stats.grandchild_int = 2; + int32_t sum = 0; + for (const RTCStatsMemberInterface* member : stats.Members()) { + sum += *member->cast_to>(); + } + EXPECT_EQ(sum, static_cast(3)); + + std::unique_ptr copy_ptr = stats.copy(); + const RTCGrandChildStats& copy = copy_ptr->cast_to(); + EXPECT_EQ(*copy.child_int, *stats.child_int); + EXPECT_EQ(*copy.grandchild_int, *stats.grandchild_int); +} + +TEST(RTCStatsTest, RTCStatsPrintsValidJson) { + std::string id = "statsId"; + int timestamp = 42; + bool m_bool = true; + int m_int32 = 123; + int64_t m_int64 = 1234567890123456499L; + double m_double = 123.4567890123456499; + std::string m_string = "123"; + + std::vector sequence_bool; + std::vector sequence_int32; + sequence_int32.push_back(static_cast(1)); + std::vector sequence_int64; + sequence_int64.push_back(static_cast(-1234567890123456499L)); + sequence_int64.push_back(static_cast(1)); + sequence_int64.push_back(static_cast(1234567890123456499L)); + std::vector sequence_double; + sequence_double.push_back(123.4567890123456499); + sequence_double.push_back(1234567890123.456499); + std::vector sequence_string; + sequence_string.push_back(std::string("four")); + + std::map map_string_uint64{ + {"long", static_cast(1234567890123456499L)}}; + std::map map_string_double{ + {"three", 123.4567890123456499}, {"thirteen", 123.4567890123456499}}; + + RTCTestStats stats(id, Timestamp::Micros(timestamp)); + stats.m_bool = m_bool; + stats.m_int32 = m_int32; + stats.m_int64 = m_int64; + stats.m_double = m_double; + stats.m_string = m_string; + stats.m_sequence_bool = sequence_bool; + stats.m_sequence_int32 = sequence_int32; + stats.m_sequence_int64 = sequence_int64; + stats.m_sequence_double = sequence_double; + stats.m_sequence_string = sequence_string; + stats.m_map_string_uint64 = map_string_uint64; + stats.m_map_string_double = map_string_double; + std::string json_stats = stats.ToJson(); + + Json::CharReaderBuilder builder; + Json::Value json_output; + std::unique_ptr json_reader(builder.newCharReader()); + EXPECT_TRUE(json_reader->parse(json_stats.c_str(), + json_stats.c_str() + json_stats.size(), + &json_output, nullptr)); + + EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "id", &id)); + EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "timestamp", ×tamp)); + EXPECT_TRUE(rtc::GetBoolFromJsonObject(json_output, "mBool", &m_bool)); + EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "mInt32", &m_int32)); + EXPECT_TRUE(rtc::GetDoubleFromJsonObject(json_output, "mDouble", &m_double)); + EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "mString", &m_string)); + + Json::Value json_array; + + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mSequenceBool", &json_array)); + EXPECT_TRUE(rtc::JsonArrayToBoolVector(json_array, &sequence_bool)); + + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mSequenceInt32", &json_array)); + EXPECT_TRUE(rtc::JsonArrayToIntVector(json_array, &sequence_int32)); + + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mSequenceDouble", &json_array)); + EXPECT_TRUE(rtc::JsonArrayToDoubleVector(json_array, &sequence_double)); + + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mSequenceString", &json_array)); + EXPECT_TRUE(rtc::JsonArrayToStringVector(json_array, &sequence_string)); + + Json::Value json_map; + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mMapStringDouble", &json_map)); + for (const auto& entry : map_string_double) { + double double_output = 0.0; + EXPECT_TRUE( + rtc::GetDoubleFromJsonObject(json_map, entry.first, &double_output)); + EXPECT_NEAR(double_output, entry.second, GetExpectedError(entry.second)); + } + + EXPECT_EQ(id, stats.id()); + EXPECT_EQ(timestamp, stats.timestamp().us()); + EXPECT_EQ(m_bool, *stats.m_bool); + EXPECT_EQ(m_int32, *stats.m_int32); + EXPECT_EQ(m_string, *stats.m_string); + EXPECT_EQ(sequence_bool, *stats.m_sequence_bool); + EXPECT_EQ(sequence_int32, *stats.m_sequence_int32); + EXPECT_EQ(sequence_string, *stats.m_sequence_string); + EXPECT_EQ(map_string_double, *stats.m_map_string_double); + + EXPECT_NEAR(m_double, *stats.m_double, GetExpectedError(*stats.m_double)); + + EXPECT_EQ(sequence_double.size(), stats.m_sequence_double->size()); + for (size_t i = 0; i < stats.m_sequence_double->size(); ++i) { + EXPECT_NEAR(sequence_double[i], stats.m_sequence_double->at(i), + GetExpectedError(stats.m_sequence_double->at(i))); + } + + EXPECT_EQ(map_string_double.size(), stats.m_map_string_double->size()); + for (const auto& entry : map_string_double) { + auto it = stats.m_map_string_double->find(entry.first); + EXPECT_NE(it, stats.m_map_string_double->end()); + EXPECT_NEAR(entry.second, it->second, GetExpectedError(it->second)); + } + + // We read mInt64 as double since JSON stores all numbers as doubles, so there + // is not enough precision to represent large numbers. + double m_int64_as_double; + std::vector sequence_int64_as_double; + + EXPECT_TRUE( + rtc::GetDoubleFromJsonObject(json_output, "mInt64", &m_int64_as_double)); + + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mSequenceInt64", &json_array)); + EXPECT_TRUE( + rtc::JsonArrayToDoubleVector(json_array, &sequence_int64_as_double)); + + double stats_m_int64_as_double = static_cast(*stats.m_int64); + EXPECT_NEAR(m_int64_as_double, stats_m_int64_as_double, + GetExpectedError(stats_m_int64_as_double)); + + EXPECT_EQ(sequence_int64_as_double.size(), stats.m_sequence_int64->size()); + for (size_t i = 0; i < stats.m_sequence_int64->size(); ++i) { + const double stats_value_as_double = + static_cast((*stats.m_sequence_int64)[i]); + EXPECT_NEAR(sequence_int64_as_double[i], stats_value_as_double, + GetExpectedError(stats_value_as_double)); + } + + // Similarly, read Uint64 as double + EXPECT_TRUE( + rtc::GetValueFromJsonObject(json_output, "mMapStringUint64", &json_map)); + for (const auto& entry : map_string_uint64) { + const double stats_value_as_double = + static_cast((*stats.m_map_string_uint64)[entry.first]); + double double_output = 0.0; + EXPECT_TRUE( + rtc::GetDoubleFromJsonObject(json_map, entry.first, &double_output)); + EXPECT_NEAR(double_output, stats_value_as_double, + GetExpectedError(stats_value_as_double)); + } + + // Neither stats.m_uint32 nor stats.m_uint64 are defined, so "mUint64" and + // "mUint32" should not be part of the generated JSON object. + int m_uint32; + int m_uint64; + EXPECT_FALSE(stats.m_uint32.is_defined()); + EXPECT_FALSE(stats.m_uint64.is_defined()); + EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint32", &m_uint32)); + EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint64", &m_uint64)); + + 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()); +} + +TEST(RTCStatsTest, IsSequence) { + RTCTestStats stats("statsId", Timestamp::Micros(42)); + EXPECT_FALSE(stats.m_bool.is_sequence()); + EXPECT_FALSE(stats.m_int32.is_sequence()); + EXPECT_FALSE(stats.m_uint32.is_sequence()); + EXPECT_FALSE(stats.m_int64.is_sequence()); + EXPECT_FALSE(stats.m_uint64.is_sequence()); + EXPECT_FALSE(stats.m_double.is_sequence()); + EXPECT_FALSE(stats.m_string.is_sequence()); + EXPECT_TRUE(stats.m_sequence_bool.is_sequence()); + EXPECT_TRUE(stats.m_sequence_int32.is_sequence()); + EXPECT_TRUE(stats.m_sequence_uint32.is_sequence()); + EXPECT_TRUE(stats.m_sequence_int64.is_sequence()); + EXPECT_TRUE(stats.m_sequence_uint64.is_sequence()); + EXPECT_TRUE(stats.m_sequence_double.is_sequence()); + EXPECT_TRUE(stats.m_sequence_string.is_sequence()); + EXPECT_FALSE(stats.m_map_string_uint64.is_sequence()); + EXPECT_FALSE(stats.m_map_string_double.is_sequence()); +} + +TEST(RTCStatsTest, Type) { + RTCTestStats stats("statsId", Timestamp::Micros(42)); + EXPECT_EQ(RTCStatsMemberInterface::kBool, stats.m_bool.type()); + EXPECT_EQ(RTCStatsMemberInterface::kInt32, stats.m_int32.type()); + EXPECT_EQ(RTCStatsMemberInterface::kUint32, stats.m_uint32.type()); + EXPECT_EQ(RTCStatsMemberInterface::kInt64, stats.m_int64.type()); + EXPECT_EQ(RTCStatsMemberInterface::kUint64, stats.m_uint64.type()); + EXPECT_EQ(RTCStatsMemberInterface::kDouble, stats.m_double.type()); + EXPECT_EQ(RTCStatsMemberInterface::kString, stats.m_string.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceBool, + stats.m_sequence_bool.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceInt32, + stats.m_sequence_int32.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceUint32, + stats.m_sequence_uint32.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceInt64, + stats.m_sequence_int64.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceUint64, + stats.m_sequence_uint64.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceDouble, + stats.m_sequence_double.type()); + EXPECT_EQ(RTCStatsMemberInterface::kSequenceString, + stats.m_sequence_string.type()); + EXPECT_EQ(RTCStatsMemberInterface::kMapStringUint64, + stats.m_map_string_uint64.type()); + EXPECT_EQ(RTCStatsMemberInterface::kMapStringDouble, + stats.m_map_string_double.type()); +} + +TEST(RTCStatsTest, IsString) { + RTCTestStats stats("statsId", Timestamp::Micros(42)); + EXPECT_TRUE(stats.m_string.is_string()); + EXPECT_FALSE(stats.m_bool.is_string()); + EXPECT_FALSE(stats.m_int32.is_string()); + EXPECT_FALSE(stats.m_uint32.is_string()); + EXPECT_FALSE(stats.m_int64.is_string()); + EXPECT_FALSE(stats.m_uint64.is_string()); + EXPECT_FALSE(stats.m_double.is_string()); + EXPECT_FALSE(stats.m_sequence_bool.is_string()); + EXPECT_FALSE(stats.m_sequence_int32.is_string()); + EXPECT_FALSE(stats.m_sequence_uint32.is_string()); + EXPECT_FALSE(stats.m_sequence_int64.is_string()); + EXPECT_FALSE(stats.m_sequence_uint64.is_string()); + EXPECT_FALSE(stats.m_sequence_double.is_string()); + EXPECT_FALSE(stats.m_sequence_string.is_string()); + EXPECT_FALSE(stats.m_map_string_uint64.is_string()); + EXPECT_FALSE(stats.m_map_string_double.is_string()); +} + +TEST(RTCStatsTest, ValueToString) { + RTCTestStats stats("statsId", Timestamp::Micros(42)); + stats.m_bool = true; + EXPECT_EQ("true", stats.m_bool.ValueToString()); + + stats.m_string = "foo"; + EXPECT_EQ("foo", stats.m_string.ValueToString()); + stats.m_int32 = -32; + EXPECT_EQ("-32", stats.m_int32.ValueToString()); + stats.m_uint32 = 32; + EXPECT_EQ("32", stats.m_uint32.ValueToString()); + stats.m_int64 = -64; + EXPECT_EQ("-64", stats.m_int64.ValueToString()); + stats.m_uint64 = 64; + EXPECT_EQ("64", stats.m_uint64.ValueToString()); + stats.m_double = 0.5; + EXPECT_EQ("0.5", stats.m_double.ValueToString()); + stats.m_sequence_bool = {true, false}; + EXPECT_EQ("[true,false]", stats.m_sequence_bool.ValueToString()); + stats.m_sequence_int32 = {-32, 32}; + EXPECT_EQ("[-32,32]", stats.m_sequence_int32.ValueToString()); + stats.m_sequence_uint32 = {64, 32}; + EXPECT_EQ("[64,32]", stats.m_sequence_uint32.ValueToString()); + stats.m_sequence_int64 = {-64, 32}; + EXPECT_EQ("[-64,32]", stats.m_sequence_int64.ValueToString()); + stats.m_sequence_uint64 = {16, 32}; + EXPECT_EQ("[16,32]", stats.m_sequence_uint64.ValueToString()); + stats.m_sequence_double = {0.5, 0.25}; + EXPECT_EQ("[0.5,0.25]", stats.m_sequence_double.ValueToString()); + stats.m_sequence_string = {"foo", "bar"}; + EXPECT_EQ("[\"foo\",\"bar\"]", stats.m_sequence_string.ValueToString()); + stats.m_map_string_uint64 = std::map(); + stats.m_map_string_uint64->emplace("foo", 32); + stats.m_map_string_uint64->emplace("bar", 64); + EXPECT_EQ("{bar:64,foo:32}", stats.m_map_string_uint64.ValueToString()); + stats.m_map_string_double = std::map(); + stats.m_map_string_double->emplace("foo", 0.5); + stats.m_map_string_double->emplace("bar", 0.25); + EXPECT_EQ("{bar:0.25,foo:0.5}", stats.m_map_string_double.ValueToString()); +} + +TEST(RTCStatsTest, RestrictedStatsTest) { + RTCStatsMember unrestricted("unrestricted"); + EXPECT_EQ(unrestricted.exposure_criteria(), StatExposureCriteria::kAlways); + RTCRestrictedStatsMember + 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 with_group_id("stat", {group_id}); + std::vector expected_ids({group_id}); + EXPECT_EQ(expected_ids, with_group_id.group_ids()); + + RTCNonStandardStatsMember without_group_id("stat"); + EXPECT_TRUE(without_group_id.group_ids().empty()); +} + +// Death tests. +// Disabled on Android because death tests misbehave on Android, see +// base/test/gtest_util.h. +#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) + +TEST(RTCStatsDeathTest, ValueOfUndefinedMember) { + RTCTestStats stats("testId", Timestamp::Micros(0)); + EXPECT_FALSE(stats.m_int32.is_defined()); + EXPECT_DEATH(*stats.m_int32, ""); +} + +TEST(RTCStatsDeathTest, InvalidCasting) { + RTCGrandChildStats stats("grandchild", Timestamp::Micros(0.0)); + EXPECT_DEATH(stats.cast_to(), ""); +} + +#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) + +} // namespace webrtc diff --git a/third_party/libwebrtc/stats/rtcstats_objects.cc b/third_party/libwebrtc/stats/rtcstats_objects.cc new file mode 100644 index 0000000000..b25e2ddc0d --- /dev/null +++ b/third_party/libwebrtc/stats/rtcstats_objects.cc @@ -0,0 +1,925 @@ +/* + * Copyright 2016 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/stats/rtcstats_objects.h" + +#include + +#include "api/stats/rtc_stats.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +const char* const RTCDataChannelState::kConnecting = "connecting"; +const char* const RTCDataChannelState::kOpen = "open"; +const char* const RTCDataChannelState::kClosing = "closing"; +const char* const RTCDataChannelState::kClosed = "closed"; + +const char* const RTCStatsIceCandidatePairState::kFrozen = "frozen"; +const char* const RTCStatsIceCandidatePairState::kWaiting = "waiting"; +const char* const RTCStatsIceCandidatePairState::kInProgress = "in-progress"; +const char* const RTCStatsIceCandidatePairState::kFailed = "failed"; +const char* const RTCStatsIceCandidatePairState::kSucceeded = "succeeded"; + +// Strings defined in https://tools.ietf.org/html/rfc5245. +const char* const RTCIceCandidateType::kHost = "host"; +const char* const RTCIceCandidateType::kSrflx = "srflx"; +const char* const RTCIceCandidateType::kPrflx = "prflx"; +const char* const RTCIceCandidateType::kRelay = "relay"; + +const char* const RTCDtlsTransportState::kNew = "new"; +const char* const RTCDtlsTransportState::kConnecting = "connecting"; +const char* const RTCDtlsTransportState::kConnected = "connected"; +const char* const RTCDtlsTransportState::kClosed = "closed"; +const char* const RTCDtlsTransportState::kFailed = "failed"; + +const char* const RTCMediaStreamTrackKind::kAudio = "audio"; +const char* const RTCMediaStreamTrackKind::kVideo = "video"; + +// https://w3c.github.io/webrtc-stats/#dom-rtcnetworktype +const char* const RTCNetworkType::kBluetooth = "bluetooth"; +const char* const RTCNetworkType::kCellular = "cellular"; +const char* const RTCNetworkType::kEthernet = "ethernet"; +const char* const RTCNetworkType::kWifi = "wifi"; +const char* const RTCNetworkType::kWimax = "wimax"; +const char* const RTCNetworkType::kVpn = "vpn"; +const char* const RTCNetworkType::kUnknown = "unknown"; + +// https://w3c.github.io/webrtc-stats/#dom-rtcqualitylimitationreason +const char* const RTCQualityLimitationReason::kNone = "none"; +const char* const RTCQualityLimitationReason::kCpu = "cpu"; +const char* const RTCQualityLimitationReason::kBandwidth = "bandwidth"; +const char* const RTCQualityLimitationReason::kOther = "other"; + +// https://webrtc.org/experiments/rtp-hdrext/video-content-type/ +const char* const RTCContentType::kUnspecified = "unspecified"; +const char* const RTCContentType::kScreenshare = "screenshare"; + +// https://w3c.github.io/webrtc-stats/#dom-rtcdtlsrole +const char* const RTCDtlsRole::kUnknown = "unknown"; +const char* const RTCDtlsRole::kClient = "client"; +const char* const RTCDtlsRole::kServer = "server"; + +// https://www.w3.org/TR/webrtc/#rtcicerole +const char* const RTCIceRole::kUnknown = "unknown"; +const char* const RTCIceRole::kControlled = "controlled"; +const char* const RTCIceRole::kControlling = "controlling"; + +// https://www.w3.org/TR/webrtc/#dom-rtcicetransportstate +const char* const RTCIceTransportState::kNew = "new"; +const char* const RTCIceTransportState::kChecking = "checking"; +const char* const RTCIceTransportState::kConnected = "connected"; +const char* const RTCIceTransportState::kCompleted = "completed"; +const char* const RTCIceTransportState::kDisconnected = "disconnected"; +const char* const RTCIceTransportState::kFailed = "failed"; +const char* const RTCIceTransportState::kClosed = "closed"; + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCCertificateStats, RTCStats, "certificate", + &fingerprint, + &fingerprint_algorithm, + &base64_certificate, + &issuer_certificate_id) +// clang-format on + +RTCCertificateStats::RTCCertificateStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + fingerprint("fingerprint"), + fingerprint_algorithm("fingerprintAlgorithm"), + base64_certificate("base64Certificate"), + issuer_certificate_id("issuerCertificateId") {} +RTCCertificateStats::RTCCertificateStats(std::string id, int64_t timestamp_us) + : RTCCertificateStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCCertificateStats::RTCCertificateStats(const RTCCertificateStats& other) = + default; +RTCCertificateStats::~RTCCertificateStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCCodecStats, RTCStats, "codec", + &transport_id, + &payload_type, + &mime_type, + &clock_rate, + &channels, + &sdp_fmtp_line) +// clang-format on + +RTCCodecStats::RTCCodecStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + transport_id("transportId"), + payload_type("payloadType"), + mime_type("mimeType"), + clock_rate("clockRate"), + channels("channels"), + sdp_fmtp_line("sdpFmtpLine") {} +RTCCodecStats::RTCCodecStats(std::string id, int64_t timestamp_us) + : RTCCodecStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCCodecStats::RTCCodecStats(const RTCCodecStats& other) = default; + +RTCCodecStats::~RTCCodecStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCDataChannelStats, RTCStats, "data-channel", + &label, + &protocol, + &data_channel_identifier, + &state, + &messages_sent, + &bytes_sent, + &messages_received, + &bytes_received) +// clang-format on + +RTCDataChannelStats::RTCDataChannelStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + label("label"), + protocol("protocol"), + data_channel_identifier("dataChannelIdentifier"), + state("state"), + messages_sent("messagesSent"), + bytes_sent("bytesSent"), + messages_received("messagesReceived"), + bytes_received("bytesReceived") {} +RTCDataChannelStats::RTCDataChannelStats(std::string id, int64_t timestamp_us) + : RTCDataChannelStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCDataChannelStats::RTCDataChannelStats(const RTCDataChannelStats& other) = + default; + +RTCDataChannelStats::~RTCDataChannelStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCIceCandidatePairStats, RTCStats, "candidate-pair", + &transport_id, + &local_candidate_id, + &remote_candidate_id, + &state, + &priority, + &nominated, + &writable, + &packets_sent, + &packets_received, + &bytes_sent, + &bytes_received, + &total_round_trip_time, + ¤t_round_trip_time, + &available_outgoing_bitrate, + &available_incoming_bitrate, + &requests_received, + &requests_sent, + &responses_received, + &responses_sent, + &consent_requests_sent, + &packets_discarded_on_send, + &bytes_discarded_on_send, + &last_packet_received_timestamp, + &last_packet_sent_timestamp) +// clang-format on + +RTCIceCandidatePairStats::RTCIceCandidatePairStats(std::string id, + Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + transport_id("transportId"), + local_candidate_id("localCandidateId"), + remote_candidate_id("remoteCandidateId"), + state("state"), + priority("priority"), + nominated("nominated"), + writable("writable"), + packets_sent("packetsSent"), + packets_received("packetsReceived"), + bytes_sent("bytesSent"), + bytes_received("bytesReceived"), + total_round_trip_time("totalRoundTripTime"), + current_round_trip_time("currentRoundTripTime"), + available_outgoing_bitrate("availableOutgoingBitrate"), + available_incoming_bitrate("availableIncomingBitrate"), + requests_received("requestsReceived"), + requests_sent("requestsSent"), + responses_received("responsesReceived"), + responses_sent("responsesSent"), + consent_requests_sent("consentRequestsSent"), + packets_discarded_on_send("packetsDiscardedOnSend"), + bytes_discarded_on_send("bytesDiscardedOnSend"), + last_packet_received_timestamp("lastPacketReceivedTimestamp"), + last_packet_sent_timestamp("lastPacketSentTimestamp") {} +RTCIceCandidatePairStats::RTCIceCandidatePairStats(std::string id, + int64_t timestamp_us) + : RTCIceCandidatePairStats(std::move(id), Timestamp::Micros(timestamp_us)) { +} + +RTCIceCandidatePairStats::RTCIceCandidatePairStats( + const RTCIceCandidatePairStats& other) = default; + +RTCIceCandidatePairStats::~RTCIceCandidatePairStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCIceCandidateStats, RTCStats, "abstract-ice-candidate", + &transport_id, + &is_remote, + &network_type, + &ip, + &address, + &port, + &protocol, + &relay_protocol, + &candidate_type, + &priority, + &url, + &foundation, + &related_address, + &related_port, + &username_fragment, + &tcp_type, + &vpn, + &network_adapter_type) +// clang-format on + +RTCIceCandidateStats::RTCIceCandidateStats(std::string id, + Timestamp timestamp, + bool is_remote) + : RTCStats(std::move(id), timestamp), + transport_id("transportId"), + is_remote("isRemote", is_remote), + network_type("networkType"), + ip("ip"), + address("address"), + port("port"), + protocol("protocol"), + relay_protocol("relayProtocol"), + candidate_type("candidateType"), + priority("priority"), + url("url"), + foundation("foundation"), + related_address("relatedAddress"), + related_port("relatedPort"), + username_fragment("usernameFragment"), + tcp_type("tcpType"), + vpn("vpn"), + network_adapter_type("networkAdapterType") {} +RTCIceCandidateStats::RTCIceCandidateStats(std::string id, + int64_t timestamp_us, + bool is_remote) + : RTCIceCandidateStats(std::move(id), + Timestamp::Micros(timestamp_us), + is_remote) {} + +RTCIceCandidateStats::RTCIceCandidateStats(const RTCIceCandidateStats& other) = + default; + +RTCIceCandidateStats::~RTCIceCandidateStats() {} + +const char RTCLocalIceCandidateStats::kType[] = "local-candidate"; + +RTCLocalIceCandidateStats::RTCLocalIceCandidateStats(std::string id, + Timestamp timestamp) + : RTCIceCandidateStats(std::move(id), timestamp, false) {} +RTCLocalIceCandidateStats::RTCLocalIceCandidateStats(std::string id, + int64_t timestamp_us) + : RTCLocalIceCandidateStats(std::move(id), + Timestamp::Micros(timestamp_us)) {} + +std::unique_ptr RTCLocalIceCandidateStats::copy() const { + return std::make_unique(*this); +} + +const char* RTCLocalIceCandidateStats::type() const { + return kType; +} + +const char RTCRemoteIceCandidateStats::kType[] = "remote-candidate"; + +RTCRemoteIceCandidateStats::RTCRemoteIceCandidateStats(std::string id, + Timestamp timestamp) + : RTCIceCandidateStats(std::move(id), timestamp, true) {} +RTCRemoteIceCandidateStats::RTCRemoteIceCandidateStats(std::string id, + int64_t timestamp_us) + : RTCRemoteIceCandidateStats(std::move(id), + Timestamp::Micros(timestamp_us)) {} + +std::unique_ptr RTCRemoteIceCandidateStats::copy() const { + return std::make_unique(*this); +} + +const char* RTCRemoteIceCandidateStats::type() const { + return kType; +} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(DEPRECATED_RTCMediaStreamStats, RTCStats, "stream", + &stream_identifier, + &track_ids) +// clang-format on + +DEPRECATED_RTCMediaStreamStats::DEPRECATED_RTCMediaStreamStats( + std::string id, + Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + stream_identifier("streamIdentifier"), + track_ids("trackIds") {} +DEPRECATED_RTCMediaStreamStats::DEPRECATED_RTCMediaStreamStats( + std::string id, + int64_t timestamp_us) + : DEPRECATED_RTCMediaStreamStats(std::move(id), + Timestamp::Micros(timestamp_us)) {} + +DEPRECATED_RTCMediaStreamStats::DEPRECATED_RTCMediaStreamStats( + const DEPRECATED_RTCMediaStreamStats& other) = default; + +DEPRECATED_RTCMediaStreamStats::~DEPRECATED_RTCMediaStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(DEPRECATED_RTCMediaStreamTrackStats, RTCStats, "track", + &track_identifier, + &media_source_id, + &remote_source, + &ended, + &detached, + &kind, + &jitter_buffer_delay, + &jitter_buffer_emitted_count, + &frame_width, + &frame_height, + &frames_sent, + &huge_frames_sent, + &frames_received, + &frames_decoded, + &frames_dropped, + &audio_level, + &total_audio_energy, + &echo_return_loss, + &echo_return_loss_enhancement, + &total_samples_received, + &total_samples_duration, + &concealed_samples, + &silent_concealed_samples, + &concealment_events, + &inserted_samples_for_deceleration, + &removed_samples_for_acceleration) +// clang-format on + +DEPRECATED_RTCMediaStreamTrackStats::DEPRECATED_RTCMediaStreamTrackStats( + std::string id, + Timestamp timestamp, + const char* kind) + : RTCStats(std::move(id), timestamp), + track_identifier("trackIdentifier"), + media_source_id("mediaSourceId"), + remote_source("remoteSource"), + ended("ended"), + detached("detached"), + kind("kind", kind), + jitter_buffer_delay("jitterBufferDelay"), + jitter_buffer_emitted_count("jitterBufferEmittedCount"), + frame_width("frameWidth"), + frame_height("frameHeight"), + frames_sent("framesSent"), + huge_frames_sent("hugeFramesSent"), + frames_received("framesReceived"), + frames_decoded("framesDecoded"), + frames_dropped("framesDropped"), + audio_level("audioLevel"), + total_audio_energy("totalAudioEnergy"), + echo_return_loss("echoReturnLoss"), + echo_return_loss_enhancement("echoReturnLossEnhancement"), + total_samples_received("totalSamplesReceived"), + total_samples_duration("totalSamplesDuration"), + concealed_samples("concealedSamples"), + silent_concealed_samples("silentConcealedSamples"), + concealment_events("concealmentEvents"), + inserted_samples_for_deceleration("insertedSamplesForDeceleration"), + removed_samples_for_acceleration("removedSamplesForAcceleration") { + RTC_DCHECK(kind == RTCMediaStreamTrackKind::kAudio || + kind == RTCMediaStreamTrackKind::kVideo); +} +DEPRECATED_RTCMediaStreamTrackStats::DEPRECATED_RTCMediaStreamTrackStats( + std::string id, + int64_t timestamp_us, + const char* kind) + : DEPRECATED_RTCMediaStreamTrackStats(std::move(id), + Timestamp::Micros(timestamp_us), + kind) {} + +DEPRECATED_RTCMediaStreamTrackStats::DEPRECATED_RTCMediaStreamTrackStats( + const DEPRECATED_RTCMediaStreamTrackStats& other) = default; + +DEPRECATED_RTCMediaStreamTrackStats::~DEPRECATED_RTCMediaStreamTrackStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCPeerConnectionStats, RTCStats, "peer-connection", + &data_channels_opened, + &data_channels_closed) +// clang-format on + +RTCPeerConnectionStats::RTCPeerConnectionStats(std::string id, + Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + data_channels_opened("dataChannelsOpened"), + data_channels_closed("dataChannelsClosed") {} +RTCPeerConnectionStats::RTCPeerConnectionStats(std::string id, + int64_t timestamp_us) + : RTCPeerConnectionStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCPeerConnectionStats::RTCPeerConnectionStats( + const RTCPeerConnectionStats& other) = default; + +RTCPeerConnectionStats::~RTCPeerConnectionStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCRTPStreamStats, RTCStats, "rtp", + &ssrc, + &kind, + &track_id, + &transport_id, + &codec_id, + &media_type) +// clang-format on + +RTCRTPStreamStats::RTCRTPStreamStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + ssrc("ssrc"), + kind("kind"), + track_id("trackId"), + transport_id("transportId"), + codec_id("codecId"), + media_type("mediaType") {} +RTCRTPStreamStats::RTCRTPStreamStats(std::string id, int64_t timestamp_us) + : RTCRTPStreamStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCRTPStreamStats::RTCRTPStreamStats(const RTCRTPStreamStats& other) = default; + +RTCRTPStreamStats::~RTCRTPStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCReceivedRtpStreamStats, RTCRTPStreamStats, "received-rtp", + &jitter, + &packets_lost) +// clang-format on + +RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats(std::string id, + Timestamp timestamp) + : RTCRTPStreamStats(std::move(id), timestamp), + jitter("jitter"), + packets_lost("packetsLost") {} +RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats(std::string id, + int64_t timestamp_us) + : RTCReceivedRtpStreamStats(std::move(id), + Timestamp::Micros(timestamp_us)) {} + +RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats( + const RTCReceivedRtpStreamStats& other) = default; + +RTCReceivedRtpStreamStats::~RTCReceivedRtpStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCSentRtpStreamStats, RTCRTPStreamStats, "sent-rtp", + &packets_sent, + &bytes_sent) +// clang-format on + +RTCSentRtpStreamStats::RTCSentRtpStreamStats(std::string id, + Timestamp timestamp) + : RTCRTPStreamStats(std::move(id), timestamp), + packets_sent("packetsSent"), + bytes_sent("bytesSent") {} +RTCSentRtpStreamStats::RTCSentRtpStreamStats(std::string(id), + int64_t timestamp_us) + : RTCSentRtpStreamStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCSentRtpStreamStats::RTCSentRtpStreamStats( + const RTCSentRtpStreamStats& other) = default; + +RTCSentRtpStreamStats::~RTCSentRtpStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCInboundRTPStreamStats, RTCReceivedRtpStreamStats, "inbound-rtp", + &track_identifier, + &mid, + &remote_id, + &packets_received, + &packets_discarded, + &fec_packets_received, + &fec_packets_discarded, + &bytes_received, + &header_bytes_received, + &last_packet_received_timestamp, + &jitter_buffer_delay, + &jitter_buffer_target_delay, + &jitter_buffer_minimum_delay, + &jitter_buffer_emitted_count, + &total_samples_received, + &concealed_samples, + &silent_concealed_samples, + &concealment_events, + &inserted_samples_for_deceleration, + &removed_samples_for_acceleration, + &audio_level, + &total_audio_energy, + &total_samples_duration, + &playout_id, + &frames_received, + &frame_width, + &frame_height, + &frames_per_second, + &frames_decoded, + &key_frames_decoded, + &frames_dropped, + &total_decode_time, + &total_processing_delay, + &total_assembly_time, + &frames_assembled_from_multiple_packets, + &total_inter_frame_delay, + &total_squared_inter_frame_delay, + &pause_count, + &total_pauses_duration, + &freeze_count, + &total_freezes_duration, + &content_type, + &estimated_playout_timestamp, + &decoder_implementation, + &fir_count, + &pli_count, + &nack_count, + &qp_sum, + &goog_timing_frame_info, + &power_efficient_decoder, + &jitter_buffer_flushes, + &delayed_packet_outage_samples, + &relative_packet_arrival_delay, + &interruption_count, + &total_interruption_duration, + &min_playout_delay) +// clang-format on + +RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string id, + Timestamp timestamp) + : RTCReceivedRtpStreamStats(std::move(id), timestamp), + playout_id("playoutId"), + track_identifier("trackIdentifier"), + mid("mid"), + remote_id("remoteId"), + packets_received("packetsReceived"), + packets_discarded("packetsDiscarded"), + fec_packets_received("fecPacketsReceived"), + fec_packets_discarded("fecPacketsDiscarded"), + bytes_received("bytesReceived"), + header_bytes_received("headerBytesReceived"), + last_packet_received_timestamp("lastPacketReceivedTimestamp"), + jitter_buffer_delay("jitterBufferDelay"), + jitter_buffer_target_delay("jitterBufferTargetDelay"), + jitter_buffer_minimum_delay("jitterBufferMinimumDelay"), + jitter_buffer_emitted_count("jitterBufferEmittedCount"), + total_samples_received("totalSamplesReceived"), + concealed_samples("concealedSamples"), + silent_concealed_samples("silentConcealedSamples"), + concealment_events("concealmentEvents"), + inserted_samples_for_deceleration("insertedSamplesForDeceleration"), + removed_samples_for_acceleration("removedSamplesForAcceleration"), + audio_level("audioLevel"), + total_audio_energy("totalAudioEnergy"), + total_samples_duration("totalSamplesDuration"), + frames_received("framesReceived"), + frame_width("frameWidth"), + frame_height("frameHeight"), + frames_per_second("framesPerSecond"), + frames_decoded("framesDecoded"), + key_frames_decoded("keyFramesDecoded"), + frames_dropped("framesDropped"), + total_decode_time("totalDecodeTime"), + total_processing_delay("totalProcessingDelay"), + total_assembly_time("totalAssemblyTime"), + frames_assembled_from_multiple_packets( + "framesAssembledFromMultiplePackets"), + total_inter_frame_delay("totalInterFrameDelay"), + total_squared_inter_frame_delay("totalSquaredInterFrameDelay"), + pause_count("pauseCount"), + total_pauses_duration("totalPausesDuration"), + freeze_count("freezeCount"), + total_freezes_duration("totalFreezesDuration"), + content_type("contentType"), + estimated_playout_timestamp("estimatedPlayoutTimestamp"), + decoder_implementation("decoderImplementation"), + fir_count("firCount"), + pli_count("pliCount"), + nack_count("nackCount"), + qp_sum("qpSum"), + goog_timing_frame_info("googTimingFrameInfo"), + power_efficient_decoder("powerEfficientDecoder"), + jitter_buffer_flushes( + "jitterBufferFlushes", + {NonStandardGroupId::kRtcAudioJitterBufferMaxPackets}), + delayed_packet_outage_samples( + "delayedPacketOutageSamples", + {NonStandardGroupId::kRtcAudioJitterBufferMaxPackets, + NonStandardGroupId::kRtcStatsRelativePacketArrivalDelay}), + relative_packet_arrival_delay( + "relativePacketArrivalDelay", + {NonStandardGroupId::kRtcStatsRelativePacketArrivalDelay}), + interruption_count("interruptionCount"), + total_interruption_duration("totalInterruptionDuration"), + min_playout_delay("minPlayoutDelay") {} +RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string id, + int64_t timestamp_us) + : RTCInboundRTPStreamStats(std::move(id), Timestamp::Micros(timestamp_us)) { +} + +RTCInboundRTPStreamStats::RTCInboundRTPStreamStats( + const RTCInboundRTPStreamStats& other) = default; +RTCInboundRTPStreamStats::~RTCInboundRTPStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCOutboundRTPStreamStats, RTCRTPStreamStats, "outbound-rtp", + &media_source_id, + &remote_id, + &mid, + &rid, + &packets_sent, + &retransmitted_packets_sent, + &bytes_sent, + &header_bytes_sent, + &retransmitted_bytes_sent, + &target_bitrate, + &frames_encoded, + &key_frames_encoded, + &total_encode_time, + &total_encoded_bytes_target, + &frame_width, + &frame_height, + &frames_per_second, + &frames_sent, + &huge_frames_sent, + &total_packet_send_delay, + &quality_limitation_reason, + &quality_limitation_durations, + &quality_limitation_resolution_changes, + &content_type, + &encoder_implementation, + &fir_count, + &pli_count, + &nack_count, + &qp_sum, + &active, + &power_efficient_encoder, + &scalability_mode) +// clang-format on + +RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(std::string id, + Timestamp timestamp) + : RTCRTPStreamStats(std::move(id), timestamp), + media_source_id("mediaSourceId"), + remote_id("remoteId"), + mid("mid"), + rid("rid"), + packets_sent("packetsSent"), + retransmitted_packets_sent("retransmittedPacketsSent"), + bytes_sent("bytesSent"), + header_bytes_sent("headerBytesSent"), + retransmitted_bytes_sent("retransmittedBytesSent"), + target_bitrate("targetBitrate"), + frames_encoded("framesEncoded"), + key_frames_encoded("keyFramesEncoded"), + total_encode_time("totalEncodeTime"), + total_encoded_bytes_target("totalEncodedBytesTarget"), + frame_width("frameWidth"), + frame_height("frameHeight"), + frames_per_second("framesPerSecond"), + frames_sent("framesSent"), + huge_frames_sent("hugeFramesSent"), + total_packet_send_delay("totalPacketSendDelay"), + quality_limitation_reason("qualityLimitationReason"), + quality_limitation_durations("qualityLimitationDurations"), + quality_limitation_resolution_changes( + "qualityLimitationResolutionChanges"), + content_type("contentType"), + encoder_implementation("encoderImplementation"), + fir_count("firCount"), + pli_count("pliCount"), + nack_count("nackCount"), + qp_sum("qpSum"), + active("active"), + power_efficient_encoder("powerEfficientEncoder"), + scalability_mode("scalabilityMode") {} +RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(std::string id, + int64_t timestamp_us) + : RTCOutboundRTPStreamStats(std::move(id), + Timestamp::Micros(timestamp_us)) {} + +RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats( + const RTCOutboundRTPStreamStats& other) = default; + +RTCOutboundRTPStreamStats::~RTCOutboundRTPStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCRemoteInboundRtpStreamStats, RTCReceivedRtpStreamStats, + "remote-inbound-rtp", + &local_id, + &round_trip_time, + &fraction_lost, + &total_round_trip_time, + &round_trip_time_measurements) +// clang-format on + +RTCRemoteInboundRtpStreamStats::RTCRemoteInboundRtpStreamStats( + std::string id, + Timestamp timestamp) + : RTCReceivedRtpStreamStats(std::move(id), timestamp), + local_id("localId"), + round_trip_time("roundTripTime"), + fraction_lost("fractionLost"), + total_round_trip_time("totalRoundTripTime"), + round_trip_time_measurements("roundTripTimeMeasurements") {} +RTCRemoteInboundRtpStreamStats::RTCRemoteInboundRtpStreamStats( + std::string id, + int64_t timestamp_us) + : RTCRemoteInboundRtpStreamStats(std::move(id), + Timestamp::Micros(timestamp_us)) {} + +RTCRemoteInboundRtpStreamStats::RTCRemoteInboundRtpStreamStats( + const RTCRemoteInboundRtpStreamStats& other) = default; + +RTCRemoteInboundRtpStreamStats::~RTCRemoteInboundRtpStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCRemoteOutboundRtpStreamStats, RTCSentRtpStreamStats, + "remote-outbound-rtp", + &local_id, + &remote_timestamp, + &reports_sent, + &round_trip_time, + &round_trip_time_measurements, + &total_round_trip_time) +// clang-format on + +RTCRemoteOutboundRtpStreamStats::RTCRemoteOutboundRtpStreamStats( + std::string id, + Timestamp timestamp) + : RTCSentRtpStreamStats(std::move(id), timestamp), + local_id("localId"), + remote_timestamp("remoteTimestamp"), + reports_sent("reportsSent"), + round_trip_time("roundTripTime"), + round_trip_time_measurements("roundTripTimeMeasurements"), + total_round_trip_time("totalRoundTripTime") {} +RTCRemoteOutboundRtpStreamStats::RTCRemoteOutboundRtpStreamStats( + std::string id, + int64_t timestamp) + : RTCRemoteOutboundRtpStreamStats(std::move(id), + Timestamp::Micros(timestamp)) {} + +RTCRemoteOutboundRtpStreamStats::RTCRemoteOutboundRtpStreamStats( + const RTCRemoteOutboundRtpStreamStats& other) = default; + +RTCRemoteOutboundRtpStreamStats::~RTCRemoteOutboundRtpStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCMediaSourceStats, RTCStats, "parent-media-source", + &track_identifier, + &kind) +// clang-format on + +RTCMediaSourceStats::RTCMediaSourceStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + track_identifier("trackIdentifier"), + kind("kind") {} +RTCMediaSourceStats::RTCMediaSourceStats(std::string id, int64_t timestamp_us) + : RTCMediaSourceStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCMediaSourceStats::RTCMediaSourceStats(const RTCMediaSourceStats& other) = + default; + +RTCMediaSourceStats::~RTCMediaSourceStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCAudioSourceStats, RTCMediaSourceStats, "media-source", + &audio_level, + &total_audio_energy, + &total_samples_duration, + &echo_return_loss, + &echo_return_loss_enhancement) +// clang-format on + +RTCAudioSourceStats::RTCAudioSourceStats(std::string id, Timestamp timestamp) + : RTCMediaSourceStats(std::move(id), timestamp), + audio_level("audioLevel"), + total_audio_energy("totalAudioEnergy"), + total_samples_duration("totalSamplesDuration"), + echo_return_loss("echoReturnLoss"), + echo_return_loss_enhancement("echoReturnLossEnhancement") {} +RTCAudioSourceStats::RTCAudioSourceStats(std::string id, int64_t timestamp_us) + : RTCAudioSourceStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCAudioSourceStats::RTCAudioSourceStats(const RTCAudioSourceStats& other) = + default; + +RTCAudioSourceStats::~RTCAudioSourceStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCVideoSourceStats, RTCMediaSourceStats, "media-source", + &width, + &height, + &frames, + &frames_per_second) +// clang-format on + +RTCVideoSourceStats::RTCVideoSourceStats(std::string id, Timestamp timestamp) + : RTCMediaSourceStats(std::move(id), timestamp), + width("width"), + height("height"), + frames("frames"), + frames_per_second("framesPerSecond") {} +RTCVideoSourceStats::RTCVideoSourceStats(std::string id, int64_t timestamp_us) + : RTCVideoSourceStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCVideoSourceStats::RTCVideoSourceStats(const RTCVideoSourceStats& other) = + default; + +RTCVideoSourceStats::~RTCVideoSourceStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCTransportStats, RTCStats, "transport", + &bytes_sent, + &packets_sent, + &bytes_received, + &packets_received, + &rtcp_transport_stats_id, + &dtls_state, + &selected_candidate_pair_id, + &local_certificate_id, + &remote_certificate_id, + &tls_version, + &dtls_cipher, + &dtls_role, + &srtp_cipher, + &selected_candidate_pair_changes, + &ice_role, + &ice_local_username_fragment, + &ice_state) +// clang-format on + +RTCTransportStats::RTCTransportStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + bytes_sent("bytesSent"), + packets_sent("packetsSent"), + bytes_received("bytesReceived"), + packets_received("packetsReceived"), + rtcp_transport_stats_id("rtcpTransportStatsId"), + dtls_state("dtlsState"), + selected_candidate_pair_id("selectedCandidatePairId"), + local_certificate_id("localCertificateId"), + remote_certificate_id("remoteCertificateId"), + tls_version("tlsVersion"), + dtls_cipher("dtlsCipher"), + dtls_role("dtlsRole"), + srtp_cipher("srtpCipher"), + selected_candidate_pair_changes("selectedCandidatePairChanges"), + ice_role("iceRole"), + ice_local_username_fragment("iceLocalUsernameFragment"), + ice_state("iceState") {} +RTCTransportStats::RTCTransportStats(std::string id, int64_t timestamp_us) + : RTCTransportStats(std::move(id), Timestamp::Micros(timestamp_us)) {} + +RTCTransportStats::RTCTransportStats(const RTCTransportStats& other) = default; + +RTCTransportStats::~RTCTransportStats() {} + +RTCAudioPlayoutStats::RTCAudioPlayoutStats(const std::string& id, + Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + kind("kind", "audio"), + synthesized_samples_duration("synthesizedSamplesDuration"), + synthesized_samples_events("synthesizedSamplesEvents"), + total_samples_duration("totalSamplesDuration"), + total_playout_delay("totalPlayoutDelay"), + total_samples_count("totalSamplesCount") {} + +RTCAudioPlayoutStats::RTCAudioPlayoutStats(const RTCAudioPlayoutStats& other) = + default; + +RTCAudioPlayoutStats::~RTCAudioPlayoutStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCAudioPlayoutStats, RTCStats, "media-playout", + &kind, + &synthesized_samples_duration, + &synthesized_samples_events, + &total_samples_duration, + &total_playout_delay, + &total_samples_count) +// clang-format on + +} // namespace webrtc diff --git a/third_party/libwebrtc/stats/test/rtc_test_stats.cc b/third_party/libwebrtc/stats/test/rtc_test_stats.cc new file mode 100644 index 0000000000..30d5ce0d85 --- /dev/null +++ b/third_party/libwebrtc/stats/test/rtc_test_stats.cc @@ -0,0 +1,80 @@ +/* + * Copyright 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "stats/test/rtc_test_stats.h" + +#include "rtc_base/checks.h" + +namespace webrtc { + +WEBRTC_RTCSTATS_IMPL(RTCTestStats, + RTCStats, + "test-stats", + &m_bool, + &m_int32, + &m_uint32, + &m_int64, + &m_uint64, + &m_double, + &m_string, + &m_sequence_bool, + &m_sequence_int32, + &m_sequence_uint32, + &m_sequence_int64, + &m_sequence_uint64, + &m_sequence_double, + &m_sequence_string, + &m_map_string_uint64, + &m_map_string_double) + +RTCTestStats::RTCTestStats(const std::string& id, Timestamp timestamp) + : RTCStats(id, timestamp), + m_bool("mBool"), + m_int32("mInt32"), + m_uint32("mUint32"), + m_int64("mInt64"), + m_uint64("mUint64"), + m_double("mDouble"), + m_string("mString"), + m_sequence_bool("mSequenceBool"), + m_sequence_int32("mSequenceInt32"), + m_sequence_uint32("mSequenceUint32"), + m_sequence_int64("mSequenceInt64"), + m_sequence_uint64("mSequenceUint64"), + m_sequence_double("mSequenceDouble"), + m_sequence_string("mSequenceString"), + m_map_string_uint64("mMapStringUint64"), + m_map_string_double("mMapStringDouble") {} + +RTCTestStats::RTCTestStats(const std::string& id, int64_t timestamp_us) + : RTCTestStats(id, Timestamp::Micros(timestamp_us)) {} + +RTCTestStats::RTCTestStats(const RTCTestStats& other) + : RTCStats(other.id(), other.timestamp()), + m_bool(other.m_bool), + m_int32(other.m_int32), + m_uint32(other.m_uint32), + m_int64(other.m_int64), + m_uint64(other.m_uint64), + m_double(other.m_double), + m_string(other.m_string), + m_sequence_bool(other.m_sequence_bool), + m_sequence_int32(other.m_sequence_int32), + m_sequence_uint32(other.m_sequence_uint32), + m_sequence_int64(other.m_sequence_int64), + m_sequence_uint64(other.m_sequence_uint64), + m_sequence_double(other.m_sequence_double), + m_sequence_string(other.m_sequence_string), + m_map_string_uint64(other.m_map_string_uint64), + m_map_string_double(other.m_map_string_double) {} + +RTCTestStats::~RTCTestStats() {} + +} // namespace webrtc diff --git a/third_party/libwebrtc/stats/test/rtc_test_stats.h b/third_party/libwebrtc/stats/test/rtc_test_stats.h new file mode 100644 index 0000000000..082002db5f --- /dev/null +++ b/third_party/libwebrtc/stats/test/rtc_test_stats.h @@ -0,0 +1,54 @@ +/* + * Copyright 2016 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef STATS_TEST_RTC_TEST_STATS_H_ +#define STATS_TEST_RTC_TEST_STATS_H_ + +#include +#include +#include +#include + +#include "api/stats/rtc_stats.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +class RTC_EXPORT RTCTestStats : public RTCStats { + public: + WEBRTC_RTCSTATS_DECL(); + + RTCTestStats(const std::string& id, Timestamp timestamp); + ABSL_DEPRECATED("Use constructor with Timestamp instead") + RTCTestStats(const std::string& id, int64_t timestamp_us); + RTCTestStats(const RTCTestStats& other); + ~RTCTestStats() override; + + RTCStatsMember m_bool; + RTCStatsMember m_int32; + RTCStatsMember m_uint32; + RTCStatsMember m_int64; + RTCStatsMember m_uint64; + RTCStatsMember m_double; + RTCStatsMember m_string; + RTCStatsMember> m_sequence_bool; + RTCStatsMember> m_sequence_int32; + RTCStatsMember> m_sequence_uint32; + RTCStatsMember> m_sequence_int64; + RTCStatsMember> m_sequence_uint64; + RTCStatsMember> m_sequence_double; + RTCStatsMember> m_sequence_string; + RTCStatsMember> m_map_string_uint64; + RTCStatsMember> m_map_string_double; +}; + +} // namespace webrtc + +#endif // STATS_TEST_RTC_TEST_STATS_H_ -- cgit v1.2.3