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