commit 5ceb95bf192af309ce1e4a5a25f593bacab25009
parent 45e6701319efb29c5f91f94e77af2c4baf19c1a5
Author: Dan Baker <dbaker@mozilla.com>
Date: Mon, 1 Dec 2025 18:25:02 -0700
Bug 2000941 - Vendor libwebrtc from 5bb3ccb3e2
Upstream commit: https://webrtc.googlesource.com/src/+/5bb3ccb3e2d3b4b8c50a3ad3c127b114a80a2eed
Propagate clock into BasicIceController
Update time related parameters and variables to use Timestamp and TimeDelta types
Bug: webrtc:42223992
Change-Id: I704cbac53bdc9e5b2e0b53e9592688dd739e246c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/408161
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45602}
Diffstat:
7 files changed, 53 insertions(+), 52 deletions(-)
diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor
@@ -1,4 +1,4 @@
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
-libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T01:21:35.119040+00:00.
+libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T01:24:44.345435+00:00.
# base of lastest vendoring
-63a8d4f5e3
+5bb3ccb3e2
diff --git a/third_party/libwebrtc/p2p/BUILD.gn b/third_party/libwebrtc/p2p/BUILD.gn
@@ -84,7 +84,10 @@ rtc_library("basic_ice_controller") {
":transport_description",
"../api:array_view",
"../api:candidate",
+ "../api/environment",
"../api/transport:enums",
+ "../api/units:time_delta",
+ "../api/units:timestamp",
"../rtc_base:checks",
"../rtc_base:ip_address",
"../rtc_base:logging",
@@ -391,6 +394,7 @@ rtc_source_set("ice_controller_factory_interface") {
":ice_transport_internal",
":p2p_transport_channel_ice_field_trials",
":transport_description",
+ "../api/environment",
]
}
diff --git a/third_party/libwebrtc/p2p/base/basic_ice_controller.cc b/third_party/libwebrtc/p2p/base/basic_ice_controller.cc
@@ -22,6 +22,8 @@
#include "absl/algorithm/container.h"
#include "api/candidate.h"
#include "api/transport/enums.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "p2p/base/connection.h"
#include "p2p/base/connection_info.h"
#include "p2p/base/ice_controller_factory_interface.h"
@@ -36,7 +38,6 @@
#include "rtc_base/net_helper.h"
#include "rtc_base/network.h"
#include "rtc_base/network_constants.h"
-#include "rtc_base/time_utils.h"
namespace {
@@ -86,7 +87,8 @@ int CompareCandidatePairsByNetworkPreference(
namespace webrtc {
BasicIceController::BasicIceController(const IceControllerFactoryArgs& args)
- : ice_transport_state_func_(args.ice_transport_state_func),
+ : env_(args.env),
+ ice_transport_state_func_(args.ice_transport_state_func),
ice_role_func_(args.ice_role_func),
is_connection_pruned_func_(args.is_connection_pruned_func),
field_trials_(args.ice_field_trials) {}
@@ -116,7 +118,7 @@ void BasicIceController::OnConnectionDestroyed(const Connection* connection) {
}
bool BasicIceController::HasPingableConnection() const {
- int64_t now = TimeMillis();
+ Timestamp now = Connection::AlignTime(env_.clock().CurrentTime());
return absl::c_any_of(connections_, [this, now](const Connection* c) {
return IsPingable(c, now);
});
@@ -137,7 +139,8 @@ IceControllerInterface::PingResult BasicIceController::SelectConnectionToPing(
: strong_ping_interval();
const Connection* conn = nullptr;
- if (TimeMillis() >= last_ping_sent_ms + ping_interval.ms()) {
+ if (Connection::AlignTime(env_.clock().CurrentTime()) >=
+ Timestamp::Millis(last_ping_sent_ms) + ping_interval) {
conn = FindNextPingableConnection();
}
return PingResult(conn, std::min(ping_interval, check_receiving_interval()));
@@ -151,7 +154,7 @@ void BasicIceController::MarkConnectionPinged(const Connection* conn) {
// Returns the next pingable connection to ping.
const Connection* BasicIceController::FindNextPingableConnection() {
- int64_t now = TimeMillis();
+ Timestamp now = Connection::AlignTime(env_.clock().CurrentTime());
// Rule 1: Selected connection takes priority over non-selected ones.
if (selected_connection_ && selected_connection_->connected() &&
@@ -237,7 +240,7 @@ const Connection* BasicIceController::FindNextPingableConnection() {
// (last_ping_received > last_ping_sent). But we shouldn't do
// triggered checks if the connection is already writable.
const Connection* BasicIceController::FindOldestConnectionNeedingTriggeredCheck(
- int64_t now) {
+ Timestamp now) {
const Connection* oldest_needing_triggered_check = nullptr;
for (auto* conn : connections_) {
if (!IsPingable(conn, now)) {
@@ -263,14 +266,14 @@ const Connection* BasicIceController::FindOldestConnectionNeedingTriggeredCheck(
bool BasicIceController::WritableConnectionPastPingInterval(
const Connection* conn,
- int64_t now) const {
+ Timestamp now) const {
TimeDelta interval = CalculateActiveWritablePingInterval(conn, now);
- return conn->LastPingSent() + interval <= Timestamp::Millis(now);
+ return conn->LastPingSent() + interval <= now;
}
TimeDelta BasicIceController::CalculateActiveWritablePingInterval(
const Connection* conn,
- int64_t now) const {
+ Timestamp now) const {
// Ping each connection at a higher rate at least
// kMinPingsAtWeakPingInterval times.
if (conn->num_pings_sent() < kMinPingsAtWeakPingInterval) {
@@ -290,7 +293,8 @@ TimeDelta BasicIceController::CalculateActiveWritablePingInterval(
// Is the connection in a state for us to even consider pinging the other side?
// We consider a connection pingable even if it's not connected because that's
// how a TCP connection is kicked into reconnecting on the active side.
-bool BasicIceController::IsPingable(const Connection* conn, int64_t now) const {
+bool BasicIceController::IsPingable(const Connection* conn,
+ Timestamp now) const {
const Candidate& remote = conn->remote_candidate();
// We should never get this far with an empty remote ufrag.
RTC_DCHECK(!remote.username().empty());
@@ -326,9 +330,8 @@ bool BasicIceController::IsPingable(const Connection* conn, int64_t now) const {
// or not, but backup connections are pinged at a slower rate.
if (IsBackupConnection(conn)) {
return conn->rtt_samples() == 0 ||
- (now >=
- conn->last_ping_response_received() +
- config_.backup_connection_ping_interval_or_default().ms());
+ (now >= conn->LastPingResponseReceived() +
+ config_.backup_connection_ping_interval_or_default());
}
// Don't ping inactive non-backup connections.
if (!conn->active()) {
@@ -452,7 +455,7 @@ BasicIceController::HandleInitialSelectDampening(
return {.connection = new_connection};
}
- int64_t now = TimeMillis();
+ Timestamp now = Connection::AlignTime(env_.clock().CurrentTime());
int64_t max_delay = 0;
if (new_connection->last_ping_received() > 0 &&
field_trials_->initial_select_dampening_ping_received.has_value()) {
@@ -461,26 +464,24 @@ BasicIceController::HandleInitialSelectDampening(
max_delay = *field_trials_->initial_select_dampening;
}
- int64_t start_wait =
- initial_select_timestamp_ms_ == 0 ? now : initial_select_timestamp_ms_;
- int64_t max_wait_until = start_wait + max_delay;
+ Timestamp start_wait = initial_select_timestamp_.value_or(now);
+ Timestamp max_wait_until = start_wait + TimeDelta::Millis(max_delay);
if (now >= max_wait_until) {
RTC_LOG(LS_INFO) << "reset initial_select_timestamp_ = "
- << initial_select_timestamp_ms_
- << " selection delayed by: " << (now - start_wait) << "ms";
- initial_select_timestamp_ms_ = 0;
+ << initial_select_timestamp_.value_or(Timestamp::Zero())
+ << " selection delayed by: " << (now - start_wait);
+ initial_select_timestamp_ = std::nullopt;
return {.connection = new_connection};
}
// We are not yet ready to select first connection...
- if (initial_select_timestamp_ms_ == 0) {
+ if (!initial_select_timestamp_.has_value()) {
// Set timestamp on first time...
// but run the delayed invokation everytime to
// avoid possibility that we miss it.
- initial_select_timestamp_ms_ = now;
- RTC_LOG(LS_INFO) << "set initial_select_timestamp_ms_ = "
- << initial_select_timestamp_ms_;
+ initial_select_timestamp_ = now;
+ RTC_LOG(LS_INFO) << "set initial_select_timestamp_ = " << now;
}
int min_delay = max_delay;
@@ -518,8 +519,12 @@ IceControllerInterface::SwitchResult BasicIceController::ShouldSwitchConnection(
}
bool missed_receiving_unchanged_threshold = false;
- std::optional<int64_t> receiving_unchanged_threshold(
- TimeMillis() - config_.receiving_switching_delay_or_default().ms());
+ // TODO: bugs.webrtc.org/42223979 - consider switching threshold to
+ // Timestamp type, but beware of subtracting that may lead to negative
+ // Timestamp that DCHECKs
+ std::optional<int64_t> receiving_unchanged_threshold =
+ Connection::AlignTime(env_.clock().CurrentTime()).ms() -
+ config_.receiving_switching_delay_or_default().ms();
int cmp = CompareConnections(selected_connection_, new_connection,
receiving_unchanged_threshold,
&missed_receiving_unchanged_threshold);
diff --git a/third_party/libwebrtc/p2p/base/basic_ice_controller.h b/third_party/libwebrtc/p2p/base/basic_ice_controller.h
@@ -20,6 +20,9 @@
#include <vector>
#include "api/array_view.h"
+#include "api/environment/environment.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "p2p/base/connection.h"
#include "p2p/base/ice_controller_factory_interface.h"
#include "p2p/base/ice_controller_interface.h"
@@ -91,7 +94,7 @@ class BasicIceController : public IceControllerInterface {
config_.receiving_timeout_or_default() / 10);
}
- const Connection* FindOldestConnectionNeedingTriggeredCheck(int64_t now);
+ const Connection* FindOldestConnectionNeedingTriggeredCheck(Timestamp now);
// Between `conn1` and `conn2`, this function returns the one which should
// be pinged first.
const Connection* MorePingable(const Connection* conn1,
@@ -104,14 +107,14 @@ class BasicIceController : public IceControllerInterface {
const Connection* LeastRecentlyPinged(const Connection* conn1,
const Connection* conn2);
- bool IsPingable(const Connection* conn, int64_t now) const;
+ bool IsPingable(const Connection* conn, Timestamp now) const;
bool IsBackupConnection(const Connection* conn) const;
// Whether a writable connection is past its ping interval and needs to be
// pinged again.
bool WritableConnectionPastPingInterval(const Connection* conn,
- int64_t now) const;
+ Timestamp now) const;
TimeDelta CalculateActiveWritablePingInterval(const Connection* conn,
- int64_t now) const;
+ Timestamp now) const;
std::map<const Network*, const Connection*> GetBestConnectionByNetwork()
const;
@@ -152,6 +155,7 @@ class BasicIceController : public IceControllerInterface {
SwitchResult HandleInitialSelectDampening(IceSwitchReason reason,
const Connection* new_connection);
+ const Environment env_;
std::function<IceTransportStateInternal()> ice_transport_state_func_;
std::function<IceRole()> ice_role_func_;
std::function<bool(const Connection*)> is_connection_pruned_func_;
@@ -170,7 +174,7 @@ class BasicIceController : public IceControllerInterface {
std::set<const Connection*> unpinged_connections_;
// Timestamp for when we got the first selectable connection.
- int64_t initial_select_timestamp_ms_ = 0;
+ std::optional<Timestamp> initial_select_timestamp_;
};
} // namespace webrtc
diff --git a/third_party/libwebrtc/p2p/base/ice_controller_factory_interface.h b/third_party/libwebrtc/p2p/base/ice_controller_factory_interface.h
@@ -15,6 +15,7 @@
#include <memory>
#include <string>
+#include "api/environment/environment.h"
#include "p2p/base/connection.h"
#include "p2p/base/ice_controller_interface.h"
#include "p2p/base/ice_transport_internal.h"
@@ -25,6 +26,7 @@ namespace webrtc {
// struct with arguments to IceControllerFactoryInterface::Create
struct IceControllerFactoryArgs {
+ Environment env;
std::function<IceTransportStateInternal()> ice_transport_state_func;
std::function<IceRole()> ice_role_func;
std::function<bool(const Connection*)> is_connection_pruned_func;
diff --git a/third_party/libwebrtc/p2p/base/p2p_transport_channel.cc b/third_party/libwebrtc/p2p/base/p2p_transport_channel.cc
@@ -215,6 +215,7 @@ P2PTransportChannel::P2PTransportChannel(
ParseFieldTrials(env_.field_trials());
IceControllerFactoryArgs args{
+ .env = env_,
.ice_transport_state_func = [this] { return GetState(); },
.ice_role_func = [this] { return GetIceRole(); },
.is_connection_pruned_func =
diff --git a/third_party/libwebrtc/p2p/base/wrapping_active_ice_controller_unittest.cc b/third_party/libwebrtc/p2p/base/wrapping_active_ice_controller_unittest.cc
@@ -26,24 +26,13 @@
#include "rtc_base/event.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/thread.h"
+#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"
+namespace webrtc {
namespace {
-using ::webrtc::Connection;
-using ::webrtc::IceConfig;
-using ::webrtc::IceControllerFactoryArgs;
-using ::webrtc::IceControllerInterface;
-using ::webrtc::IceMode;
-using ::webrtc::IceRecheckEvent;
-using ::webrtc::IceSwitchReason;
-using ::webrtc::MockIceAgent;
-using ::webrtc::MockIceController;
-using ::webrtc::MockIceControllerFactory;
-using ::webrtc::NominationMode;
-using ::webrtc::WrappingActiveIceController;
-
using ::testing::_;
using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
@@ -52,11 +41,6 @@ using ::testing::Ref;
using ::testing::Return;
using ::testing::Sequence;
-using ::webrtc::AutoThread;
-using ::webrtc::Event;
-using ::webrtc::ScopedFakeClock;
-using ::webrtc::TimeDelta;
-
using NiceMockIceController = NiceMock<MockIceController>;
const Connection* kConnection = reinterpret_cast<const Connection*>(0xabcd);
@@ -72,7 +56,7 @@ constexpr TimeDelta kTick = TimeDelta::Millis(1);
TEST(WrappingActiveIceControllerTest, CreateLegacyIceControllerFromFactory) {
AutoThread main;
MockIceAgent agent;
- IceControllerFactoryArgs args;
+ IceControllerFactoryArgs args = {.env = CreateTestEnvironment()};
MockIceControllerFactory legacy_controller_factory;
EXPECT_CALL(legacy_controller_factory, RecordIceControllerCreated()).Times(1);
WrappingActiveIceController controller(&agent, &legacy_controller_factory,
@@ -314,3 +298,4 @@ TEST(WrappingActiveIceControllerTest, StartPingingAfterSortAndSwitch) {
}
} // namespace
+} // namespace webrtc