1 /* 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef API_STATS_RTC_STATS_REPORT_H_ 12 #define API_STATS_RTC_STATS_REPORT_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <map> 18 #include <memory> 19 #include <string> 20 #include <utility> 21 #include <vector> 22 23 #include "api/ref_counted_base.h" 24 #include "api/scoped_refptr.h" 25 #include "api/stats/rtc_stats.h" 26 #include "api/units/timestamp.h" 27 // TODO(tommi): Remove this include after fixing iwyu issue in chromium. 28 // See: third_party/blink/renderer/platform/peerconnection/rtc_stats.cc 29 #include "rtc_base/ref_counted_object.h" 30 #include "rtc_base/system/rtc_export.h" 31 32 namespace webrtc { 33 34 // A collection of stats. 35 // This is accessible as a map from `RTCStats::id` to `RTCStats`. 36 class RTC_EXPORT RTCStatsReport final 37 : public rtc::RefCountedNonVirtual<RTCStatsReport> { 38 public: 39 typedef std::map<std::string, std::unique_ptr<const RTCStats>> StatsMap; 40 41 class RTC_EXPORT ConstIterator { 42 public: 43 ConstIterator(ConstIterator&& other); 44 ~ConstIterator(); 45 46 ConstIterator& operator++(); 47 ConstIterator& operator++(int); 48 const RTCStats& operator*() const; 49 const RTCStats* operator->() const; 50 bool operator==(const ConstIterator& other) const; 51 bool operator!=(const ConstIterator& other) const; 52 53 private: 54 friend class RTCStatsReport; 55 ConstIterator(const rtc::scoped_refptr<const RTCStatsReport>& report, 56 StatsMap::const_iterator it); 57 58 // Reference report to make sure it is kept alive. 59 rtc::scoped_refptr<const RTCStatsReport> report_; 60 StatsMap::const_iterator it_; 61 }; 62 63 // TODO(bugs.webrtc.org/13756): deprecate this in favor of Timestamp. 64 // TODO(hbos): Remove "= 0" once downstream has been updated to call with a 65 // parameter. 66 static rtc::scoped_refptr<RTCStatsReport> Create(int64_t timestamp_us = 0); 67 static rtc::scoped_refptr<RTCStatsReport> Create(Timestamp timestamp); 68 69 // TODO(bugs.webrtc.org/13756): deprecate this in favor of Timestamp. 70 explicit RTCStatsReport(int64_t timestamp_us); 71 explicit RTCStatsReport(Timestamp timestamp); 72 73 RTCStatsReport(const RTCStatsReport& other) = delete; 74 rtc::scoped_refptr<RTCStatsReport> Copy() const; 75 timestamp_us()76 int64_t timestamp_us() const { return timestamp_.us_or(-1); } timestamp()77 Timestamp timestamp() const { return timestamp_; } 78 void AddStats(std::unique_ptr<const RTCStats> stats); 79 // On success, returns a non-owning pointer to `stats`. If the stats ID is not 80 // unique, `stats` is not inserted and nullptr is returned. 81 template <typename T> TryAddStats(std::unique_ptr<T> stats)82 T* TryAddStats(std::unique_ptr<T> stats) { 83 T* stats_ptr = stats.get(); 84 if (!stats_ 85 .insert(std::make_pair(std::string(stats->id()), std::move(stats))) 86 .second) { 87 return nullptr; 88 } 89 return stats_ptr; 90 } 91 const RTCStats* Get(const std::string& id) const; size()92 size_t size() const { return stats_.size(); } 93 94 // Gets the stat object of type `T` by ID, where `T` is any class descending 95 // from `RTCStats`. 96 // Returns null if there is no stats object for the given ID or it is the 97 // wrong type. 98 template <typename T> GetAs(const std::string & id)99 const T* GetAs(const std::string& id) const { 100 const RTCStats* stats = Get(id); 101 if (!stats || stats->type() != T::kType) { 102 return nullptr; 103 } 104 return &stats->cast_to<const T>(); 105 } 106 107 // Removes the stats object from the report, returning ownership of it or null 108 // if there is no object with `id`. 109 std::unique_ptr<const RTCStats> Take(const std::string& id); 110 // Takes ownership of all the stats in `other`, leaving it empty. 111 void TakeMembersFrom(rtc::scoped_refptr<RTCStatsReport> other); 112 113 // Stats iterators. Stats are ordered lexicographically on `RTCStats::id`. 114 ConstIterator begin() const; 115 ConstIterator end() const; 116 117 // Gets the subset of stats that are of type `T`, where `T` is any class 118 // descending from `RTCStats`. 119 template <typename T> GetStatsOfType()120 std::vector<const T*> GetStatsOfType() const { 121 std::vector<const T*> stats_of_type; 122 for (const RTCStats& stats : *this) { 123 if (stats.type() == T::kType) 124 stats_of_type.push_back(&stats.cast_to<const T>()); 125 } 126 return stats_of_type; 127 } 128 129 // Creates a JSON readable string representation of the report, 130 // listing all of its stats objects. 131 std::string ToJson() const; 132 133 protected: 134 friend class rtc::RefCountedNonVirtual<RTCStatsReport>; 135 ~RTCStatsReport() = default; 136 137 private: 138 Timestamp timestamp_; 139 StatsMap stats_; 140 }; 141 142 } // namespace webrtc 143 144 #endif // API_STATS_RTC_STATS_REPORT_H_ 145