1 /* 2 * Copyright 2012 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 // This file contains a class used for gathering statistics from an ongoing 12 // libjingle PeerConnection. 13 14 #ifndef PC_LEGACY_STATS_COLLECTOR_H_ 15 #define PC_LEGACY_STATS_COLLECTOR_H_ 16 17 #include <stdint.h> 18 19 #include <algorithm> 20 #include <cstdint> 21 #include <map> 22 #include <memory> 23 #include <string> 24 #include <type_traits> 25 #include <utility> 26 #include <vector> 27 28 #include "absl/types/optional.h" 29 #include "api/field_trials_view.h" 30 #include "api/legacy_stats_types.h" 31 #include "api/media_stream_interface.h" 32 #include "api/peer_connection_interface.h" 33 #include "api/scoped_refptr.h" 34 #include "p2p/base/connection_info.h" 35 #include "p2p/base/port.h" 36 #include "pc/legacy_stats_collector_interface.h" 37 #include "pc/peer_connection_internal.h" 38 #include "pc/rtp_transceiver.h" 39 #include "pc/transport_stats.h" 40 #include "rtc_base/network_constants.h" 41 #include "rtc_base/ssl_certificate.h" 42 #include "rtc_base/thread_annotations.h" 43 44 namespace webrtc { 45 46 // Conversion function to convert candidate type string to the corresponding one 47 // from enum RTCStatsIceCandidateType. 48 const char* IceCandidateTypeToStatsType(const std::string& candidate_type); 49 50 // Conversion function to convert adapter type to report string which are more 51 // fitting to the general style of http://w3c.github.io/webrtc-stats. This is 52 // only used by stats collector. 53 const char* AdapterTypeToStatsType(rtc::AdapterType type); 54 55 // A mapping between track ids and their StatsReport. 56 typedef std::map<std::string, StatsReport*> TrackIdMap; 57 58 class LegacyStatsCollector : public LegacyStatsCollectorInterface { 59 public: 60 // The caller is responsible for ensuring that the pc outlives the 61 // LegacyStatsCollector instance. 62 explicit LegacyStatsCollector(PeerConnectionInternal* pc); 63 virtual ~LegacyStatsCollector(); 64 65 // Adds a MediaStream with tracks that can be used as a `selector` in a call 66 // to GetStats. 67 void AddStream(MediaStreamInterface* stream); 68 void AddTrack(MediaStreamTrackInterface* track); 69 70 // Adds a local audio track that is used for getting some voice statistics. 71 void AddLocalAudioTrack(AudioTrackInterface* audio_track, 72 uint32_t ssrc) override; 73 74 // Removes a local audio tracks that is used for getting some voice 75 // statistics. 76 void RemoveLocalAudioTrack(AudioTrackInterface* audio_track, 77 uint32_t ssrc) override; 78 79 // Gather statistics from the session and store them for future use. 80 void UpdateStats(PeerConnectionInterface::StatsOutputLevel level); 81 82 // Gets a StatsReports of the last collected stats. Note that UpdateStats must 83 // be called before this function to get the most recent stats. `selector` is 84 // a track label or empty string. The most recent reports are stored in 85 // `reports`. 86 // TODO(tommi): Change this contract to accept a callback object instead 87 // of filling in `reports`. As is, there's a requirement that the caller 88 // uses `reports` immediately without allowing any async activity on 89 // the thread (message handling etc) and then discard the results. 90 void GetStats(MediaStreamTrackInterface* track, 91 StatsReports* reports) override; 92 93 // Prepare a local or remote SSRC report for the given ssrc. Used internally 94 // in the ExtractStatsFromList template. 95 StatsReport* PrepareReport(bool local, 96 uint32_t ssrc, 97 const std::string& track_id, 98 const StatsReport::Id& transport_id, 99 StatsReport::Direction direction); 100 101 StatsReport* PrepareADMReport(); 102 103 // A track is invalid if there is no report data for it. 104 bool IsValidTrack(const std::string& track_id); 105 106 // Reset the internal cache timestamp to force an update of the stats next 107 // time UpdateStats() is called. This call needs to be made on the signaling 108 // thread and should be made every time configuration changes that affect 109 // stats have been made. 110 void InvalidateCache(); 111 UseStandardBytesStats()112 bool UseStandardBytesStats() const { return use_standard_bytes_stats_; } 113 114 private: 115 friend class LegacyStatsCollectorTest; 116 117 // Struct that's populated on the network thread and carries the values to 118 // the signaling thread where the stats are added to the stats reports. 119 struct TransportStats { 120 TransportStats() = default; TransportStatsTransportStats121 TransportStats(std::string transport_name, 122 cricket::TransportStats transport_stats) 123 : name(std::move(transport_name)), stats(std::move(transport_stats)) {} 124 TransportStats(TransportStats&&) = default; 125 TransportStats(const TransportStats&) = delete; 126 127 std::string name; 128 cricket::TransportStats stats; 129 std::unique_ptr<rtc::SSLCertificateStats> local_cert_stats; 130 std::unique_ptr<rtc::SSLCertificateStats> remote_cert_stats; 131 }; 132 133 struct SessionStats { 134 SessionStats() = default; 135 SessionStats(SessionStats&&) = default; 136 SessionStats(const SessionStats&) = delete; 137 138 SessionStats& operator=(SessionStats&&) = default; 139 SessionStats& operator=(SessionStats&) = delete; 140 141 cricket::CandidateStatsList candidate_stats; 142 std::vector<TransportStats> transport_stats; 143 std::map<std::string, std::string> transport_names_by_mid; 144 }; 145 146 // Overridden in unit tests to fake timing. 147 virtual double GetTimeNow(); 148 149 bool CopySelectedReports(const std::string& selector, StatsReports* reports); 150 151 // Helper method for creating IceCandidate report. `is_local` indicates 152 // whether this candidate is local or remote. 153 StatsReport* AddCandidateReport( 154 const cricket::CandidateStats& candidate_stats, 155 bool local); 156 157 // Adds a report for this certificate and every certificate in its chain, and 158 // returns the leaf certificate's report (`cert_stats`'s report). 159 StatsReport* AddCertificateReports( 160 std::unique_ptr<rtc::SSLCertificateStats> cert_stats); 161 162 StatsReport* AddConnectionInfoReport(const std::string& content_name, 163 int component, 164 int connection_id, 165 const StatsReport::Id& channel_report_id, 166 const cricket::ConnectionInfo& info); 167 168 void ExtractDataInfo(); 169 170 // Returns the `transport_names_by_mid` member from the SessionStats as 171 // gathered and used to populate the stats. 172 std::map<std::string, std::string> ExtractSessionInfo(); 173 174 void ExtractBweInfo(); 175 void ExtractMediaInfo( 176 const std::map<std::string, std::string>& transport_names_by_mid); 177 void ExtractSenderInfo(); 178 webrtc::StatsReport* GetReport(const StatsReport::StatsType& type, 179 const std::string& id, 180 StatsReport::Direction direction); 181 182 // Helper method to get stats from the local audio tracks. 183 void UpdateStatsFromExistingLocalAudioTracks(bool has_remote_tracks); 184 void UpdateReportFromAudioTrack(AudioTrackInterface* track, 185 StatsReport* report, 186 bool has_remote_tracks); 187 188 // Helper method to update the timestamp of track records. 189 void UpdateTrackReports(); 190 191 SessionStats ExtractSessionInfo_n( 192 const std::vector<rtc::scoped_refptr< 193 RtpTransceiverProxyWithInternal<RtpTransceiver>>>& transceivers, 194 absl::optional<std::string> sctp_transport_name, 195 absl::optional<std::string> sctp_mid); 196 void ExtractSessionInfo_s(SessionStats& session_stats); 197 198 // A collection for all of our stats reports. 199 StatsCollection reports_; 200 TrackIdMap track_ids_; 201 // Raw pointer to the peer connection the statistics are gathered from. 202 PeerConnectionInternal* const pc_; 203 int64_t cache_timestamp_ms_ RTC_GUARDED_BY(pc_->signaling_thread()) = 0; 204 double stats_gathering_started_; 205 const bool use_standard_bytes_stats_; 206 207 // TODO(tommi): We appear to be holding on to raw pointers to reference 208 // counted objects? We should be using scoped_refptr here. 209 typedef std::vector<std::pair<AudioTrackInterface*, uint32_t>> 210 LocalAudioTrackVector; 211 LocalAudioTrackVector local_audio_tracks_; 212 }; 213 214 } // namespace webrtc 215 216 #endif // PC_LEGACY_STATS_COLLECTOR_H_ 217