Add support for injecting Clock to RepeatingTaskHandle.

This will improve support for tests that use Clock as well as offer
a way to remove use of Sleep() in the tests.

Bug: none
Change-Id: I25fd0c6fc1b52ec0c917e56fae6807b136213d8d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/175566
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31305}
diff --git a/rtc_base/task_utils/BUILD.gn b/rtc_base/task_utils/BUILD.gn
index 1882cd9..32f72b8 100644
--- a/rtc_base/task_utils/BUILD.gn
+++ b/rtc_base/task_utils/BUILD.gn
@@ -21,6 +21,7 @@
     "../../api/task_queue",
     "../../api/units:time_delta",
     "../../api/units:timestamp",
+    "../../system_wrappers:system_wrappers",
     "../synchronization:sequence_checker",
     "//third_party/abseil-cpp/absl/memory",
   ]
diff --git a/rtc_base/task_utils/repeating_task.cc b/rtc_base/task_utils/repeating_task.cc
index 3b84701..574e633 100644
--- a/rtc_base/task_utils/repeating_task.cc
+++ b/rtc_base/task_utils/repeating_task.cc
@@ -17,11 +17,13 @@
 
 namespace webrtc {
 namespace webrtc_repeating_task_impl {
+
 RepeatingTaskBase::RepeatingTaskBase(TaskQueueBase* task_queue,
-                                     TimeDelta first_delay)
+                                     TimeDelta first_delay,
+                                     Clock* clock)
     : task_queue_(task_queue),
-      next_run_time_(Timestamp::Micros(rtc::TimeMicros()) + first_delay) {
-}
+      clock_(clock),
+      next_run_time_(clock_->CurrentTime() + first_delay) {}
 
 RepeatingTaskBase::~RepeatingTaskBase() = default;
 
@@ -39,7 +41,7 @@
     return true;
 
   RTC_DCHECK(delay.IsFinite());
-  TimeDelta lost_time = Timestamp::Micros(rtc::TimeMicros()) - next_run_time_;
+  TimeDelta lost_time = clock_->CurrentTime() - next_run_time_;
   next_run_time_ += delay;
   delay -= lost_time;
   delay = std::max(delay, TimeDelta::Zero());
diff --git a/rtc_base/task_utils/repeating_task.h b/rtc_base/task_utils/repeating_task.h
index f7ae55e..487b7d1 100644
--- a/rtc_base/task_utils/repeating_task.h
+++ b/rtc_base/task_utils/repeating_task.h
@@ -19,6 +19,7 @@
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "api/units/timestamp.h"
+#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 
@@ -27,7 +28,9 @@
 namespace webrtc_repeating_task_impl {
 class RepeatingTaskBase : public QueuedTask {
  public:
-  RepeatingTaskBase(TaskQueueBase* task_queue, TimeDelta first_delay);
+  RepeatingTaskBase(TaskQueueBase* task_queue,
+                    TimeDelta first_delay,
+                    Clock* clock);
   ~RepeatingTaskBase() override;
 
   void Stop();
@@ -38,6 +41,7 @@
   bool Run() final;
 
   TaskQueueBase* const task_queue_;
+  Clock* const clock_;
   // This is always finite, except for the special case where it's PlusInfinity
   // to signal that the task should stop.
   Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_);
@@ -49,8 +53,9 @@
  public:
   RepeatingTaskImpl(TaskQueueBase* task_queue,
                     TimeDelta first_delay,
-                    Closure&& closure)
-      : RepeatingTaskBase(task_queue, first_delay),
+                    Closure&& closure,
+                    Clock* clock)
+      : RepeatingTaskBase(task_queue, first_delay, clock),
         closure_(std::forward<Closure>(closure)) {
     static_assert(
         std::is_same<TimeDelta,
@@ -90,10 +95,11 @@
   // repeated task is owned by the TaskQueue.
   template <class Closure>
   static RepeatingTaskHandle Start(TaskQueueBase* task_queue,
-                                   Closure&& closure) {
+                                   Closure&& closure,
+                                   Clock* clock = Clock::GetRealTimeClock()) {
     auto repeating_task = std::make_unique<
         webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
-        task_queue, TimeDelta::Zero(), std::forward<Closure>(closure));
+        task_queue, TimeDelta::Zero(), std::forward<Closure>(closure), clock);
     auto* repeating_task_ptr = repeating_task.get();
     task_queue->PostTask(std::move(repeating_task));
     return RepeatingTaskHandle(repeating_task_ptr);
@@ -102,12 +108,14 @@
   // DelayedStart is equivalent to Start except that the first invocation of the
   // closure will be delayed by the given amount.
   template <class Closure>
-  static RepeatingTaskHandle DelayedStart(TaskQueueBase* task_queue,
-                                          TimeDelta first_delay,
-                                          Closure&& closure) {
+  static RepeatingTaskHandle DelayedStart(
+      TaskQueueBase* task_queue,
+      TimeDelta first_delay,
+      Closure&& closure,
+      Clock* clock = Clock::GetRealTimeClock()) {
     auto repeating_task = std::make_unique<
         webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
-        task_queue, first_delay, std::forward<Closure>(closure));
+        task_queue, first_delay, std::forward<Closure>(closure), clock);
     auto* repeating_task_ptr = repeating_task.get();
     task_queue->PostDelayedTask(std::move(repeating_task), first_delay.ms());
     return RepeatingTaskHandle(repeating_task_ptr);
diff --git a/rtc_base/task_utils/repeating_task_unittest.cc b/rtc_base/task_utils/repeating_task_unittest.cc
index 36d085c..2fb15d1 100644
--- a/rtc_base/task_utils/repeating_task_unittest.cc
+++ b/rtc_base/task_utils/repeating_task_unittest.cc
@@ -44,6 +44,21 @@
   MOCK_METHOD(void, Delete, ());
 };
 
+class MockTaskQueue : public TaskQueueBase {
+ public:
+  MockTaskQueue() : task_queue_setter_(this) {}
+
+  MOCK_METHOD(void, Delete, (), (override));
+  MOCK_METHOD(void, PostTask, (std::unique_ptr<QueuedTask> task), (override));
+  MOCK_METHOD(void,
+              PostDelayedTask,
+              (std::unique_ptr<QueuedTask> task, uint32_t milliseconds),
+              (override));
+
+ private:
+  CurrentTaskQueueSetter task_queue_setter_;
+};
+
 class MoveOnlyClosure {
  public:
   explicit MoveOnlyClosure(MockClosure* mock) : mock_(mock) {}
@@ -228,4 +243,37 @@
   // task queue destruction and running the desctructor closure.
 }
 
+TEST(RepeatingTaskTest, ClockIntegration) {
+  std::unique_ptr<QueuedTask> delayed_task;
+  uint32_t expected_ms = 0;
+  SimulatedClock clock(Timestamp::Millis(0));
+
+  NiceMock<MockTaskQueue> task_queue;
+  ON_CALL(task_queue, PostDelayedTask)
+      .WillByDefault(
+          Invoke([&delayed_task, &expected_ms](std::unique_ptr<QueuedTask> task,
+                                               uint32_t milliseconds) {
+            EXPECT_EQ(milliseconds, expected_ms);
+            delayed_task = std::move(task);
+          }));
+
+  expected_ms = 100;
+  RepeatingTaskHandle handle = RepeatingTaskHandle::DelayedStart(
+      &task_queue, TimeDelta::Millis(100),
+      [&clock]() {
+        EXPECT_EQ(Timestamp::Millis(100), clock.CurrentTime());
+        // Simulate work happening for 10ms.
+        clock.AdvanceTimeMilliseconds(10);
+        return TimeDelta::Millis(100);
+      },
+      &clock);
+
+  clock.AdvanceTimeMilliseconds(100);
+  QueuedTask* task_to_run = delayed_task.release();
+  expected_ms = 90;
+  EXPECT_FALSE(task_to_run->Run());
+  EXPECT_NE(nullptr, delayed_task.get());
+  handle.Stop();
+}
+
 }  // namespace webrtc