PeerConnection[Interface]::GetStats(RTCStatsCollectorCallback*) added.
New file structure and targets:
rtc_stats_api
webrtc/api/stats/rtcstats.h
webrtc/api/stats/rtcstats_objects.h
webrtc/api/stats/rtcstatsreport.h
rtc_stats (dep on rtc_stats_api)
webrtc/stats/rtcstats.cc
webrtc/stats/rtcstats_objects.cc
webrtc/stats/rtcstatsreport.cc
libjingle_peerconnection (dep on rtc_stats)
webrtc/api/rtcstatscollector.cc
webrtc/api/rtcstatscollector.h
Placing rtc_stats_api headers in this separate target instead of
libjingle_peerconnection avoids a circular dependency
libjingle_peerconnection -> rtc_stats -> libjingle_peerconnection
Code changes:
PeerConnectionInterface::GetStats(RTCStatsCollectorCallback*) added for
the new stats collection API. Implemented by PeerConnection.
BUG=chromium:627816
Review-Url: https://codereview.webrtc.org/2331373004
Cr-Commit-Position: refs/heads/master@{#14246}
diff --git a/.gn b/.gn
index 65bc7dd..db61a47 100644
--- a/.gn
+++ b/.gn
@@ -20,18 +20,20 @@
# "gn check" or "gn gen --check".
# TODO(kjellander): Keep adding paths to this list as work in webrtc:5589 is done.
check_targets = [
+ "//webrtc/api:rtc_stats_api",
"//webrtc/modules/audio_coding:g711_test",
"//webrtc/modules/audio_coding:g722_test",
+ "//webrtc/modules/audio_coding:ilbc_test",
+ "//webrtc/modules/audio_coding:isac",
+ "//webrtc/modules/audio_coding:isac_api_test",
"//webrtc/modules/audio_coding:isac_fix_test",
+ "//webrtc/modules/audio_coding:isac_switch_samprate_test",
"//webrtc/modules/audio_coding:isac_test",
"//webrtc/modules/audio_coding:webrtc_opus_fec_test",
"//webrtc/modules/audio_device/*",
"//webrtc/modules/audio_mixer/*",
+ "//webrtc/stats:rtc_stats",
"//webrtc/voice_engine:level_indicator",
- "//webrtc/modules/audio_coding:ilbc_test",
- "//webrtc/modules/audio_coding:isac",
- "//webrtc/modules/audio_coding:isac_api_test",
- "//webrtc/modules/audio_coding:isac_switch_samprate_test",
]
# These are the list of GN files that run exec_script. This whitelist exists
diff --git a/webrtc/api/BUILD.gn b/webrtc/api/BUILD.gn
index 4f15bc4..b7cd679 100644
--- a/webrtc/api/BUILD.gn
+++ b/webrtc/api/BUILD.gn
@@ -84,9 +84,8 @@
"proxy.h",
"remoteaudiosource.cc",
"remoteaudiosource.h",
- "rtcstats.h",
- "rtcstats_objects.h",
- "rtcstatsreport.h",
+ "rtcstatscollector.cc",
+ "rtcstatscollector.h",
"rtpparameters.h",
"rtpreceiver.cc",
"rtpreceiver.h",
@@ -125,9 +124,11 @@
deps = [
":call_api",
+ ":rtc_stats_api",
"../call",
"../media",
"../pc",
+ "../stats",
]
if (rtc_use_quic) {
@@ -298,6 +299,20 @@
}
}
+# GYP version: webrtc/api/api.gyp:rtc_stats_api
+rtc_source_set("rtc_stats_api") {
+ cflags = []
+ sources = [
+ "stats/rtcstats.h",
+ "stats/rtcstats_objects.h",
+ "stats/rtcstatsreport.h",
+ ]
+
+ deps = [
+ "../base:rtc_base_approved",
+ ]
+}
+
if (rtc_include_tests) {
config("peerconnection_unittests_config") {
# The warnings below are enabled by default. Since GN orders compiler flags
@@ -336,6 +351,7 @@
"peerconnectionfactory_unittest.cc",
"peerconnectioninterface_unittest.cc",
"proxy_unittest.cc",
+ "rtcstatscollector_unittest.cc",
"rtpsenderreceiver_unittest.cc",
"statscollector_unittest.cc",
"test/fakeaudiocapturemodule.cc",
diff --git a/webrtc/api/api.gyp b/webrtc/api/api.gyp
index 5b14fdf..d017cda 100644
--- a/webrtc/api/api.gyp
+++ b/webrtc/api/api.gyp
@@ -115,8 +115,10 @@
'type': 'static_library',
'dependencies': [
':call_api',
+ ':rtc_stats_api',
'<(webrtc_root)/media/media.gyp:rtc_media',
'<(webrtc_root)/pc/pc.gyp:rtc_pc',
+ '<(webrtc_root)/stats/stats.gyp:rtc_stats',
],
'sources': [
'audiotrack.cc',
@@ -157,9 +159,8 @@
'proxy.h',
'remoteaudiosource.cc',
'remoteaudiosource.h',
- 'rtcstats.h',
- 'rtcstats_objects.h',
- 'rtcstatsreport.h',
+ 'rtcstatscollector.cc',
+ 'rtcstatscollector.h',
'rtpparameters.h',
'rtpreceiver.cc',
'rtpreceiver.h',
@@ -217,5 +218,18 @@
}],
],
}, # target libjingle_peerconnection
+ {
+ # GN version: webrtc/api:rtc_stats_api
+ 'target_name': 'rtc_stats_api',
+ 'type': 'static_library',
+ 'dependencies': [
+ '<(webrtc_root)/base/base.gyp:rtc_base_approved',
+ ],
+ 'sources': [
+ 'stats/rtcstats.h',
+ 'stats/rtcstats_objects.h',
+ 'stats/rtcstatsreport.h',
+ ],
+ }, # target rtc_stats_api
], # targets
}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index bdd33d7..144b1c6 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -632,6 +632,7 @@
configuration.redetermine_role_on_ice_restart))));
stats_.reset(new StatsCollector(this));
+ stats_collector_ = RTCStatsCollector::Create(this);
enable_ice_renomination_ = configuration.enable_ice_renomination;
@@ -888,6 +889,11 @@
return true;
}
+void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
+ RTC_DCHECK(stats_collector_);
+ stats_collector_->GetStatsReport(callback);
+}
+
PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
return signaling_state_;
}
diff --git a/webrtc/api/peerconnection.h b/webrtc/api/peerconnection.h
index 042e7f1..3087160 100644
--- a/webrtc/api/peerconnection.h
+++ b/webrtc/api/peerconnection.h
@@ -18,6 +18,7 @@
#include "webrtc/api/peerconnectionfactory.h"
#include "webrtc/api/peerconnectioninterface.h"
+#include "webrtc/api/rtcstatscollector.h"
#include "webrtc/api/rtpreceiver.h"
#include "webrtc/api/rtpsender.h"
#include "webrtc/api/statscollector.h"
@@ -102,6 +103,7 @@
bool GetStats(StatsObserver* observer,
webrtc::MediaStreamTrackInterface* track,
StatsOutputLevel level) override;
+ void GetStats(RTCStatsCollectorCallback* callback) override;
SignalingState signaling_state() override;
@@ -427,6 +429,7 @@
std::unique_ptr<WebRtcSession> session_;
std::unique_ptr<StatsCollector> stats_;
+ rtc::scoped_refptr<RTCStatsCollector> stats_collector_;
};
} // namespace webrtc
diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h
index f5d8c63..a04e53e 100644
--- a/webrtc/api/peerconnectioninterface.h
+++ b/webrtc/api/peerconnectioninterface.h
@@ -60,6 +60,7 @@
#include "webrtc/api/dtmfsenderinterface.h"
#include "webrtc/api/jsep.h"
#include "webrtc/api/mediastreaminterface.h"
+#include "webrtc/api/rtcstatscollector.h"
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/api/rtpsenderinterface.h"
#include "webrtc/api/statstypes.h"
@@ -440,6 +441,12 @@
virtual bool GetStats(StatsObserver* observer,
MediaStreamTrackInterface* track,
StatsOutputLevel level) = 0;
+ // Gets stats using the new stats collection API, see webrtc/api/stats/. These
+ // will replace old stats collection API when the new API has matured enough.
+ // TODO(hbos): Default implementation that does nothing only exists as to not
+ // break third party projects. As soon as they have been updated this should
+ // be changed to "= 0;".
+ virtual void GetStats(RTCStatsCollectorCallback* callback) {}
virtual rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
const std::string& label,
diff --git a/webrtc/api/peerconnectionproxy.h b/webrtc/api/peerconnectionproxy.h
index 37f2e89..8c15b3d 100644
--- a/webrtc/api/peerconnectionproxy.h
+++ b/webrtc/api/peerconnectionproxy.h
@@ -42,6 +42,7 @@
PROXY_METHOD3(bool, GetStats, StatsObserver*,
MediaStreamTrackInterface*,
StatsOutputLevel)
+ PROXY_METHOD1(void, GetStats, RTCStatsCollectorCallback*)
PROXY_METHOD2(rtc::scoped_refptr<DataChannelInterface>,
CreateDataChannel, const std::string&, const DataChannelInit*)
PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, local_description)
diff --git a/webrtc/api/rtcstats.h b/webrtc/api/rtcstats.h
index e2cbf29..55aeb1d 100644
--- a/webrtc/api/rtcstats.h
+++ b/webrtc/api/rtcstats.h
@@ -8,274 +8,6 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_API_RTCSTATS_H_
-#define WEBRTC_API_RTCSTATS_H_
+// TODO(hbos): Remove this file once Chromium uses the correct include path.
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "webrtc/base/checks.h"
-
-namespace webrtc {
-
-class RTCStatsMemberInterface;
-
-// Abstract base class for RTCStats-derived dictionaries, see
-// https://w3c.github.io/webrtc-stats/.
-//
-// All derived classes must have the following static variable defined:
-// static const char kType[];
-// It is used as a unique class identifier and a string representation of the
-// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
-// Use the |WEBRTC_RTCSTATS_IMPL| macro when implementing subclasses, see macro
-// for details.
-//
-// Derived classes list their dictionary members, RTCStatsMember<T>, as public
-// fields, allowing the following:
-//
-// RTCFooStats foo("fooId", GetCurrentTime());
-// foo.bar = 42;
-// foo.baz = std::vector<std::string>();
-// foo.baz->push_back("hello world");
-// uint32_t x = *foo.bar;
-//
-// Pointers to all the members are available with |Members|, allowing iteration:
-//
-// for (const RTCStatsMemberInterface* member : foo.Members()) {
-// printf("%s = %s\n", member->name(), member->ValueToString().c_str());
-// }
-class RTCStats {
- public:
- RTCStats(const std::string& id, int64_t timestamp_us)
- : id_(id), timestamp_us_(timestamp_us) {}
- RTCStats(std::string&& id, int64_t timestamp_us)
- : id_(std::move(id)), timestamp_us_(timestamp_us) {}
- virtual ~RTCStats() {}
-
- virtual std::unique_ptr<RTCStats> copy() const = 0;
-
- const std::string& id() const { return id_; }
- // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
- int64_t timestamp_us() const { return timestamp_us_; }
- // Returns the static member variable |kType| of the implementing class.
- virtual const char* type() const = 0;
- // Returns a vector of pointers to all the RTCStatsMemberInterface members of
- // this class. This allows for iteration of members.
- std::vector<const RTCStatsMemberInterface*> Members() const;
-
- // Creates a human readable string representation of the report, listing all
- // of its members (names and values).
- std::string ToString() const;
-
- // Downcasts the stats object to an |RTCStats| subclass |T|. DCHECKs that the
- // object is of type |T|.
- template<typename T>
- const T& cast_to() const {
- RTC_DCHECK_EQ(type(), T::kType);
- return static_cast<const T&>(*this);
- }
-
- protected:
- // Gets a vector of all members of this |RTCStats| object, including members
- // derived from parent classes. |additional_capacity| is how many more members
- // shall be reserved in the vector (so that subclasses can allocate a vector
- // with room for both parent and child members without it having to resize).
- virtual std::vector<const RTCStatsMemberInterface*>
- MembersOfThisObjectAndAncestors(
- size_t additional_capacity) const;
-
- std::string const id_;
- int64_t timestamp_us_;
-};
-
-// All |RTCStats| classes should use this macro in a public section of the class
-// definition.
-//
-// This macro declares the static |kType| and overrides methods as required by
-// subclasses of |RTCStats|: |copy|, |type|, and
-// |MembersOfThisObjectAndAncestors|. The |...| argument is a list of addresses
-// to each member defined in the implementing class (list cannot be empty, must
-// have at least one new member).
-//
-// (Since class names need to be known to implement these methods this cannot be
-// part of the base |RTCStats|. While these methods could be implemented using
-// templates, that would only work for immediate subclasses. Subclasses of
-// subclasses also have to override these methods, resulting in boilerplate
-// code. Using a macro avoids this and works for any |RTCStats| class, including
-// grandchildren.)
-//
-// Sample usage:
-//
-// rtcfoostats.h:
-// class RTCFooStats : public RTCStats {
-// public:
-// RTCFooStats(const std::string& id, int64_t timestamp_us)
-// : RTCStats(id, timestamp_us),
-// foo("foo"),
-// bar("bar") {
-// }
-//
-// WEBRTC_RTCSTATS_IMPL(RTCStats, RTCFooStats,
-// &foo,
-// &bar);
-//
-// RTCStatsMember<int32_t> foo;
-// RTCStatsMember<int32_t> bar;
-// };
-//
-// rtcfoostats.cc:
-// const char RTCFooStats::kType[] = "foo-stats";
-//
-#define WEBRTC_RTCSTATS_IMPL(parent_class, this_class, ...) \
- public: \
- static const char kType[]; \
- std::unique_ptr<webrtc::RTCStats> copy() const override { \
- return std::unique_ptr<webrtc::RTCStats>(new this_class(*this)); \
- } \
- const char* type() const override { return this_class::kType; } \
- protected: \
- std::vector<const webrtc::RTCStatsMemberInterface*> \
- MembersOfThisObjectAndAncestors( \
- size_t local_var_additional_capacity) const override { \
- const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
- __VA_ARGS__ \
- }; \
- size_t local_var_members_count = \
- sizeof(local_var_members) / sizeof(local_var_members[0]); \
- std::vector<const webrtc::RTCStatsMemberInterface*> local_var_members_vec =\
- parent_class::MembersOfThisObjectAndAncestors( \
- local_var_members_count + local_var_additional_capacity); \
- RTC_DCHECK_GE( \
- local_var_members_vec.capacity() - local_var_members_vec.size(), \
- local_var_members_count + local_var_additional_capacity); \
- local_var_members_vec.insert(local_var_members_vec.end(), \
- &local_var_members[0], \
- &local_var_members[local_var_members_count]); \
- return local_var_members_vec; \
- } \
- public:
-
-// Interface for |RTCStats| members, which have a name and a value of a type
-// defined in a subclass. Only the types listed in |Type| are supported, these
-// are implemented by |RTCStatsMember<T>|. The value of a member may be
-// undefined, the value can only be read if |is_defined|.
-class RTCStatsMemberInterface {
- public:
- // Member value types.
- enum Type {
- kInt32, // int32_t
- kUint32, // uint32_t
- kInt64, // int64_t
- kUint64, // uint64_t
- kDouble, // double
- kString, // std::string
-
- kSequenceInt32, // std::vector<int32_t>
- kSequenceUint32, // std::vector<uint32_t>
- kSequenceInt64, // std::vector<int64_t>
- kSequenceUint64, // std::vector<uint64_t>
- kSequenceDouble, // std::vector<double>
- kSequenceString, // std::vector<std::string>
- };
-
- virtual ~RTCStatsMemberInterface() {}
-
- const char* name() const { return name_; }
- virtual Type type() const = 0;
- virtual bool is_sequence() const = 0;
- virtual bool is_string() const = 0;
- bool is_defined() const { return is_defined_; }
- virtual std::string ValueToString() const = 0;
-
- template<typename T>
- const T& cast_to() const {
- RTC_DCHECK_EQ(type(), T::kType);
- return static_cast<const T&>(*this);
- }
-
- protected:
- RTCStatsMemberInterface(const char* name, bool is_defined)
- : name_(name), is_defined_(is_defined) {}
-
- const char* const name_;
- bool is_defined_;
-};
-
-// Template implementation of |RTCStatsMemberInterface|. Every possible |T| is
-// specialized in rtcstats.cc, using a different |T| results in a linker error
-// (undefined reference to |kType|). The supported types are the ones described
-// by |RTCStatsMemberInterface::Type|.
-template<typename T>
-class RTCStatsMember : public RTCStatsMemberInterface {
- public:
- static const Type kType;
-
- explicit RTCStatsMember(const char* name)
- : RTCStatsMemberInterface(name, false),
- value_() {}
- RTCStatsMember(const char* name, const T& value)
- : RTCStatsMemberInterface(name, true),
- value_(value) {}
- RTCStatsMember(const char* name, T&& value)
- : RTCStatsMemberInterface(name, true),
- value_(std::move(value)) {}
- explicit RTCStatsMember(const RTCStatsMember<T>& other)
- : RTCStatsMemberInterface(other.name_, other.is_defined_),
- value_(other.value_) {}
- explicit RTCStatsMember(RTCStatsMember<T>&& other)
- : RTCStatsMemberInterface(other.name_, other.is_defined_),
- value_(std::move(other.value_)) {}
-
- Type type() const override { return kType; }
- bool is_sequence() const override;
- bool is_string() const override;
- std::string ValueToString() const override;
-
- // Assignment operators.
- T& operator=(const T& value) {
- value_ = value;
- is_defined_ = true;
- return value_;
- }
- T& operator=(const T&& value) {
- value_ = std::move(value);
- is_defined_ = true;
- return value_;
- }
- T& operator=(const RTCStatsMember<T>& other) {
- RTC_DCHECK(other.is_defined_);
- value_ = other.is_defined_;
- is_defined_ = true;
- return value_;
- }
-
- // Value getters.
- T& operator*() {
- RTC_DCHECK(is_defined_);
- return value_;
- }
- const T& operator*() const {
- RTC_DCHECK(is_defined_);
- return value_;
- }
-
- // Value getters, arrow operator.
- T* operator->() {
- RTC_DCHECK(is_defined_);
- return &value_;
- }
- const T* operator->() const {
- RTC_DCHECK(is_defined_);
- return &value_;
- }
-
- private:
- T value_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_API_RTCSTATS_H_
+#include "webrtc/api/stats/rtcstats.h"
diff --git a/webrtc/stats/rtcstatscollector.cc b/webrtc/api/rtcstatscollector.cc
similarity index 98%
rename from webrtc/stats/rtcstatscollector.cc
rename to webrtc/api/rtcstatscollector.cc
index 3ff4155..d2938a4 100644
--- a/webrtc/stats/rtcstatscollector.cc
+++ b/webrtc/api/rtcstatscollector.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/stats/rtcstatscollector.h"
+#include "webrtc/api/rtcstatscollector.h"
#include <memory>
#include <utility>
diff --git a/webrtc/stats/rtcstatscollector.h b/webrtc/api/rtcstatscollector.h
similarity index 93%
rename from webrtc/stats/rtcstatscollector.h
rename to webrtc/api/rtcstatscollector.h
index ee59a10..61edc52 100644
--- a/webrtc/stats/rtcstatscollector.h
+++ b/webrtc/api/rtcstatscollector.h
@@ -8,14 +8,14 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_STATS_RTCSTATSCOLLECTOR_H_
-#define WEBRTC_STATS_RTCSTATSCOLLECTOR_H_
+#ifndef WEBRTC_API_RTCSTATSCOLLECTOR_H_
+#define WEBRTC_API_RTCSTATSCOLLECTOR_H_
#include <memory>
#include <vector>
-#include "webrtc/api/rtcstats_objects.h"
-#include "webrtc/api/rtcstatsreport.h"
+#include "webrtc/api/stats/rtcstats_objects.h"
+#include "webrtc/api/stats/rtcstatsreport.h"
#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
@@ -94,4 +94,4 @@
} // namespace webrtc
-#endif // WEBRTC_STATS_RTCSTATSCOLLECTOR_H_
+#endif // WEBRTC_API_RTCSTATSCOLLECTOR_H_
diff --git a/webrtc/stats/rtcstatscollector_unittest.cc b/webrtc/api/rtcstatscollector_unittest.cc
similarity index 98%
rename from webrtc/stats/rtcstatscollector_unittest.cc
rename to webrtc/api/rtcstatscollector_unittest.cc
index a90c334..446990c 100644
--- a/webrtc/stats/rtcstatscollector_unittest.cc
+++ b/webrtc/api/rtcstatscollector_unittest.cc
@@ -8,15 +8,15 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/stats/rtcstatscollector.h"
+#include "webrtc/api/rtcstatscollector.h"
#include <memory>
#include <string>
#include <vector>
#include "webrtc/api/jsepsessiondescription.h"
-#include "webrtc/api/rtcstats_objects.h"
-#include "webrtc/api/rtcstatsreport.h"
+#include "webrtc/api/stats/rtcstats_objects.h"
+#include "webrtc/api/stats/rtcstatsreport.h"
#include "webrtc/api/test/mock_datachannel.h"
#include "webrtc/api/test/mock_peerconnection.h"
#include "webrtc/api/test/mock_webrtcsession.h"
diff --git a/webrtc/api/rtcstatsreport.h b/webrtc/api/rtcstatsreport.h
index fbd78b9..b16a53b 100644
--- a/webrtc/api/rtcstatsreport.h
+++ b/webrtc/api/rtcstatsreport.h
@@ -8,83 +8,6 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_API_RTCSTATSREPORT_H_
-#define WEBRTC_API_RTCSTATSREPORT_H_
+// TODO(hbos): Remove this file once Chromium uses the correct include path.
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "webrtc/api/rtcstats.h"
-#include "webrtc/base/refcount.h"
-#include "webrtc/base/scoped_ref_ptr.h"
-
-namespace webrtc {
-
-// A collection of stats.
-// This is accessible as a map from |RTCStats::id| to |RTCStats|.
-class RTCStatsReport : public rtc::RefCountInterface {
- public:
- typedef std::map<std::string, std::unique_ptr<const RTCStats>> StatsMap;
-
- class ConstIterator {
- public:
- ConstIterator(const ConstIterator&& other);
- ~ConstIterator();
-
- ConstIterator& operator++();
- ConstIterator& operator++(int);
- const RTCStats& operator*() const;
- bool operator==(const ConstIterator& other) const;
- bool operator!=(const ConstIterator& other) const;
-
- private:
- friend class RTCStatsReport;
- ConstIterator(const rtc::scoped_refptr<const RTCStatsReport>& report,
- StatsMap::const_iterator it);
-
- // Reference report to make sure it is kept alive.
- rtc::scoped_refptr<const RTCStatsReport> report_;
- StatsMap::const_iterator it_;
- };
-
- static rtc::scoped_refptr<RTCStatsReport> Create();
-
- RTCStatsReport();
- RTCStatsReport(const RTCStatsReport& other) = delete;
-
- bool AddStats(std::unique_ptr<const RTCStats> stats);
- const RTCStats* Get(const std::string& id) const;
- size_t size() const { return stats_.size(); }
-
- // Takes ownership of all the stats in |victim|, leaving it empty.
- void TakeMembersFrom(rtc::scoped_refptr<RTCStatsReport> victim);
-
- // Stats iterators. Stats are ordered lexicographically on |RTCStats::id|.
- ConstIterator begin() const;
- ConstIterator end() const;
-
- // Gets the subset of stats that are of type |T|, where |T| is any class
- // descending from |RTCStats|.
- template<typename T>
- std::vector<const T*> GetStatsOfType() const {
- std::vector<const T*> stats_of_type;
- for (const RTCStats& stats : *this) {
- if (stats.type() == T::kType)
- stats_of_type.push_back(&stats.cast_to<const T>());
- }
- return stats_of_type;
- }
-
- friend class rtc::RefCountedObject<RTCStatsReport>;
-
- private:
- ~RTCStatsReport() override;
-
- StatsMap stats_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_API_RTCSTATSREPORT_H_
+#include "webrtc/api/stats/rtcstatsreport.h"
diff --git a/webrtc/api/stats/rtcstats.h b/webrtc/api/stats/rtcstats.h
new file mode 100644
index 0000000..01dd1c3
--- /dev/null
+++ b/webrtc/api/stats/rtcstats.h
@@ -0,0 +1,281 @@
+/*
+ * 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 WEBRTC_API_STATS_RTCSTATS_H_
+#define WEBRTC_API_STATS_RTCSTATS_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "webrtc/base/checks.h"
+
+namespace webrtc {
+
+class RTCStatsMemberInterface;
+
+// Abstract base class for RTCStats-derived dictionaries, see
+// https://w3c.github.io/webrtc-stats/.
+//
+// All derived classes must have the following static variable defined:
+// static const char kType[];
+// It is used as a unique class identifier and a string representation of the
+// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
+// Use the |WEBRTC_RTCSTATS_IMPL| macro when implementing subclasses, see macro
+// for details.
+//
+// Derived classes list their dictionary members, RTCStatsMember<T>, as public
+// fields, allowing the following:
+//
+// RTCFooStats foo("fooId", GetCurrentTime());
+// foo.bar = 42;
+// foo.baz = std::vector<std::string>();
+// foo.baz->push_back("hello world");
+// uint32_t x = *foo.bar;
+//
+// Pointers to all the members are available with |Members|, allowing iteration:
+//
+// for (const RTCStatsMemberInterface* member : foo.Members()) {
+// printf("%s = %s\n", member->name(), member->ValueToString().c_str());
+// }
+class RTCStats {
+ public:
+ RTCStats(const std::string& id, int64_t timestamp_us)
+ : id_(id), timestamp_us_(timestamp_us) {}
+ RTCStats(std::string&& id, int64_t timestamp_us)
+ : id_(std::move(id)), timestamp_us_(timestamp_us) {}
+ virtual ~RTCStats() {}
+
+ virtual std::unique_ptr<RTCStats> copy() const = 0;
+
+ const std::string& id() const { return id_; }
+ // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
+ int64_t timestamp_us() const { return timestamp_us_; }
+ // Returns the static member variable |kType| of the implementing class.
+ virtual const char* type() const = 0;
+ // Returns a vector of pointers to all the RTCStatsMemberInterface members of
+ // this class. This allows for iteration of members.
+ std::vector<const RTCStatsMemberInterface*> Members() const;
+
+ // Creates a human readable string representation of the report, listing all
+ // of its members (names and values).
+ std::string ToString() const;
+
+ // Downcasts the stats object to an |RTCStats| subclass |T|. DCHECKs that the
+ // object is of type |T|.
+ template<typename T>
+ const T& cast_to() const {
+ RTC_DCHECK_EQ(type(), T::kType);
+ return static_cast<const T&>(*this);
+ }
+
+ protected:
+ // Gets a vector of all members of this |RTCStats| object, including members
+ // derived from parent classes. |additional_capacity| is how many more members
+ // shall be reserved in the vector (so that subclasses can allocate a vector
+ // with room for both parent and child members without it having to resize).
+ virtual std::vector<const RTCStatsMemberInterface*>
+ MembersOfThisObjectAndAncestors(
+ size_t additional_capacity) const;
+
+ std::string const id_;
+ int64_t timestamp_us_;
+};
+
+// All |RTCStats| classes should use this macro in a public section of the class
+// definition.
+//
+// This macro declares the static |kType| and overrides methods as required by
+// subclasses of |RTCStats|: |copy|, |type|, and
+// |MembersOfThisObjectAndAncestors|. The |...| argument is a list of addresses
+// to each member defined in the implementing class (list cannot be empty, must
+// have at least one new member).
+//
+// (Since class names need to be known to implement these methods this cannot be
+// part of the base |RTCStats|. While these methods could be implemented using
+// templates, that would only work for immediate subclasses. Subclasses of
+// subclasses also have to override these methods, resulting in boilerplate
+// code. Using a macro avoids this and works for any |RTCStats| class, including
+// grandchildren.)
+//
+// Sample usage:
+//
+// rtcfoostats.h:
+// class RTCFooStats : public RTCStats {
+// public:
+// RTCFooStats(const std::string& id, int64_t timestamp_us)
+// : RTCStats(id, timestamp_us),
+// foo("foo"),
+// bar("bar") {
+// }
+//
+// WEBRTC_RTCSTATS_IMPL(RTCStats, RTCFooStats,
+// &foo,
+// &bar);
+//
+// RTCStatsMember<int32_t> foo;
+// RTCStatsMember<int32_t> bar;
+// };
+//
+// rtcfoostats.cc:
+// const char RTCFooStats::kType[] = "foo-stats";
+//
+#define WEBRTC_RTCSTATS_IMPL(parent_class, this_class, ...) \
+ public: \
+ static const char kType[]; \
+ std::unique_ptr<webrtc::RTCStats> copy() const override { \
+ return std::unique_ptr<webrtc::RTCStats>(new this_class(*this)); \
+ } \
+ const char* type() const override { return this_class::kType; } \
+ protected: \
+ std::vector<const webrtc::RTCStatsMemberInterface*> \
+ MembersOfThisObjectAndAncestors( \
+ size_t local_var_additional_capacity) const override { \
+ const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
+ __VA_ARGS__ \
+ }; \
+ size_t local_var_members_count = \
+ sizeof(local_var_members) / sizeof(local_var_members[0]); \
+ std::vector<const webrtc::RTCStatsMemberInterface*> local_var_members_vec =\
+ parent_class::MembersOfThisObjectAndAncestors( \
+ local_var_members_count + local_var_additional_capacity); \
+ RTC_DCHECK_GE( \
+ local_var_members_vec.capacity() - local_var_members_vec.size(), \
+ local_var_members_count + local_var_additional_capacity); \
+ local_var_members_vec.insert(local_var_members_vec.end(), \
+ &local_var_members[0], \
+ &local_var_members[local_var_members_count]); \
+ return local_var_members_vec; \
+ } \
+ public:
+
+// Interface for |RTCStats| members, which have a name and a value of a type
+// defined in a subclass. Only the types listed in |Type| are supported, these
+// are implemented by |RTCStatsMember<T>|. The value of a member may be
+// undefined, the value can only be read if |is_defined|.
+class RTCStatsMemberInterface {
+ public:
+ // Member value types.
+ enum Type {
+ kInt32, // int32_t
+ kUint32, // uint32_t
+ kInt64, // int64_t
+ kUint64, // uint64_t
+ kDouble, // double
+ kString, // std::string
+
+ kSequenceInt32, // std::vector<int32_t>
+ kSequenceUint32, // std::vector<uint32_t>
+ kSequenceInt64, // std::vector<int64_t>
+ kSequenceUint64, // std::vector<uint64_t>
+ kSequenceDouble, // std::vector<double>
+ kSequenceString, // std::vector<std::string>
+ };
+
+ virtual ~RTCStatsMemberInterface() {}
+
+ const char* name() const { return name_; }
+ virtual Type type() const = 0;
+ virtual bool is_sequence() const = 0;
+ virtual bool is_string() const = 0;
+ bool is_defined() const { return is_defined_; }
+ virtual std::string ValueToString() const = 0;
+
+ template<typename T>
+ const T& cast_to() const {
+ RTC_DCHECK_EQ(type(), T::kType);
+ return static_cast<const T&>(*this);
+ }
+
+ protected:
+ RTCStatsMemberInterface(const char* name, bool is_defined)
+ : name_(name), is_defined_(is_defined) {}
+
+ const char* const name_;
+ bool is_defined_;
+};
+
+// Template implementation of |RTCStatsMemberInterface|. Every possible |T| is
+// specialized in rtcstats.cc, using a different |T| results in a linker error
+// (undefined reference to |kType|). The supported types are the ones described
+// by |RTCStatsMemberInterface::Type|.
+template<typename T>
+class RTCStatsMember : public RTCStatsMemberInterface {
+ public:
+ static const Type kType;
+
+ explicit RTCStatsMember(const char* name)
+ : RTCStatsMemberInterface(name, false),
+ value_() {}
+ RTCStatsMember(const char* name, const T& value)
+ : RTCStatsMemberInterface(name, true),
+ value_(value) {}
+ RTCStatsMember(const char* name, T&& value)
+ : RTCStatsMemberInterface(name, true),
+ value_(std::move(value)) {}
+ explicit RTCStatsMember(const RTCStatsMember<T>& other)
+ : RTCStatsMemberInterface(other.name_, other.is_defined_),
+ value_(other.value_) {}
+ explicit RTCStatsMember(RTCStatsMember<T>&& other)
+ : RTCStatsMemberInterface(other.name_, other.is_defined_),
+ value_(std::move(other.value_)) {}
+
+ Type type() const override { return kType; }
+ bool is_sequence() const override;
+ bool is_string() const override;
+ std::string ValueToString() const override;
+
+ // Assignment operators.
+ T& operator=(const T& value) {
+ value_ = value;
+ is_defined_ = true;
+ return value_;
+ }
+ T& operator=(const T&& value) {
+ value_ = std::move(value);
+ is_defined_ = true;
+ return value_;
+ }
+ T& operator=(const RTCStatsMember<T>& other) {
+ RTC_DCHECK(other.is_defined_);
+ value_ = other.is_defined_;
+ is_defined_ = true;
+ return value_;
+ }
+
+ // Value getters.
+ T& operator*() {
+ RTC_DCHECK(is_defined_);
+ return value_;
+ }
+ const T& operator*() const {
+ RTC_DCHECK(is_defined_);
+ return value_;
+ }
+
+ // Value getters, arrow operator.
+ T* operator->() {
+ RTC_DCHECK(is_defined_);
+ return &value_;
+ }
+ const T* operator->() const {
+ RTC_DCHECK(is_defined_);
+ return &value_;
+ }
+
+ private:
+ T value_;
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_API_STATS_RTCSTATS_H_
diff --git a/webrtc/api/rtcstats_objects.h b/webrtc/api/stats/rtcstats_objects.h
similarity index 83%
rename from webrtc/api/rtcstats_objects.h
rename to webrtc/api/stats/rtcstats_objects.h
index 4bc889d..ac480a9 100644
--- a/webrtc/api/rtcstats_objects.h
+++ b/webrtc/api/stats/rtcstats_objects.h
@@ -8,12 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_API_RTCSTATS_OBJECTS_H_
-#define WEBRTC_API_RTCSTATS_OBJECTS_H_
+#ifndef WEBRTC_API_STATS_RTCSTATS_OBJECTS_H_
+#define WEBRTC_API_STATS_RTCSTATS_OBJECTS_H_
#include <string>
-#include "webrtc/api/rtcstats.h"
+#include "webrtc/api/stats/rtcstats.h"
namespace webrtc {
@@ -32,4 +32,4 @@
} // namespace webrtc
-#endif // WEBRTC_API_RTCSTATS_OBJECTS_H_
+#endif // WEBRTC_API_STATS_RTCSTATS_OBJECTS_H_
diff --git a/webrtc/api/stats/rtcstatsreport.h b/webrtc/api/stats/rtcstatsreport.h
new file mode 100644
index 0000000..beb8650
--- /dev/null
+++ b/webrtc/api/stats/rtcstatsreport.h
@@ -0,0 +1,90 @@
+/*
+ * 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 WEBRTC_API_STATS_RTCSTATSREPORT_H_
+#define WEBRTC_API_STATS_RTCSTATSREPORT_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "webrtc/api/stats/rtcstats.h"
+#include "webrtc/base/refcount.h"
+#include "webrtc/base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+// A collection of stats.
+// This is accessible as a map from |RTCStats::id| to |RTCStats|.
+class RTCStatsReport : public rtc::RefCountInterface {
+ public:
+ typedef std::map<std::string, std::unique_ptr<const RTCStats>> StatsMap;
+
+ class ConstIterator {
+ public:
+ ConstIterator(const ConstIterator&& other);
+ ~ConstIterator();
+
+ ConstIterator& operator++();
+ ConstIterator& operator++(int);
+ const RTCStats& operator*() const;
+ bool operator==(const ConstIterator& other) const;
+ bool operator!=(const ConstIterator& other) const;
+
+ private:
+ friend class RTCStatsReport;
+ ConstIterator(const rtc::scoped_refptr<const RTCStatsReport>& report,
+ StatsMap::const_iterator it);
+
+ // Reference report to make sure it is kept alive.
+ rtc::scoped_refptr<const RTCStatsReport> report_;
+ StatsMap::const_iterator it_;
+ };
+
+ static rtc::scoped_refptr<RTCStatsReport> Create();
+
+ RTCStatsReport();
+ RTCStatsReport(const RTCStatsReport& other) = delete;
+
+ bool AddStats(std::unique_ptr<const RTCStats> stats);
+ const RTCStats* Get(const std::string& id) const;
+ size_t size() const { return stats_.size(); }
+
+ // Takes ownership of all the stats in |victim|, leaving it empty.
+ void TakeMembersFrom(rtc::scoped_refptr<RTCStatsReport> victim);
+
+ // Stats iterators. Stats are ordered lexicographically on |RTCStats::id|.
+ ConstIterator begin() const;
+ ConstIterator end() const;
+
+ // Gets the subset of stats that are of type |T|, where |T| is any class
+ // descending from |RTCStats|.
+ template<typename T>
+ std::vector<const T*> GetStatsOfType() const {
+ std::vector<const T*> stats_of_type;
+ for (const RTCStats& stats : *this) {
+ if (stats.type() == T::kType)
+ stats_of_type.push_back(&stats.cast_to<const T>());
+ }
+ return stats_of_type;
+ }
+
+ friend class rtc::RefCountedObject<RTCStatsReport>;
+
+ private:
+ ~RTCStatsReport() override;
+
+ StatsMap stats_;
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_API_STATS_RTCSTATSREPORT_H_
diff --git a/webrtc/stats/BUILD.gn b/webrtc/stats/BUILD.gn
index 1b5da8d..0f13c10 100644
--- a/webrtc/stats/BUILD.gn
+++ b/webrtc/stats/BUILD.gn
@@ -20,8 +20,6 @@
sources = [
"rtcstats.cc",
"rtcstats_objects.cc",
- "rtcstatscollector.cc",
- "rtcstatscollector.h",
"rtcstatsreport.cc",
]
@@ -31,7 +29,8 @@
}
deps = [
- "../api:libjingle_peerconnection",
+ "../api:rtc_stats_api",
+ "../base:rtc_base_approved",
]
}
@@ -41,7 +40,6 @@
testonly = true
sources = [
"rtcstats_unittest.cc",
- "rtcstatscollector_unittest.cc",
"rtcstatsreport_unittest.cc",
]
diff --git a/webrtc/stats/rtcstats.cc b/webrtc/stats/rtcstats.cc
index 8fc0ebb..6b6c437 100644
--- a/webrtc/stats/rtcstats.cc
+++ b/webrtc/stats/rtcstats.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/api/rtcstats.h"
+#include "webrtc/api/stats/rtcstats.h"
#include "webrtc/base/stringencode.h"
diff --git a/webrtc/stats/rtcstats_objects.cc b/webrtc/stats/rtcstats_objects.cc
index 46962f2..c435908 100644
--- a/webrtc/stats/rtcstats_objects.cc
+++ b/webrtc/stats/rtcstats_objects.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/api/rtcstats_objects.h"
+#include "webrtc/api/stats/rtcstats_objects.h"
namespace webrtc {
diff --git a/webrtc/stats/rtcstats_unittest.cc b/webrtc/stats/rtcstats_unittest.cc
index f6de8e6..685093a 100644
--- a/webrtc/stats/rtcstats_unittest.cc
+++ b/webrtc/stats/rtcstats_unittest.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/api/rtcstats.h"
+#include "webrtc/api/stats/rtcstats.h"
#include <cstring>
diff --git a/webrtc/stats/rtcstatsreport.cc b/webrtc/stats/rtcstatsreport.cc
index 00a55f4..4be554d 100644
--- a/webrtc/stats/rtcstatsreport.cc
+++ b/webrtc/stats/rtcstatsreport.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/api/rtcstatsreport.h"
+#include "webrtc/api/stats/rtcstatsreport.h"
namespace webrtc {
diff --git a/webrtc/stats/rtcstatsreport_unittest.cc b/webrtc/stats/rtcstatsreport_unittest.cc
index 2dcb584..9a0bb1a 100644
--- a/webrtc/stats/rtcstatsreport_unittest.cc
+++ b/webrtc/stats/rtcstatsreport_unittest.cc
@@ -8,9 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/api/rtcstatsreport.h"
+#include "webrtc/api/stats/rtcstatsreport.h"
-#include "webrtc/api/rtcstats.h"
+#include "webrtc/api/stats/rtcstats.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/gunit.h"
diff --git a/webrtc/stats/stats.gyp b/webrtc/stats/stats.gyp
index 49932e8..bbeb021 100644
--- a/webrtc/stats/stats.gyp
+++ b/webrtc/stats/stats.gyp
@@ -14,13 +14,12 @@
'target_name': 'rtc_stats',
'type': 'static_library',
'dependencies': [
- '<(webrtc_root)/api/api.gyp:libjingle_peerconnection',
+ '<(webrtc_root)/api/api.gyp:rtc_stats_api',
+ '<(webrtc_root)/base/base.gyp:rtc_base_approved',
],
'sources': [
'rtcstats.cc',
'rtcstats_objects.cc',
- 'rtcstatscollector.cc',
- 'rtcstatscollector.h',
'rtcstatsreport.cc',
],
},