| /* | 
 |  *  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 PC_RTCSTATSCOLLECTOR_H_ | 
 | #define PC_RTCSTATSCOLLECTOR_H_ | 
 |  | 
 | #include <map> | 
 | #include <memory> | 
 | #include <set> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | #include "absl/types/optional.h" | 
 | #include "api/stats/rtcstats_objects.h" | 
 | #include "api/stats/rtcstatscollectorcallback.h" | 
 | #include "api/stats/rtcstatsreport.h" | 
 | #include "call/call.h" | 
 | #include "media/base/mediachannel.h" | 
 | #include "pc/datachannel.h" | 
 | #include "pc/peerconnectioninternal.h" | 
 | #include "pc/trackmediainfomap.h" | 
 | #include "rtc_base/asyncinvoker.h" | 
 | #include "rtc_base/refcount.h" | 
 | #include "rtc_base/scoped_ref_ptr.h" | 
 | #include "rtc_base/sslidentity.h" | 
 | #include "rtc_base/third_party/sigslot/sigslot.h" | 
 | #include "rtc_base/timeutils.h" | 
 |  | 
 | namespace webrtc { | 
 |  | 
 | class RtpSenderInternal; | 
 | class RtpReceiverInternal; | 
 |  | 
 | // All public methods of the collector are to be called on the signaling thread. | 
 | // Stats are gathered on the signaling, worker and network threads | 
 | // asynchronously. The callback is invoked on the signaling thread. Resulting | 
 | // reports are cached for |cache_lifetime_| ms. | 
 | class RTCStatsCollector : public virtual rtc::RefCountInterface, | 
 |                           public sigslot::has_slots<> { | 
 |  public: | 
 |   static rtc::scoped_refptr<RTCStatsCollector> Create( | 
 |       PeerConnectionInternal* pc, | 
 |       int64_t cache_lifetime_us = 50 * rtc::kNumMicrosecsPerMillisec); | 
 |  | 
 |   // Gets a recent stats report. If there is a report cached that is still fresh | 
 |   // it is returned, otherwise new stats are gathered and returned. A report is | 
 |   // considered fresh for |cache_lifetime_| ms. const RTCStatsReports are safe | 
 |   // to use across multiple threads and may be destructed on any thread. | 
 |   // If the optional selector argument is used, stats are filtered according to | 
 |   // stats selection algorithm before delivery. | 
 |   // https://w3c.github.io/webrtc-pc/#dfn-stats-selection-algorithm | 
 |   void GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback> callback); | 
 |   // If |selector| is null the selection algorithm is still applied (interpreted | 
 |   // as: no RTP streams are sent by selector). The result is empty. | 
 |   void GetStatsReport(rtc::scoped_refptr<RtpSenderInternal> selector, | 
 |                       rtc::scoped_refptr<RTCStatsCollectorCallback> callback); | 
 |   // If |selector| is null the selection algorithm is still applied (interpreted | 
 |   // as: no RTP streams are received by selector). The result is empty. | 
 |   void GetStatsReport(rtc::scoped_refptr<RtpReceiverInternal> selector, | 
 |                       rtc::scoped_refptr<RTCStatsCollectorCallback> callback); | 
 |   // Clears the cache's reference to the most recent stats report. Subsequently | 
 |   // calling |GetStatsReport| guarantees fresh stats. | 
 |   void ClearCachedStatsReport(); | 
 |  | 
 |   // If there is a |GetStatsReport| requests in-flight, waits until it has been | 
 |   // completed. Must be called on the signaling thread. | 
 |   void WaitForPendingRequest(); | 
 |  | 
 |  protected: | 
 |   RTCStatsCollector(PeerConnectionInternal* pc, int64_t cache_lifetime_us); | 
 |   ~RTCStatsCollector(); | 
 |  | 
 |   // Stats gathering on a particular thread. Calls |AddPartialResults| before | 
 |   // returning. Virtual for the sake of testing. | 
 |   virtual void ProducePartialResultsOnSignalingThread(int64_t timestamp_us); | 
 |   virtual void ProducePartialResultsOnNetworkThread(int64_t timestamp_us); | 
 |  | 
 |   // Can be called on any thread. | 
 |   void AddPartialResults( | 
 |       const rtc::scoped_refptr<RTCStatsReport>& partial_report); | 
 |  | 
 |  private: | 
 |   class RequestInfo { | 
 |    public: | 
 |     enum class FilterMode { kAll, kSenderSelector, kReceiverSelector }; | 
 |  | 
 |     // Constructs with FilterMode::kAll. | 
 |     explicit RequestInfo( | 
 |         rtc::scoped_refptr<RTCStatsCollectorCallback> callback); | 
 |     // Constructs with FilterMode::kSenderSelector. The selection algorithm is | 
 |     // applied even if |selector| is null, resulting in an empty report. | 
 |     RequestInfo(rtc::scoped_refptr<RtpSenderInternal> selector, | 
 |                 rtc::scoped_refptr<RTCStatsCollectorCallback> callback); | 
 |     // Constructs with FilterMode::kReceiverSelector. The selection algorithm is | 
 |     // applied even if |selector| is null, resulting in an empty report. | 
 |     RequestInfo(rtc::scoped_refptr<RtpReceiverInternal> selector, | 
 |                 rtc::scoped_refptr<RTCStatsCollectorCallback> callback); | 
 |  | 
 |     FilterMode filter_mode() const { return filter_mode_; } | 
 |     rtc::scoped_refptr<RTCStatsCollectorCallback> callback() const { | 
 |       return callback_; | 
 |     } | 
 |     rtc::scoped_refptr<RtpSenderInternal> sender_selector() const { | 
 |       RTC_DCHECK(filter_mode_ == FilterMode::kSenderSelector); | 
 |       return sender_selector_; | 
 |     } | 
 |     rtc::scoped_refptr<RtpReceiverInternal> receiver_selector() const { | 
 |       RTC_DCHECK(filter_mode_ == FilterMode::kReceiverSelector); | 
 |       return receiver_selector_; | 
 |     } | 
 |  | 
 |    private: | 
 |     RequestInfo(FilterMode filter_mode, | 
 |                 rtc::scoped_refptr<RTCStatsCollectorCallback> callback, | 
 |                 rtc::scoped_refptr<RtpSenderInternal> sender_selector, | 
 |                 rtc::scoped_refptr<RtpReceiverInternal> receiver_selector); | 
 |  | 
 |     FilterMode filter_mode_; | 
 |     rtc::scoped_refptr<RTCStatsCollectorCallback> callback_; | 
 |     rtc::scoped_refptr<RtpSenderInternal> sender_selector_; | 
 |     rtc::scoped_refptr<RtpReceiverInternal> receiver_selector_; | 
 |   }; | 
 |  | 
 |   void GetStatsReportInternal(RequestInfo request); | 
 |  | 
 |   struct CertificateStatsPair { | 
 |     std::unique_ptr<rtc::SSLCertificateStats> local; | 
 |     std::unique_ptr<rtc::SSLCertificateStats> remote; | 
 |   }; | 
 |  | 
 |   // Structure for tracking stats about each RtpTransceiver managed by the | 
 |   // PeerConnection. This can either by a Plan B style or Unified Plan style | 
 |   // transceiver (i.e., can have 0 or many senders and receivers). | 
 |   // Some fields are copied from the RtpTransceiver/BaseChannel object so that | 
 |   // they can be accessed safely on threads other than the signaling thread. | 
 |   // If a BaseChannel is not available (e.g., if signaling has not started), | 
 |   // then |mid| and |transport_name| will be null. | 
 |   struct RtpTransceiverStatsInfo { | 
 |     rtc::scoped_refptr<RtpTransceiver> transceiver; | 
 |     cricket::MediaType media_type; | 
 |     absl::optional<std::string> mid; | 
 |     absl::optional<std::string> transport_name; | 
 |     std::unique_ptr<TrackMediaInfoMap> track_media_info_map; | 
 |   }; | 
 |  | 
 |   void AddPartialResults_s(rtc::scoped_refptr<RTCStatsReport> partial_report); | 
 |   void DeliverCachedReport( | 
 |       rtc::scoped_refptr<const RTCStatsReport> cached_report, | 
 |       std::vector<RequestInfo> requests); | 
 |  | 
 |   // Produces |RTCCertificateStats|. | 
 |   void ProduceCertificateStats_n( | 
 |       int64_t timestamp_us, | 
 |       const std::map<std::string, CertificateStatsPair>& transport_cert_stats, | 
 |       RTCStatsReport* report) const; | 
 |   // Produces |RTCCodecStats|. | 
 |   void ProduceCodecStats_n( | 
 |       int64_t timestamp_us, | 
 |       const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos, | 
 |       RTCStatsReport* report) const; | 
 |   // Produces |RTCDataChannelStats|. | 
 |   void ProduceDataChannelStats_s(int64_t timestamp_us, | 
 |                                  RTCStatsReport* report) const; | 
 |   // Produces |RTCIceCandidatePairStats| and |RTCIceCandidateStats|. | 
 |   void ProduceIceCandidateAndPairStats_n( | 
 |       int64_t timestamp_us, | 
 |       const std::map<std::string, cricket::TransportStats>& | 
 |           transport_stats_by_name, | 
 |       const Call::Stats& call_stats, | 
 |       RTCStatsReport* report) const; | 
 |   // Produces |RTCMediaStreamStats|. | 
 |   void ProduceMediaStreamStats_s(int64_t timestamp_us, | 
 |                                  RTCStatsReport* report) const; | 
 |   // Produces |RTCMediaStreamTrackStats|. | 
 |   void ProduceMediaStreamTrackStats_s(int64_t timestamp_us, | 
 |                                       RTCStatsReport* report) const; | 
 |   // Produces |RTCPeerConnectionStats|. | 
 |   void ProducePeerConnectionStats_s(int64_t timestamp_us, | 
 |                                     RTCStatsReport* report) const; | 
 |   // Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|. | 
 |   void ProduceRTPStreamStats_n( | 
 |       int64_t timestamp_us, | 
 |       const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos, | 
 |       RTCStatsReport* report) const; | 
 |   void ProduceAudioRTPStreamStats_n(int64_t timestamp_us, | 
 |                                     const RtpTransceiverStatsInfo& stats, | 
 |                                     RTCStatsReport* report) const; | 
 |   void ProduceVideoRTPStreamStats_n(int64_t timestamp_us, | 
 |                                     const RtpTransceiverStatsInfo& stats, | 
 |                                     RTCStatsReport* report) const; | 
 |   // Produces |RTCTransportStats|. | 
 |   void ProduceTransportStats_n( | 
 |       int64_t timestamp_us, | 
 |       const std::map<std::string, cricket::TransportStats>& | 
 |           transport_stats_by_name, | 
 |       const std::map<std::string, CertificateStatsPair>& transport_cert_stats, | 
 |       RTCStatsReport* report) const; | 
 |  | 
 |   // Helper function to stats-producing functions. | 
 |   std::map<std::string, CertificateStatsPair> | 
 |   PrepareTransportCertificateStats_n( | 
 |       const std::map<std::string, cricket::TransportStats>& | 
 |           transport_stats_by_name) const; | 
 |   std::vector<RtpTransceiverStatsInfo> PrepareTransceiverStatsInfos_s() const; | 
 |   std::set<std::string> PrepareTransportNames_s() const; | 
 |  | 
 |   // Slots for signals (sigslot) that are wired up to |pc_|. | 
 |   void OnDataChannelCreated(DataChannel* channel); | 
 |   // Slots for signals (sigslot) that are wired up to |channel|. | 
 |   void OnDataChannelOpened(DataChannel* channel); | 
 |   void OnDataChannelClosed(DataChannel* channel); | 
 |  | 
 |   PeerConnectionInternal* const pc_; | 
 |   rtc::Thread* const signaling_thread_; | 
 |   rtc::Thread* const worker_thread_; | 
 |   rtc::Thread* const network_thread_; | 
 |   rtc::AsyncInvoker invoker_; | 
 |  | 
 |   int num_pending_partial_reports_; | 
 |   int64_t partial_report_timestamp_us_; | 
 |   rtc::scoped_refptr<RTCStatsReport> partial_report_; | 
 |   std::vector<RequestInfo> requests_; | 
 |  | 
 |   // Set in |GetStatsReport|, read in |ProducePartialResultsOnNetworkThread| and | 
 |   // |ProducePartialResultsOnSignalingThread|, reset after work is complete. Not | 
 |   // passed as arguments to avoid copies. This is thread safe - when we | 
 |   // set/reset we know there are no pending stats requests in progress. | 
 |   std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos_; | 
 |   std::set<std::string> transport_names_; | 
 |  | 
 |   Call::Stats call_stats_; | 
 |  | 
 |   // A timestamp, in microseconds, that is based on a timer that is | 
 |   // monotonically increasing. That is, even if the system clock is modified the | 
 |   // difference between the timer and this timestamp is how fresh the cached | 
 |   // report is. | 
 |   int64_t cache_timestamp_us_; | 
 |   int64_t cache_lifetime_us_; | 
 |   rtc::scoped_refptr<const RTCStatsReport> cached_report_; | 
 |  | 
 |   // Data recorded and maintained by the stats collector during its lifetime. | 
 |   // Some stats are produced from this record instead of other components. | 
 |   struct InternalRecord { | 
 |     InternalRecord() : data_channels_opened(0), data_channels_closed(0) {} | 
 |  | 
 |     // The opened count goes up when a channel is fully opened and the closed | 
 |     // count goes up if a previously opened channel has fully closed. The opened | 
 |     // count does not go down when a channel closes, meaning (opened - closed) | 
 |     // is the number of channels currently opened. A channel that is closed | 
 |     // before reaching the open state does not affect these counters. | 
 |     uint32_t data_channels_opened; | 
 |     uint32_t data_channels_closed; | 
 |     // Identifies by address channels that have been opened, which remain in the | 
 |     // set until they have been fully closed. | 
 |     std::set<uintptr_t> opened_data_channels; | 
 |   }; | 
 |   InternalRecord internal_record_; | 
 | }; | 
 |  | 
 | const char* CandidateTypeToRTCIceCandidateTypeForTesting( | 
 |     const std::string& type); | 
 | const char* DataStateToRTCDataChannelStateForTesting( | 
 |     DataChannelInterface::DataState state); | 
 |  | 
 | }  // namespace webrtc | 
 |  | 
 | #endif  // PC_RTCSTATSCOLLECTOR_H_ |