Propagate clock into BasicIceController

Bug: webrtc:42223992
Change-Id: I15e4d1a8c692e8a04f50d0f0b51cabecc584b0ab
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/407100
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45508}
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index ba483b7..2baa0e2 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -81,7 +81,10 @@
     ":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",
@@ -386,6 +389,7 @@
     ":ice_transport_internal",
     ":p2p_transport_channel_ice_field_trials",
     ":transport_description",
+    "../api/environment",
   ]
 }
 
diff --git a/p2p/base/basic_ice_controller.cc b/p2p/base/basic_ice_controller.cc
index ca8f826..8da13f5 100644
--- a/p2p/base/basic_ice_controller.cc
+++ b/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 @@
 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 @@
 }
 
 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 @@
                           : strong_ping_interval();
 
   const Connection* conn = nullptr;
-  if (TimeMillis() >= last_ping_sent_ms + ping_interval) {
+  if (Connection::AlignTime(env_.clock().CurrentTime()).ms() >=
+      last_ping_sent_ms + ping_interval) {
     conn = FindNextPingableConnection();
   }
   PingResult res(conn, std::min(ping_interval, check_receiving_interval()));
@@ -152,7 +155,7 @@
 
 // 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() &&
@@ -238,7 +241,7 @@
 // (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)) {
@@ -264,24 +267,24 @@
 
 bool BasicIceController::WritableConnectionPastPingInterval(
     const Connection* conn,
-    int64_t now) const {
-  int interval = CalculateActiveWritablePingInterval(conn, now);
-  return conn->last_ping_sent() + interval <= now;
+    Timestamp now) const {
+  TimeDelta interval = CalculateActiveWritablePingInterval(conn, now);
+  return conn->LastPingSent() + interval <= now;
 }
 
-int BasicIceController::CalculateActiveWritablePingInterval(
+TimeDelta BasicIceController::CalculateActiveWritablePingInterval(
     const Connection* conn,
-    int64_t now) const {
+    Timestamp now) const {
   // Ping each connection at a higher rate at least
   // MIN_PINGS_AT_WEAK_PING_INTERVAL times.
   if (conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL) {
-    return weak_ping_interval();
+    return TimeDelta::Millis(weak_ping_interval());
   }
 
-  int stable_interval =
-      config_.stable_writable_connection_ping_interval_or_default();
-  int weak_or_stablizing_interval = std::min(
-      stable_interval, WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
+  TimeDelta stable_interval = TimeDelta::Millis(
+      config_.stable_writable_connection_ping_interval_or_default());
+  TimeDelta weak_or_stablizing_interval = std::min(
+      stable_interval, kWeakOrStabilizingWritableConnectionPingInterval);
   // If the channel is weak or the connection is not stable yet, use the
   // weak_or_stablizing_interval.
   return (!weak() && conn->stable(now)) ? stable_interval
@@ -291,7 +294,8 @@
 // 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());
@@ -327,8 +331,10 @@
   // 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());
+           (now >=
+            conn->LastPingResponseReceived() +
+                TimeDelta::Millis(
+                    config_.backup_connection_ping_interval_or_default()));
   }
   // Don't ping inactive non-backup connections.
   if (!conn->active()) {
@@ -452,7 +458,7 @@
     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 +467,24 @@
     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;
@@ -519,7 +523,8 @@
 
   bool missed_receiving_unchanged_threshold = false;
   std::optional<int64_t> receiving_unchanged_threshold(
-      TimeMillis() - config_.receiving_switching_delay_or_default());
+      Connection::AlignTime(env_.clock().CurrentTime()).ms() -
+      config_.receiving_switching_delay_or_default());
   int cmp = CompareConnections(selected_connection_, new_connection,
                                receiving_unchanged_threshold,
                                &missed_receiving_unchanged_threshold);
diff --git a/p2p/base/basic_ice_controller.h b/p2p/base/basic_ice_controller.h
index b2aa3c3..66a0402 100644
--- a/p2p/base/basic_ice_controller.h
+++ b/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 @@
                     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 @@
   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;
-  int CalculateActiveWritablePingInterval(const Connection* conn,
-                                          int64_t now) const;
+                                          Timestamp now) const;
+  TimeDelta CalculateActiveWritablePingInterval(const Connection* conn,
+                                                Timestamp now) const;
 
   std::map<const Network*, const Connection*> GetBestConnectionByNetwork()
       const;
@@ -152,6 +155,7 @@
   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 @@
   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/p2p/base/ice_controller_factory_interface.h b/p2p/base/ice_controller_factory_interface.h
index 2f8754e..966d3e3 100644
--- a/p2p/base/ice_controller_factory_interface.h
+++ b/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 @@
 
 // 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/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index eee1092..82d854f 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -215,6 +215,7 @@
   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/p2p/base/wrapping_active_ice_controller_unittest.cc b/p2p/base/wrapping_active_ice_controller_unittest.cc
index 074f3b6..8b56013 100644
--- a/p2p/base/wrapping_active_ice_controller_unittest.cc
+++ b/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::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 @@
 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,
@@ -83,7 +67,8 @@
   AutoThread main;
   MockIceAgent agent;
   std::unique_ptr<MockIceController> will_move =
-      std::make_unique<MockIceController>(IceControllerFactoryArgs{});
+      std::make_unique<MockIceController>(
+          IceControllerFactoryArgs{.env = CreateTestEnvironment()});
   MockIceController* wrapped = will_move.get();
   WrappingActiveIceController controller(&agent, std::move(will_move));
 
@@ -120,7 +105,8 @@
   ScopedFakeClock clock;
   NiceMock<MockIceAgent> agent;
   std::unique_ptr<NiceMockIceController> will_move =
-      std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+      std::make_unique<NiceMockIceController>(
+          IceControllerFactoryArgs{.env = CreateTestEnvironment()});
   NiceMockIceController* wrapped = will_move.get();
   WrappingActiveIceController controller(&agent, std::move(will_move));
 
@@ -165,7 +151,8 @@
   ScopedFakeClock clock;
   NiceMock<MockIceAgent> agent;
   std::unique_ptr<NiceMockIceController> will_move =
-      std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+      std::make_unique<NiceMockIceController>(
+          IceControllerFactoryArgs{.env = CreateTestEnvironment()});
   NiceMockIceController* wrapped = will_move.get();
   WrappingActiveIceController controller(&agent, std::move(will_move));
 
@@ -223,7 +210,8 @@
 
   NiceMock<MockIceAgent> agent;
   std::unique_ptr<NiceMockIceController> will_move =
-      std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+      std::make_unique<NiceMockIceController>(
+          IceControllerFactoryArgs{.env = CreateTestEnvironment()});
   NiceMockIceController* wrapped = will_move.get();
   WrappingActiveIceController controller(&agent, std::move(will_move));
 
@@ -268,7 +256,8 @@
 
   NiceMock<MockIceAgent> agent;
   std::unique_ptr<NiceMockIceController> will_move =
-      std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+      std::make_unique<NiceMockIceController>(
+          IceControllerFactoryArgs{.env = CreateTestEnvironment()});
   NiceMockIceController* wrapped = will_move.get();
   WrappingActiveIceController controller(&agent, std::move(will_move));
 
@@ -319,3 +308,4 @@
 }
 
 }  // namespace
+}  // namespace webrtc