From 1fe14f2752a35932bea6d6ccff7433a6716c6391 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Fri, 17 Jun 2022 11:34:31 +0200 Subject: [PATCH] pc: invalidate stats cache when firing onicecandidate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://w3c.github.io/webrtc-stats/#guidelines-for-getstats-results-caching-throttling "When the state of the RTCPeerConnection visibly changes as a result of an API call, a promise resolving or an event firing, subsequent new getStats() calls must return up-to-date dictionaries for the affected objects." BUG=webrtc:14190 Change-Id: I4560be22795f30e0369d573bda0100e490efb57b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265870 Reviewed-by: Henrik Boström Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#37255} --- pc/peer_connection.cc | 1 + pc/peer_connection_integrationtest.cc | 32 +++++++++++++++++++++++++++ pc/test/integration_test_helpers.h | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 557f2e6899..11004ba743 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -2000,6 +2000,7 @@ void PeerConnection::OnIceCandidate( return; } ReportIceCandidateCollected(candidate->candidate()); + ClearStatsCache(); Observer()->OnIceCandidate(candidate.get()); } diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index 9811392bbd..d6ac0c82c9 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -2418,6 +2418,38 @@ TEST_P(PeerConnectionIntegrationTestWithFakeClock, ClosePeerConnections(); } +TEST_P(PeerConnectionIntegrationTestWithFakeClock, + OnIceCandidateFlushesGetStatsCache) { + ASSERT_TRUE(CreatePeerConnectionWrappers()); + ConnectFakeSignaling(); + caller()->AddAudioTrack(); + + // Call getStats, assert there are no candidates. + rtc::scoped_refptr first_report = + caller()->NewGetStats(); + ASSERT_TRUE(first_report); + auto first_candidate_stats = + first_report->GetStatsOfType(); + ASSERT_EQ(first_candidate_stats.size(), 0u); + + // Start candidate gathering and wait for it to complete. + caller()->CreateAndSetAndSignalOffer(); + ASSERT_TRUE_SIMULATED_WAIT(caller()->IceGatheringStateComplete(), + kDefaultTimeout, FakeClock()); + + // Call getStats again, assert there are candidates now. + rtc::scoped_refptr second_report = + caller()->NewGetStats(); + ASSERT_TRUE(second_report); + auto second_candidate_stats = + second_report->GetStatsOfType(); + ASSERT_NE(second_candidate_stats.size(), 0u); + + // The fake clock ensures that no time has passed so the cache must have been + // explicitly invalidated. + EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us()); +} + #endif // !defined(THREAD_SANITIZER) // Verify that a TurnCustomizer passed in through RTCConfiguration diff --git a/pc/test/integration_test_helpers.h b/pc/test/integration_test_helpers.h index 53df9fc478..460148c559 100644 --- a/pc/test/integration_test_helpers.h +++ b/pc/test/integration_test_helpers.h @@ -410,6 +410,11 @@ class PeerConnectionIntegrationWrapper : public webrtc::PeerConnectionObserver, return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable; } + bool IceGatheringStateComplete() { + return pc()->ice_gathering_state() == + webrtc::PeerConnectionInterface::kIceGatheringComplete; + } + void CreateDataChannel() { CreateDataChannel(nullptr); } void CreateDataChannel(const webrtc::DataChannelInit* init) {