From 44d0dff7a979e2e6c2cc417529249d4b52d3cc34 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Fri, 9 Oct 2020 05:43:53 +0000 Subject: [PATCH] Move the PeerConnection's usage pattern concept to its own file. This makes it easier to use it from multiple other modules. Bug: webrtc:11995 Change-Id: Id23843ae4600ebe46aed7465e873d107089fd50b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/187347 Reviewed-by: Mirko Bonadei Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/master@{#32361} --- pc/BUILD.gn | 14 ++ pc/peer_connection.cc | 26 +-- pc/peer_connection.h | 50 +---- pc/peer_connection_histogram_unittest.cc | 248 +++++++++-------------- pc/sdp_offer_answer.cc | 20 +- pc/usage_pattern.cc | 49 +++++ pc/usage_pattern.h | 75 +++++++ 7 files changed, 243 insertions(+), 239 deletions(-) create mode 100644 pc/usage_pattern.cc create mode 100644 pc/usage_pattern.h diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 047fc2253c..3fb1729ce2 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -230,6 +230,7 @@ rtc_library("peerconnection") { ":rtp_sender", ":rtp_transceiver", ":stats_collector_interface", + ":usage_pattern", ":video_track_source", "../api:array_view", "../api:audio_options_api", @@ -305,6 +306,18 @@ rtc_library("peer_connection_message_handler") { ] } +rtc_library("usage_pattern") { + sources = [ + "usage_pattern.cc", + "usage_pattern.h", + ] + deps = [ + "../api:libjingle_peerconnection_api", + "../rtc_base:logging", + "../system_wrappers:metrics", + ] +} + rtc_library("rtp_transceiver") { sources = [ "rtp_transceiver.cc", @@ -745,6 +758,7 @@ if (rtc_include_tests) { ":rtp_receiver", ":rtp_sender", ":rtp_transceiver", + ":usage_pattern", ":video_track_source", "../api:array_view", "../api:audio_options_api", diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index e43a44749e..6b7028e9e0 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -3066,33 +3066,11 @@ void PeerConnection::ReportIceCandidateCollected( void PeerConnection::NoteUsageEvent(UsageEvent event) { RTC_DCHECK_RUN_ON(signaling_thread()); - usage_event_accumulator_ |= static_cast(event); + usage_pattern_.NoteUsageEvent(event); } void PeerConnection::ReportUsagePattern() const { - RTC_DLOG(LS_INFO) << "Usage signature is " << usage_event_accumulator_; - RTC_HISTOGRAM_ENUMERATION_SPARSE("WebRTC.PeerConnection.UsagePattern", - usage_event_accumulator_, - static_cast(UsageEvent::MAX_VALUE)); - const int bad_bits = - static_cast(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED) | - static_cast(UsageEvent::CANDIDATE_COLLECTED); - const int good_bits = - static_cast(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED) | - static_cast(UsageEvent::REMOTE_CANDIDATE_ADDED) | - static_cast(UsageEvent::ICE_STATE_CONNECTED); - if ((usage_event_accumulator_ & bad_bits) == bad_bits && - (usage_event_accumulator_ & good_bits) == 0) { - // If called after close(), we can't report, because observer may have - // been deallocated, and therefore pointer is null. Write to log instead. - if (observer_) { - Observer()->OnInterestingUsage(usage_event_accumulator_); - } else { - RTC_LOG(LS_INFO) << "Interesting usage signature " - << usage_event_accumulator_ - << " observed after observer shutdown"; - } - } + usage_pattern_.ReportUsagePattern(observer_); } bool PeerConnection::SrtpRequired() const { diff --git a/pc/peer_connection.h b/pc/peer_connection.h index c073b59a0f..8698c30008 100644 --- a/pc/peer_connection.h +++ b/pc/peer_connection.h @@ -36,6 +36,7 @@ #include "pc/stats_collector.h" #include "pc/stream_collection.h" #include "pc/transceiver_list.h" +#include "pc/usage_pattern.h" #include "pc/webrtc_session_description_factory.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/operations_chain.h" @@ -70,53 +71,6 @@ class PeerConnection : public PeerConnectionInternal, public RtpSenderBase::SetStreamsObserver, public sigslot::has_slots<> { public: - // A bit in the usage pattern is registered when its defining event occurs at - // least once. - enum class UsageEvent : int { - TURN_SERVER_ADDED = 0x01, - STUN_SERVER_ADDED = 0x02, - DATA_ADDED = 0x04, - AUDIO_ADDED = 0x08, - VIDEO_ADDED = 0x10, - // |SetLocalDescription| returns successfully. - SET_LOCAL_DESCRIPTION_SUCCEEDED = 0x20, - // |SetRemoteDescription| returns successfully. - SET_REMOTE_DESCRIPTION_SUCCEEDED = 0x40, - // A local candidate (with type host, server-reflexive, or relay) is - // collected. - CANDIDATE_COLLECTED = 0x80, - // A remote candidate is successfully added via |AddIceCandidate|. - ADD_ICE_CANDIDATE_SUCCEEDED = 0x100, - ICE_STATE_CONNECTED = 0x200, - CLOSE_CALLED = 0x400, - // A local candidate with private IP is collected. - PRIVATE_CANDIDATE_COLLECTED = 0x800, - // A remote candidate with private IP is added, either via AddiceCandidate - // or from the remote description. - REMOTE_PRIVATE_CANDIDATE_ADDED = 0x1000, - // A local mDNS candidate is collected. - MDNS_CANDIDATE_COLLECTED = 0x2000, - // A remote mDNS candidate is added, either via AddIceCandidate or from the - // remote description. - REMOTE_MDNS_CANDIDATE_ADDED = 0x4000, - // A local candidate with IPv6 address is collected. - IPV6_CANDIDATE_COLLECTED = 0x8000, - // A remote candidate with IPv6 address is added, either via AddIceCandidate - // or from the remote description. - REMOTE_IPV6_CANDIDATE_ADDED = 0x10000, - // A remote candidate (with type host, server-reflexive, or relay) is - // successfully added, either via AddIceCandidate or from the remote - // description. - REMOTE_CANDIDATE_ADDED = 0x20000, - // An explicit host-host candidate pair is selected, i.e. both the local and - // the remote candidates have the host type. This does not include candidate - // pairs formed with equivalent prflx remote candidates, e.g. a host-prflx - // pair where the prflx candidate has the same base as a host candidate of - // the remote peer. - DIRECT_CONNECTION_SELECTED = 0x40000, - MAX_VALUE = 0x80000, - }; - explicit PeerConnection(PeerConnectionFactory* factory, std::unique_ptr event_log, std::unique_ptr call); @@ -873,7 +827,7 @@ class PeerConnection : public PeerConnectionInternal, cricket::AudioOptions audio_options_ RTC_GUARDED_BY(signaling_thread()); cricket::VideoOptions video_options_ RTC_GUARDED_BY(signaling_thread()); - int usage_event_accumulator_ RTC_GUARDED_BY(signaling_thread()) = 0; + UsagePattern usage_pattern_ RTC_GUARDED_BY(signaling_thread()); bool return_histogram_very_quickly_ RTC_GUARDED_BY(signaling_thread()) = false; diff --git a/pc/peer_connection_histogram_unittest.cc b/pc/peer_connection_histogram_unittest.cc index e36b29a23a..8fcb87a68e 100644 --- a/pc/peer_connection_histogram_unittest.cc +++ b/pc/peer_connection_histogram_unittest.cc @@ -32,6 +32,7 @@ #include "pc/peer_connection_wrapper.h" #include "pc/sdp_utils.h" #include "pc/test/mock_peer_connection_observers.h" +#include "pc/usage_pattern.h" #include "pc/webrtc_sdp.h" #include "rtc_base/arraysize.h" #include "rtc_base/checks.h" @@ -61,7 +62,7 @@ static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0); static const rtc::SocketAddress kPrivateIpv6LocalAddress("fd12:3456:789a:1::1", 0); -int MakeUsageFingerprint(std::set events) { +int MakeUsageFingerprint(std::set events) { int signature = 0; for (const auto it : events) { signature |= static_cast(it); @@ -418,16 +419,12 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) { caller->pc()->Close(); callee->pc()->Close(); int expected_fingerprint = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::VIDEO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED, + UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED, // depending on the machine configuration. EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); @@ -437,9 +434,7 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintAudioVideo) { webrtc::metrics::NumEvents( kUsagePatternMetric, expected_fingerprint | - static_cast( - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == - 2); + static_cast(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == 2); } // Test getting the usage fingerprint when the caller collects an mDNS @@ -458,32 +453,24 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) { callee->pc()->Close(); int expected_fingerprint_caller = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::VIDEO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED, + UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::MDNS_CANDIDATE_COLLECTED, + UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); // Without a resolver, the callee cannot resolve the received mDNS candidate // but can still connect with the caller via a prflx candidate. As a result, // the bit for the direct connection should not be logged. int expected_fingerprint_callee = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::VIDEO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED, + UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::REMOTE_CANDIDATE_ADDED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint_caller)); @@ -509,29 +496,21 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) { // Similar to the test above, the caller connects with the callee via a prflx // candidate. int expected_fingerprint_caller = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::VIDEO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED, + UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::REMOTE_CANDIDATE_ADDED, UsageEvent::CLOSE_CALLED}); int expected_fingerprint_callee = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::VIDEO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::VIDEO_ADDED, + UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::MDNS_CANDIDATE_COLLECTED, + UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint_caller)); @@ -549,15 +528,11 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) { caller->pc()->Close(); callee->pc()->Close(); int expected_fingerprint = MakeUsageFingerprint( - {PeerConnection::UsageEvent::DATA_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_TRUE( webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint) == @@ -565,9 +540,7 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) { webrtc::metrics::NumEvents( kUsagePatternMetric, expected_fingerprint | - static_cast( - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == - 2); + static_cast(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == 2); } #endif // HAVE_SCTP #endif // WEBRTC_ANDROID @@ -584,10 +557,9 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurn) { auto caller = CreatePeerConnection(configuration); ASSERT_TRUE(caller); caller->pc()->Close(); - int expected_fingerprint = - MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED, - PeerConnection::UsageEvent::TURN_SERVER_ADDED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + int expected_fingerprint = MakeUsageFingerprint( + {UsageEvent::STUN_SERVER_ADDED, UsageEvent::TURN_SERVER_ADDED, + UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ( 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint)); @@ -606,10 +578,9 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintStunTurnInReconfiguration) { ASSERT_TRUE(caller); ASSERT_TRUE(caller->pc()->SetConfiguration(configuration).ok()); caller->pc()->Close(); - int expected_fingerprint = - MakeUsageFingerprint({PeerConnection::UsageEvent::STUN_SERVER_ADDED, - PeerConnection::UsageEvent::TURN_SERVER_ADDED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + int expected_fingerprint = MakeUsageFingerprint( + {UsageEvent::STUN_SERVER_ADDED, UsageEvent::TURN_SERVER_ADDED, + UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ( 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint)); @@ -624,28 +595,20 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCaller) { callee->pc()->Close(); int expected_fingerprint_caller = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::PRIVATE_CANDIDATE_COLLECTED, + UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); int expected_fingerprint_callee = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED, + UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint_caller)); @@ -662,30 +625,22 @@ TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIpv6Callee) { callee->pc()->Close(); int expected_fingerprint_caller = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED, + UsageEvent::ICE_STATE_CONNECTED, UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); int expected_fingerprint_callee = MakeUsageFingerprint( - {PeerConnection::UsageEvent::AUDIO_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::IPV6_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::AUDIO_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::PRIVATE_CANDIDATE_COLLECTED, + UsageEvent::IPV6_CANDIDATE_COLLECTED, + UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED, + UsageEvent::REMOTE_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint_caller)); @@ -747,27 +702,20 @@ TEST_F(PeerConnectionUsageHistogramTest, // with the callee via a prflx candidate and hence no direct connection bit // should be set. int expected_fingerprint_caller = MakeUsageFingerprint( - {PeerConnection::UsageEvent::DATA_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::IPV6_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::PRIVATE_CANDIDATE_COLLECTED, + UsageEvent::IPV6_CANDIDATE_COLLECTED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::CLOSE_CALLED}); int expected_fingerprint_callee = MakeUsageFingerprint( - {PeerConnection::UsageEvent::DATA_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::MDNS_CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED, - PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED, - PeerConnection::UsageEvent::ICE_STATE_CONNECTED, - PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::MDNS_CANDIDATE_COLLECTED, + UsageEvent::REMOTE_CANDIDATE_ADDED, + UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED, + UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED, UsageEvent::ICE_STATE_CONNECTED, + UsageEvent::DIRECT_CONNECTION_SELECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint_caller)); @@ -781,16 +729,13 @@ TEST_F(PeerConnectionUsageHistogramTest, NotableUsageNoted) { caller->GenerateOfferAndCollectCandidates(); caller->pc()->Close(); int expected_fingerprint = MakeUsageFingerprint( - {PeerConnection::UsageEvent::DATA_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric)); EXPECT_METRIC_TRUE( expected_fingerprint == ObservedFingerprint() || (expected_fingerprint | - static_cast( - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == + static_cast(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == ObservedFingerprint()); EXPECT_METRIC_EQ(absl::make_optional(ObservedFingerprint()), caller->observer()->interesting_usage_detected()); @@ -801,9 +746,8 @@ TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) { caller->CreateDataChannel("foo"); caller->GenerateOfferAndCollectCandidates(); int expected_fingerprint = MakeUsageFingerprint( - {PeerConnection::UsageEvent::DATA_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED}); + {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED}); EXPECT_METRIC_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric)); caller->GetInternalPeerConnection()->RequestUsagePatternReportForTesting(); EXPECT_METRIC_EQ_WAIT(1, webrtc::metrics::NumSamples(kUsagePatternMetric), @@ -811,8 +755,7 @@ TEST_F(PeerConnectionUsageHistogramTest, NotableUsageOnEventFiring) { EXPECT_METRIC_TRUE( expected_fingerprint == ObservedFingerprint() || (expected_fingerprint | - static_cast( - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == + static_cast(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == ObservedFingerprint()); EXPECT_METRIC_EQ(absl::make_optional(ObservedFingerprint()), caller->observer()->interesting_usage_detected()); @@ -824,10 +767,8 @@ TEST_F(PeerConnectionUsageHistogramTest, caller->CreateDataChannel("foo"); caller->GenerateOfferAndCollectCandidates(); int expected_fingerprint = MakeUsageFingerprint( - {PeerConnection::UsageEvent::DATA_ADDED, - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, - PeerConnection::UsageEvent::CANDIDATE_COLLECTED, - PeerConnection::UsageEvent::CLOSE_CALLED}); + {UsageEvent::DATA_ADDED, UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED, + UsageEvent::CANDIDATE_COLLECTED, UsageEvent::CLOSE_CALLED}); EXPECT_METRIC_EQ(0, webrtc::metrics::NumSamples(kUsagePatternMetric)); caller->pc()->Close(); EXPECT_METRIC_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric)); @@ -838,8 +779,7 @@ TEST_F(PeerConnectionUsageHistogramTest, EXPECT_METRIC_TRUE( expected_fingerprint == ObservedFingerprint() || (expected_fingerprint | - static_cast( - PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == + static_cast(UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) == ObservedFingerprint()); // After close, the usage-detection callback should NOT have been called. EXPECT_METRIC_FALSE(caller->observer()->interesting_usage_detected()); diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 8b2d5a0b3b..5dc5571d55 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -1802,8 +1802,7 @@ void SdpOfferAnswerHandler::DoSetLocalDescription( } observer->OnSetLocalDescriptionComplete(RTCError::OK()); - pc_->NoteUsageEvent( - PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED); + pc_->NoteUsageEvent(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED); // Check if negotiation is needed. We must do this after informing the // observer that SetLocalDescription() has completed to ensure negotiation is @@ -2062,8 +2061,7 @@ void SdpOfferAnswerHandler::DoSetRemoteDescription( } observer->OnSetRemoteDescriptionComplete(RTCError::OK()); - pc_->NoteUsageEvent( - PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED); + pc_->NoteUsageEvent(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED); // Check if negotiation is needed. We must do this after informing the // observer that SetRemoteDescription() has completed to ensure negotiation is @@ -2162,8 +2160,7 @@ bool SdpOfferAnswerHandler::AddIceCandidate( if (ready) { bool result = UseCandidate(ice_candidate); if (result) { - pc_->NoteUsageEvent( - PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED); + pc_->NoteUsageEvent(UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED); NoteAddIceCandidateResult(kAddIceCandidateSuccess); } else { NoteAddIceCandidateResult(kAddIceCandidateFailNotUsable); @@ -4235,18 +4232,15 @@ bool SdpOfferAnswerHandler::ReadyToUseRemoteCandidate( void SdpOfferAnswerHandler::ReportRemoteIceCandidateAdded( const cricket::Candidate& candidate) { - pc_->NoteUsageEvent(PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED); + pc_->NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED); if (candidate.address().IsPrivateIP()) { - pc_->NoteUsageEvent( - PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED); + pc_->NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED); } if (candidate.address().IsUnresolvedIP()) { - pc_->NoteUsageEvent( - PeerConnection::UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED); + pc_->NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED); } if (candidate.address().family() == AF_INET6) { - pc_->NoteUsageEvent( - PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED); + pc_->NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED); } } diff --git a/pc/usage_pattern.cc b/pc/usage_pattern.cc new file mode 100644 index 0000000000..848472148f --- /dev/null +++ b/pc/usage_pattern.cc @@ -0,0 +1,49 @@ +/* + * Copyright 2020 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. + */ + +#include "pc/usage_pattern.h" + +#include "api/peer_connection_interface.h" +#include "rtc_base/logging.h" +#include "system_wrappers/include/metrics.h" + +namespace webrtc { + +void UsagePattern::NoteUsageEvent(UsageEvent event) { + usage_event_accumulator_ |= static_cast(event); +} + +void UsagePattern::ReportUsagePattern(PeerConnectionObserver* observer) const { + RTC_DLOG(LS_INFO) << "Usage signature is " << usage_event_accumulator_; + RTC_HISTOGRAM_ENUMERATION_SPARSE("WebRTC.PeerConnection.UsagePattern", + usage_event_accumulator_, + static_cast(UsageEvent::MAX_VALUE)); + const int bad_bits = + static_cast(UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED) | + static_cast(UsageEvent::CANDIDATE_COLLECTED); + const int good_bits = + static_cast(UsageEvent::SET_REMOTE_DESCRIPTION_SUCCEEDED) | + static_cast(UsageEvent::REMOTE_CANDIDATE_ADDED) | + static_cast(UsageEvent::ICE_STATE_CONNECTED); + if ((usage_event_accumulator_ & bad_bits) == bad_bits && + (usage_event_accumulator_ & good_bits) == 0) { + // If called after close(), we can't report, because observer may have + // been deallocated, and therefore pointer is null. Write to log instead. + if (observer) { + observer->OnInterestingUsage(usage_event_accumulator_); + } else { + RTC_LOG(LS_INFO) << "Interesting usage signature " + << usage_event_accumulator_ + << " observed after observer shutdown"; + } + } +} + +} // namespace webrtc diff --git a/pc/usage_pattern.h b/pc/usage_pattern.h new file mode 100644 index 0000000000..c4a8918ac2 --- /dev/null +++ b/pc/usage_pattern.h @@ -0,0 +1,75 @@ +/* + * Copyright 2020 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_USAGE_PATTERN_H_ +#define PC_USAGE_PATTERN_H_ + +namespace webrtc { + +class PeerConnectionObserver; + +// A bit in the usage pattern is registered when its defining event occurs +// at least once. +enum class UsageEvent : int { + TURN_SERVER_ADDED = 0x01, + STUN_SERVER_ADDED = 0x02, + DATA_ADDED = 0x04, + AUDIO_ADDED = 0x08, + VIDEO_ADDED = 0x10, + // |SetLocalDescription| returns successfully. + SET_LOCAL_DESCRIPTION_SUCCEEDED = 0x20, + // |SetRemoteDescription| returns successfully. + SET_REMOTE_DESCRIPTION_SUCCEEDED = 0x40, + // A local candidate (with type host, server-reflexive, or relay) is + // collected. + CANDIDATE_COLLECTED = 0x80, + // A remote candidate is successfully added via |AddIceCandidate|. + ADD_ICE_CANDIDATE_SUCCEEDED = 0x100, + ICE_STATE_CONNECTED = 0x200, + CLOSE_CALLED = 0x400, + // A local candidate with private IP is collected. + PRIVATE_CANDIDATE_COLLECTED = 0x800, + // A remote candidate with private IP is added, either via AddiceCandidate + // or from the remote description. + REMOTE_PRIVATE_CANDIDATE_ADDED = 0x1000, + // A local mDNS candidate is collected. + MDNS_CANDIDATE_COLLECTED = 0x2000, + // A remote mDNS candidate is added, either via AddIceCandidate or from the + // remote description. + REMOTE_MDNS_CANDIDATE_ADDED = 0x4000, + // A local candidate with IPv6 address is collected. + IPV6_CANDIDATE_COLLECTED = 0x8000, + // A remote candidate with IPv6 address is added, either via AddIceCandidate + // or from the remote description. + REMOTE_IPV6_CANDIDATE_ADDED = 0x10000, + // A remote candidate (with type host, server-reflexive, or relay) is + // successfully added, either via AddIceCandidate or from the remote + // description. + REMOTE_CANDIDATE_ADDED = 0x20000, + // An explicit host-host candidate pair is selected, i.e. both the local and + // the remote candidates have the host type. This does not include candidate + // pairs formed with equivalent prflx remote candidates, e.g. a host-prflx + // pair where the prflx candidate has the same base as a host candidate of + // the remote peer. + DIRECT_CONNECTION_SELECTED = 0x40000, + MAX_VALUE = 0x80000, +}; + +class UsagePattern { + public: + void NoteUsageEvent(UsageEvent event); + void ReportUsagePattern(PeerConnectionObserver* observer) const; + + private: + int usage_event_accumulator_ = 0; +}; + +} // namespace webrtc +#endif // PC_USAGE_PATTERN_H_