diff --git a/api/uma_metrics.h b/api/uma_metrics.h index 30543b68b1..5edb1f48e8 100644 --- a/api/uma_metrics.h +++ b/api/uma_metrics.h @@ -167,6 +167,30 @@ enum SimulcastApiVersion { kSimulcastApiVersionMax }; +// Metrics for reporting usage of BUNDLE. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum BundleUsage { + // There are no m-lines in the SDP, only a session description. + kBundleUsageEmpty = 0, + // Only a data channel is negotiated but BUNDLE is not negotiated. + kBundleUsageNoBundleDatachannelOnly = 1, + // BUNDLE is not negotiated and there is at most one m-line per media type, + kBundleUsageNoBundleSimple = 2, + // BUNDLE is not negotiated and there are multiple m-lines per media type, + kBundleUsageNoBundleComplex = 3, + // Only a data channel is negotiated and BUNDLE is negotiated. + kBundleUsageBundleDatachannelOnly = 4, + // BUNDLE is negotiated but there is at most one m-line per media type, + kBundleUsageBundleSimple = 5, + // BUNDLE is negotiated and there are multiple m-lines per media type, + kBundleUsageBundleComplex = 6, + // Legacy plan-b metrics. + kBundleUsageNoBundlePlanB = 7, + kBundleUsageBundlePlanB = 8, + kBundleUsageMax +}; + // When adding new metrics please consider using the style described in // https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#usage // instead of the legacy enums used above. diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 23be9b9112..68fa06e007 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -2344,6 +2344,52 @@ void PeerConnection::ReportSdpFormatReceived( } } +void PeerConnection::ReportSdpBundleUsage( + const SessionDescriptionInterface& remote_description) { + RTC_DCHECK_RUN_ON(signaling_thread()); + + bool using_bundle = + remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE); + int num_audio_mlines = 0; + int num_video_mlines = 0; + int num_data_mlines = 0; + for (const ContentInfo& content : + remote_description.description()->contents()) { + cricket::MediaType media_type = content.media_description()->type(); + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + num_audio_mlines += 1; + } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { + num_video_mlines += 1; + } else if (media_type == cricket::MEDIA_TYPE_DATA) { + num_data_mlines += 1; + } + } + bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1; + BundleUsage usage = kBundleUsageMax; + if (num_audio_mlines == 0 && num_video_mlines == 0) { + if (num_data_mlines > 0) { + usage = using_bundle ? kBundleUsageBundleDatachannelOnly + : kBundleUsageNoBundleDatachannelOnly; + } else { + usage = kBundleUsageEmpty; + } + } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB) { + // In plan-b, simple/complex usage will not show up in the number of + // m-lines or BUNDLE. + usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB; + } else { + if (simple) { + usage = + using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple; + } else { + usage = using_bundle ? kBundleUsageBundleComplex + : kBundleUsageNoBundleComplex; + } + } + RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage, + kBundleUsageMax); +} + void PeerConnection::ReportIceCandidateCollected( const cricket::Candidate& candidate) { NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED); diff --git a/pc/peer_connection.h b/pc/peer_connection.h index f3aa9b3422..4bab90a4b1 100644 --- a/pc/peer_connection.h +++ b/pc/peer_connection.h @@ -383,6 +383,10 @@ class PeerConnection : public PeerConnectionInternal, void ReportSdpFormatReceived( const SessionDescriptionInterface& remote_description); + // Report the UMA metric BundleUsage for the given remote description. + void ReportSdpBundleUsage( + const SessionDescriptionInterface& remote_description); + // Returns true if the PeerConnection is configured to use Unified Plan // semantics for creating offers/answers and setting local/remote // descriptions. If this is true the RtpTransceiver API will also be available diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 88852764ea..07097a9447 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -2156,6 +2156,7 @@ void SdpOfferAnswerHandler::DoSetRemoteDescription( desc->GetType() == SdpType::kAnswer) { // Report to UMA the format of the received offer or answer. pc_->ReportSdpFormatReceived(*desc); + pc_->ReportSdpBundleUsage(*desc); } // Handle remote descriptions missing a=mid lines for interop with legacy end