diff options
Diffstat (limited to 'third_party/libwebrtc/stats')
-rw-r--r-- | third_party/libwebrtc/stats/BUILD.gn | 76 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/DEPS | 3 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/OWNERS | 2 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/g3doc/stats.md | 18 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/rtc_stats.cc | 297 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/rtc_stats_report.cc | 132 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/rtc_stats_report_unittest.cc | 169 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/rtc_stats_unittest.cc | 518 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/rtcstats_objects.cc | 696 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/test/rtc_test_stats.cc | 77 | ||||
-rw-r--r-- | third_party/libwebrtc/stats/test/rtc_test_stats.h | 52 |
11 files changed, 2040 insertions, 0 deletions
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 @@ +<!-- go/cmark -->
+<!--* freshness: {owner: 'hta' reviewed: '2022-10-01'} *-->
+
+# 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..25bde289c2 --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats.cc @@ -0,0 +1,297 @@ +/* + * 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 <cstdio> + +#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 <typename T> +std::string VectorToString(const std::vector<T>& 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<bool> range loops don't +// return references but objects, causing -Wrange-loop-analysis diagnostics. +std::string VectorToString(const std::vector<bool>& 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 <typename T> +std::string VectorOfStringsToString(const std::vector<T>& strings) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (const T& element : strings) { + sb << separator << "\"" << rtc::ToString(element) << "\""; + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +template <typename T> +std::string MapToString(const std::map<std::string, T>& 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 <typename T> +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<double>(value)); + RTC_DCHECK_LE(len, arraysize(buf)); + return std::string(&buf[0], len); +} + +template <typename T> +std::string VectorToStringAsDouble(const std::vector<T>& vector) { + rtc::StringBuilder sb; + sb << "["; + const char* separator = ""; + for (const T& element : vector) { + sb << separator << ToStringAsDouble<T>(element); + separator = ","; + } + sb << "]"; + return sb.Release(); +} + +template <typename T> +std::string MapToStringAsDouble(const std::map<std::string, T>& 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<const RTCStatsMemberInterface*> members = Members(); + std::vector<const RTCStatsMemberInterface*> 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<const RTCStatsMemberInterface*> RTCStats::Members() const { + return MembersOfThisObjectAndAncestors(0); +} + +std::vector<const RTCStatsMemberInterface*> +RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const { + std::vector<const RTCStatsMemberInterface*> 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<T>::StaticType() { \ + return type; \ + } \ + template <> \ + bool RTCStatsMember<T>::is_sequence() const { \ + return is_seq; \ + } \ + template <> \ + bool RTCStatsMember<T>::is_string() const { \ + return is_str; \ + } \ + template <> \ + std::string RTCStatsMember<T>::ValueToString() const { \ + RTC_DCHECK(value_.has_value()); \ + return to_str; \ + } \ + template <> \ + std::string RTCStatsMember<T>::ValueToJson() const { \ + RTC_DCHECK(value_.has_value()); \ + return to_json; \ + } \ + template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember<T> + +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<bool>, + kSequenceBool, + true, + false, + VectorToString(*value_), + VectorToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int32_t>, + kSequenceInt32, + true, + false, + VectorToString(*value_), + VectorToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint32_t>, + kSequenceUint32, + true, + false, + VectorToString(*value_), + VectorToString(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<int64_t>, + kSequenceInt64, + true, + false, + VectorToString(*value_), + VectorToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<uint64_t>, + kSequenceUint64, + true, + false, + VectorToString(*value_), + VectorToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<double>, + kSequenceDouble, + true, + false, + VectorToString(*value_), + VectorToStringAsDouble(*value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector<std::string>, + 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_)); + +} // 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..404549135b --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats_report.cc @@ -0,0 +1,132 @@ +/* + * 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 <type_traits> +#include <utility> + +#include "rtc_base/checks.h" +#include "rtc_base/strings/string_builder.h" + +namespace webrtc { + +RTCStatsReport::ConstIterator::ConstIterator( + const rtc::scoped_refptr<const RTCStatsReport>& 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> RTCStatsReport::Create(Timestamp timestamp) { + return rtc::scoped_refptr<RTCStatsReport>(new RTCStatsReport(timestamp)); +} + +RTCStatsReport::RTCStatsReport(Timestamp timestamp) : timestamp_(timestamp) {} + +rtc::scoped_refptr<RTCStatsReport> RTCStatsReport::Copy() const { + rtc::scoped_refptr<RTCStatsReport> 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<const RTCStats> 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<const RTCStats> RTCStatsReport::Take(const std::string& id) { + StatsMap::iterator it = stats_.find(id); + if (it == stats_.end()) + return nullptr; + std::unique_ptr<const RTCStats> stats = std::move(it->second); + stats_.erase(it); + return stats; +} + +void RTCStatsReport::TakeMembersFrom(rtc::scoped_refptr<RTCStatsReport> other) { + for (StatsMap::iterator it = other->stats_.begin(); it != other->stats_.end(); + ++it) { + AddStats(std::unique_ptr<const RTCStats>(it->second.release())); + } + other->stats_.clear(); +} + +RTCStatsReport::ConstIterator RTCStatsReport::begin() const { + return ConstIterator(rtc::scoped_refptr<const RTCStatsReport>(this), + stats_.cbegin()); +} + +RTCStatsReport::ConstIterator RTCStatsReport::end() const { + return ConstIterator(rtc::scoped_refptr<const RTCStatsReport>(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..ded0c27609 --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats_report_unittest.cc @@ -0,0 +1,169 @@ +/* + * 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<int32_t> 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<double> 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<std::string> string; +}; + +WEBRTC_RTCSTATS_IMPL(RTCTestStats3, RTCStats, "test-stats-3", &string) + +TEST(RTCStatsReport, AddAndGetStats) { + rtc::scoped_refptr<RTCStatsReport> report = + RTCStatsReport::Create(Timestamp::Micros(1337)); + EXPECT_EQ(report->timestamp().us_or(-1), 1337u); + EXPECT_EQ(report->size(), static_cast<size_t>(0)); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("a0", Timestamp::Micros(1)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("a1", Timestamp::Micros(2)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats2("b0", Timestamp::Micros(4)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats2("b1", Timestamp::Micros(8)))); + report->AddStats(std::unique_ptr<RTCStats>( + new RTCTestStats1("a2", Timestamp::Micros(16)))); + report->AddStats(std::unique_ptr<RTCStats>( + new RTCTestStats2("b2", Timestamp::Micros(32)))); + EXPECT_EQ(report->size(), static_cast<size_t>(6)); + + EXPECT_EQ(report->Get("missing"), nullptr); + EXPECT_EQ(report->Get("a0")->id(), "a0"); + EXPECT_EQ(report->Get("b2")->id(), "b2"); + + std::vector<const RTCTestStats1*> a = report->GetStatsOfType<RTCTestStats1>(); + EXPECT_EQ(a.size(), static_cast<size_t>(3)); + int64_t mask = 0; + for (const RTCTestStats1* stats : a) + mask |= stats->timestamp().us(); + EXPECT_EQ(mask, static_cast<int64_t>(1 | 2 | 16)); + + std::vector<const RTCTestStats2*> b = report->GetStatsOfType<RTCTestStats2>(); + EXPECT_EQ(b.size(), static_cast<size_t>(3)); + mask = 0; + for (const RTCTestStats2* stats : b) + mask |= stats->timestamp().us(); + EXPECT_EQ(mask, static_cast<int64_t>(4 | 8 | 32)); + + EXPECT_EQ(report->GetStatsOfType<RTCTestStats3>().size(), + static_cast<size_t>(0)); +} + +TEST(RTCStatsReport, StatsOrder) { + rtc::scoped_refptr<RTCStatsReport> 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<RTCStats>(new RTCTestStats1("C", Timestamp::Micros(2)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("D", Timestamp::Micros(3)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats2("B", Timestamp::Micros(1)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats2("A", Timestamp::Micros(0)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats2("E", Timestamp::Micros(4)))); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats2("F", Timestamp::Micros(5)))); + report->AddStats( + std::unique_ptr<RTCStats>(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<int64_t>(7)); +} + +TEST(RTCStatsReport, Take) { + rtc::scoped_refptr<RTCStatsReport> report = + RTCStatsReport::Create(Timestamp::Zero()); + report->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("A", Timestamp::Micros(1)))); + report->AddStats( + std::unique_ptr<RTCStats>(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<RTCStatsReport> a = + RTCStatsReport::Create(Timestamp::Micros(1337)); + EXPECT_EQ(a->timestamp().us_or(-1), 1337u); + a->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("B", Timestamp::Micros(1)))); + a->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("C", Timestamp::Micros(2)))); + a->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("E", Timestamp::Micros(4)))); + rtc::scoped_refptr<RTCStatsReport> b = + RTCStatsReport::Create(Timestamp::Micros(1338)); + EXPECT_EQ(b->timestamp().us_or(-1), 1338u); + b->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("A", Timestamp::Micros(0)))); + b->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("D", Timestamp::Micros(3)))); + b->AddStats( + std::unique_ptr<RTCStats>(new RTCTestStats1("F", Timestamp::Micros(5)))); + + a->TakeMembersFrom(b); + EXPECT_EQ(b->size(), static_cast<size_t>(0)); + int64_t i = 0; + for (const RTCStats& stats : *a) { + EXPECT_EQ(stats.timestamp().us(), i); + ++i; + } + EXPECT_EQ(i, static_cast<int64_t>(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..249491effd --- /dev/null +++ b/third_party/libwebrtc/stats/rtc_stats_unittest.cc @@ -0,0 +1,518 @@ +/* + * 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 <cmath> +#include <cstdint> +#include <cstring> +#include <iostream> + +#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<int32_t> 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<int32_t> 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<int64_t>(42)); + std::vector<const RTCStatsMemberInterface*> members = stats.Members(); + EXPECT_EQ(members.size(), static_cast<size_t>(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<bool> sequence_bool; + sequence_bool.push_back(true); + std::vector<int32_t> sequence_int32; + sequence_int32.push_back(static_cast<int32_t>(1)); + std::vector<uint32_t> sequence_uint32; + sequence_uint32.push_back(static_cast<uint32_t>(2)); + std::vector<int64_t> sequence_int64; + sequence_int64.push_back(static_cast<int64_t>(3)); + std::vector<uint64_t> sequence_uint64; + sequence_uint64.push_back(static_cast<uint64_t>(4)); + std::vector<double> sequence_double; + sequence_double.push_back(5.0); + std::vector<std::string> sequence_string; + sequence_string.push_back(std::string("six")); + + std::map<std::string, uint64_t> map_string_uint64{{"seven", 8}}; + std::map<std::string, double> 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<int32_t>(123)); + EXPECT_EQ(*stats.m_uint32, static_cast<uint32_t>(123)); + EXPECT_EQ(*stats.m_int64, static_cast<int64_t>(123)); + EXPECT_EQ(*stats.m_uint64, static_cast<uint64_t>(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<int32_t> 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<bool>(); + stats_with_all_values.m_sequence_int32 = std::vector<int32_t>(); + stats_with_all_values.m_sequence_uint32 = std::vector<uint32_t>(); + stats_with_all_values.m_sequence_int64 = std::vector<int64_t>(); + stats_with_all_values.m_sequence_uint64 = std::vector<uint64_t>(); + stats_with_all_values.m_sequence_double = std::vector<double>(); + stats_with_all_values.m_sequence_string = std::vector<std::string>(); + stats_with_all_values.m_map_string_uint64 = std::map<std::string, uint64_t>(); + stats_with_all_values.m_map_string_double = std::map<std::string, double>(); + 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<const RTCStatsMember<int32_t>>(); + } + EXPECT_EQ(sum, static_cast<int32_t>(3)); + + std::unique_ptr<RTCStats> copy_ptr = stats.copy(); + const RTCGrandChildStats& copy = copy_ptr->cast_to<RTCGrandChildStats>(); + 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<bool> sequence_bool; + std::vector<int32_t> sequence_int32; + sequence_int32.push_back(static_cast<int32_t>(1)); + std::vector<int64_t> sequence_int64; + sequence_int64.push_back(static_cast<int64_t>(-1234567890123456499L)); + sequence_int64.push_back(static_cast<int64_t>(1)); + sequence_int64.push_back(static_cast<int64_t>(1234567890123456499L)); + std::vector<double> sequence_double; + sequence_double.push_back(123.4567890123456499); + sequence_double.push_back(1234567890123.456499); + std::vector<std::string> sequence_string; + sequence_string.push_back(std::string("four")); + + std::map<std::string, uint64_t> map_string_uint64{ + {"long", static_cast<uint64_t>(1234567890123456499L)}}; + std::map<std::string, double> 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::CharReader> 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<double> 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<double>(*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<double>((*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<double>((*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, 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<std::string, uint64_t>(); + 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<std::string, double>(); + 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()); +} + +// 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<RTCChildStats>(), ""); +} + +#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..77feaf87ba --- /dev/null +++ b/third_party/libwebrtc/stats/rtcstats_objects.cc @@ -0,0 +1,696 @@ +/* + * 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 <utility> + +#include "api/stats/rtc_stats.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +// 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(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(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(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( + 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(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) {} + +std::unique_ptr<RTCStats> RTCLocalIceCandidateStats::copy() const { + return std::make_unique<RTCLocalIceCandidateStats>(*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) {} + +std::unique_ptr<RTCStats> RTCRemoteIceCandidateStats::copy() const { + return std::make_unique<RTCRemoteIceCandidateStats>(*this); +} + +const char* RTCRemoteIceCandidateStats::type() const { + return kType; +} + +// 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( + const RTCPeerConnectionStats& other) = default; + +RTCPeerConnectionStats::~RTCPeerConnectionStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL(RTCRtpStreamStats, RTCStats, "rtp", + &ssrc, + &kind, + &transport_id, + &codec_id) +// clang-format on + +RTCRtpStreamStats::RTCRtpStreamStats(std::string id, Timestamp timestamp) + : RTCStats(std::move(id), timestamp), + ssrc("ssrc"), + kind("kind"), + transport_id("transportId"), + codec_id("codecId") {} + +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( + 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( + 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_bytes_received, + &fec_packets_discarded, + &fec_ssrc, + &bytes_received, + &header_bytes_received, + &retransmitted_packets_received, + &retransmitted_bytes_received, + &rtx_ssrc, + &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_bytes_received("fecBytesReceived"), + fec_packets_discarded("fecPacketsDiscarded"), + fec_ssrc("fecSsrc"), + bytes_received("bytesReceived"), + header_bytes_received("headerBytesReceived"), + retransmitted_packets_received("retransmittedPacketsReceived"), + retransmitted_bytes_received("retransmittedBytesReceived"), + rtx_ssrc("rtxSsrc"), + 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"), + delayed_packet_outage_samples("delayedPacketOutageSamples"), + relative_packet_arrival_delay("relativePacketArrivalDelay"), + interruption_count("interruptionCount"), + total_interruption_duration("totalInterruptionDuration"), + min_playout_delay("minPlayoutDelay") {} + +RTCInboundRtpStreamStats::RTCInboundRtpStreamStats( + const RTCInboundRtpStreamStats& other) = default; +RTCInboundRtpStreamStats::~RTCInboundRtpStreamStats() {} + +// clang-format off +WEBRTC_RTCSTATS_IMPL( + RTCOutboundRtpStreamStats, RTCSentRtpStreamStats, "outbound-rtp", + &media_source_id, + &remote_id, + &mid, + &rid, + &retransmitted_packets_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, + &rtx_ssrc) +// clang-format on + +RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(std::string id, + Timestamp timestamp) + : RTCSentRtpStreamStats(std::move(id), timestamp), + media_source_id("mediaSourceId"), + remote_id("remoteId"), + mid("mid"), + rid("rid"), + retransmitted_packets_sent("retransmittedPacketsSent"), + 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"), + rtx_ssrc("rtxSsrc") {} + +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( + 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( + 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(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(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(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(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..a83fa24178 --- /dev/null +++ b/third_party/libwebrtc/stats/test/rtc_test_stats.cc @@ -0,0 +1,77 @@ +/* + * 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 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..0247c0cc01 --- /dev/null +++ b/third_party/libwebrtc/stats/test/rtc_test_stats.h @@ -0,0 +1,52 @@ +/* + * 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 <cstdint> +#include <map> +#include <string> +#include <vector> + +#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); + RTCTestStats(const RTCTestStats& other); + ~RTCTestStats() override; + + RTCStatsMember<bool> m_bool; + RTCStatsMember<int32_t> m_int32; + RTCStatsMember<uint32_t> m_uint32; + RTCStatsMember<int64_t> m_int64; + RTCStatsMember<uint64_t> m_uint64; + RTCStatsMember<double> m_double; + RTCStatsMember<std::string> m_string; + RTCStatsMember<std::vector<bool>> m_sequence_bool; + RTCStatsMember<std::vector<int32_t>> m_sequence_int32; + RTCStatsMember<std::vector<uint32_t>> m_sequence_uint32; + RTCStatsMember<std::vector<int64_t>> m_sequence_int64; + RTCStatsMember<std::vector<uint64_t>> m_sequence_uint64; + RTCStatsMember<std::vector<double>> m_sequence_double; + RTCStatsMember<std::vector<std::string>> m_sequence_string; + RTCStatsMember<std::map<std::string, uint64_t>> m_map_string_uint64; + RTCStatsMember<std::map<std::string, double>> m_map_string_double; +}; + +} // namespace webrtc + +#endif // STATS_TEST_RTC_TEST_STATS_H_ |