Refactor RepeatingTaskHandle to use absl::AnyInvocable

Allow to use AnyInvocable in webrtc.
Demonstrate how AnyInvocable can make interface clearer to read and implement
Demonstrate that AnyInvocable can reduce binary size

Bug: None
Change-Id: I33cf33fac6ed3bf4c5e46077d1cd984ca0f253a3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/267165
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37380}
diff --git a/DEPS b/DEPS
index 6927d80..ce2332d 100644
--- a/DEPS
+++ b/DEPS
@@ -2494,6 +2494,7 @@
   "+absl/base/macros.h",
   "+absl/cleanup/cleanup.h",
   "+absl/container/inlined_vector.h",
+  "+absl/functional/any_invocable.h",
   "+absl/functional/bind_front.h",
   "+absl/memory/memory.h",
   "+absl/meta/type_traits.h",
diff --git a/g3doc/abseil-in-webrtc.md b/g3doc/abseil-in-webrtc.md
index 6f0b481..8561975 100644
--- a/g3doc/abseil-in-webrtc.md
+++ b/g3doc/abseil-in-webrtc.md
@@ -25,6 +25,7 @@
 
 ## **Allowed**
 
+* `absl::AnyInvocable`
 * `absl::bind_front`
 * `absl::Cleanup`
 * `absl::InlinedVector`
diff --git a/rtc_base/task_utils/BUILD.gn b/rtc_base/task_utils/BUILD.gn
index 04960b2..c01e82e 100644
--- a/rtc_base/task_utils/BUILD.gn
+++ b/rtc_base/task_utils/BUILD.gn
@@ -24,7 +24,10 @@
     "../../api/units:timestamp",
     "../../system_wrappers:system_wrappers",
   ]
-  absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
+  absl_deps = [
+    "//third_party/abseil-cpp/absl/functional:any_invocable",
+    "//third_party/abseil-cpp/absl/memory",
+  ]
 }
 
 rtc_library("pending_task_safety_flag") {
diff --git a/rtc_base/task_utils/repeating_task.cc b/rtc_base/task_utils/repeating_task.cc
index fc19b99..fa6ae79 100644
--- a/rtc_base/task_utils/repeating_task.cc
+++ b/rtc_base/task_utils/repeating_task.cc
@@ -10,6 +10,7 @@
 
 #include "rtc_base/task_utils/repeating_task.h"
 
+#include "absl/functional/any_invocable.h"
 #include "absl/memory/memory.h"
 #include "api/task_queue/pending_task_safety_flag.h"
 #include "api/task_queue/to_queued_task.h"
@@ -17,29 +18,53 @@
 #include "rtc_base/time_utils.h"
 
 namespace webrtc {
-namespace webrtc_repeating_task_impl {
+namespace {
 
-RepeatingTaskBase::RepeatingTaskBase(
+class RepeatingTask : public QueuedTask {
+ public:
+  RepeatingTask(TaskQueueBase* task_queue,
+                TaskQueueBase::DelayPrecision precision,
+                TimeDelta first_delay,
+                absl::AnyInvocable<TimeDelta()> task,
+                Clock* clock,
+                rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag);
+  ~RepeatingTask() override = default;
+
+ private:
+  bool Run() final;
+
+  TaskQueueBase* const task_queue_;
+  const TaskQueueBase::DelayPrecision precision_;
+  Clock* const clock_;
+  absl::AnyInvocable<TimeDelta()> task_;
+  // This is always finite.
+  Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_);
+  rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag_
+      RTC_GUARDED_BY(task_queue_);
+};
+
+RepeatingTask::RepeatingTask(
     TaskQueueBase* task_queue,
     TaskQueueBase::DelayPrecision precision,
     TimeDelta first_delay,
+    absl::AnyInvocable<TimeDelta()> task,
     Clock* clock,
     rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag)
     : task_queue_(task_queue),
       precision_(precision),
       clock_(clock),
+      task_(std::move(task)),
       next_run_time_(clock_->CurrentTime() + first_delay),
       alive_flag_(std::move(alive_flag)) {}
 
-RepeatingTaskBase::~RepeatingTaskBase() = default;
-
-bool RepeatingTaskBase::Run() {
+bool RepeatingTask::Run() {
   RTC_DCHECK_RUN_ON(task_queue_);
   // Return true to tell the TaskQueue to destruct this object.
   if (!alive_flag_->alive())
     return true;
 
-  TimeDelta delay = RunClosure();
+  webrtc_repeating_task_impl::RepeatingTaskImplDTraceProbeRun();
+  TimeDelta delay = task_();
   RTC_DCHECK_GE(delay, TimeDelta::Zero());
 
   // A delay of +infinity means that the task should not be run again.
@@ -61,7 +86,38 @@
   return false;
 }
 
-}  // namespace webrtc_repeating_task_impl
+}  // namespace
+
+RepeatingTaskHandle RepeatingTaskHandle::Start(
+    TaskQueueBase* task_queue,
+    absl::AnyInvocable<TimeDelta()> closure,
+    TaskQueueBase::DelayPrecision precision,
+    Clock* clock) {
+  auto alive_flag = PendingTaskSafetyFlag::CreateDetached();
+  webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeStart();
+  task_queue->PostTask(
+      std::make_unique<RepeatingTask>(task_queue, precision, TimeDelta::Zero(),
+                                      std::move(closure), clock, alive_flag));
+  return RepeatingTaskHandle(std::move(alive_flag));
+}
+
+// DelayedStart is equivalent to Start except that the first invocation of the
+// closure will be delayed by the given amount.
+RepeatingTaskHandle RepeatingTaskHandle::DelayedStart(
+    TaskQueueBase* task_queue,
+    TimeDelta first_delay,
+    absl::AnyInvocable<TimeDelta()> closure,
+    TaskQueueBase::DelayPrecision precision,
+    Clock* clock) {
+  auto alive_flag = PendingTaskSafetyFlag::CreateDetached();
+  webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeDelayedStart();
+  task_queue->PostDelayedTaskWithPrecision(
+      precision,
+      std::make_unique<RepeatingTask>(task_queue, precision, first_delay,
+                                      std::move(closure), clock, alive_flag),
+      first_delay.ms());
+  return RepeatingTaskHandle(std::move(alive_flag));
+}
 
 void RepeatingTaskHandle::Stop() {
   if (repeating_task_) {
diff --git a/rtc_base/task_utils/repeating_task.h b/rtc_base/task_utils/repeating_task.h
index 4d2b7eb..e5ea3d8 100644
--- a/rtc_base/task_utils/repeating_task.h
+++ b/rtc_base/task_utils/repeating_task.h
@@ -15,11 +15,10 @@
 #include <type_traits>
 #include <utility>
 
+#include "absl/functional/any_invocable.h"
 #include "api/task_queue/pending_task_safety_flag.h"
-#include "api/task_queue/queued_task.h"
 #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 {
@@ -31,64 +30,6 @@
 void RepeatingTaskHandleDTraceProbeDelayedStart();
 void RepeatingTaskImplDTraceProbeRun();
 
-class RepeatingTaskBase : public QueuedTask {
- public:
-  RepeatingTaskBase(TaskQueueBase* task_queue,
-                    TaskQueueBase::DelayPrecision precision,
-                    TimeDelta first_delay,
-                    Clock* clock,
-                    rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag);
-  ~RepeatingTaskBase() override;
-
- private:
-  virtual TimeDelta RunClosure() = 0;
-
-  bool Run() final;
-
-  TaskQueueBase* const task_queue_;
-  const TaskQueueBase::DelayPrecision precision_;
-  Clock* const clock_;
-  // This is always finite.
-  Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_);
-  rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag_
-      RTC_GUARDED_BY(task_queue_);
-};
-
-// The template closure pattern is based on rtc::ClosureTask. The provided
-// closure should have a TimeDelta return value, specifing the desired
-// non-negative interval to next repetition, or TimeDelta::PlusInfinity to
-// indicate that the task should be deleted and not called again.
-template <class Closure>
-class RepeatingTaskImpl final : public RepeatingTaskBase {
- public:
-  RepeatingTaskImpl(TaskQueueBase* task_queue,
-                    TaskQueueBase::DelayPrecision precision,
-                    TimeDelta first_delay,
-                    Closure&& closure,
-                    Clock* clock,
-                    rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag)
-      : RepeatingTaskBase(task_queue,
-                          precision,
-                          first_delay,
-                          clock,
-                          std::move(alive_flag)),
-        closure_(std::forward<Closure>(closure)) {
-    static_assert(
-        std::is_same<TimeDelta,
-                     typename std::invoke_result<decltype(&Closure::operator()),
-                                                 Closure>::type>::value,
-        "");
-  }
-
- private:
-  TimeDelta RunClosure() override {
-    RepeatingTaskImplDTraceProbeRun();
-    return closure_();
-  }
-
-  typename std::remove_const<
-      typename std::remove_reference<Closure>::type>::type closure_;
-};
 }  // namespace webrtc_repeating_task_impl
 
 // Allows starting tasks that repeat themselves on a TaskQueue indefinately
@@ -111,43 +52,21 @@
   // TaskQueue deletes it. It's perfectly fine to destroy the handle while the
   // task is running, since the repeated task is owned by the TaskQueue.
   // The tasks are scheduled onto the task queue using the specified precision.
-  template <class Closure>
   static RepeatingTaskHandle Start(TaskQueueBase* task_queue,
-                                   Closure&& closure,
+                                   absl::AnyInvocable<TimeDelta()> closure,
                                    TaskQueueBase::DelayPrecision precision =
                                        TaskQueueBase::DelayPrecision::kLow,
-                                   Clock* clock = Clock::GetRealTimeClock()) {
-    auto alive_flag = PendingTaskSafetyFlag::CreateDetached();
-    webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeStart();
-    task_queue->PostTask(
-        std::make_unique<
-            webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
-            task_queue, precision, TimeDelta::Zero(),
-            std::forward<Closure>(closure), clock, alive_flag));
-    return RepeatingTaskHandle(std::move(alive_flag));
-  }
+                                   Clock* clock = Clock::GetRealTimeClock());
 
   // 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,
+      absl::AnyInvocable<TimeDelta()> closure,
       TaskQueueBase::DelayPrecision precision =
           TaskQueueBase::DelayPrecision::kLow,
-      Clock* clock = Clock::GetRealTimeClock()) {
-    auto alive_flag = PendingTaskSafetyFlag::CreateDetached();
-    webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeDelayedStart();
-    task_queue->PostDelayedTaskWithPrecision(
-        precision,
-        std::make_unique<
-            webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
-            task_queue, precision, first_delay, std::forward<Closure>(closure),
-            clock, alive_flag),
-        first_delay.ms());
-    return RepeatingTaskHandle(std::move(alive_flag));
-  }
+      Clock* clock = Clock::GetRealTimeClock());
 
   // Stops future invocations of the repeating task closure. Can only be called
   // from the TaskQueue where the task is running. The closure is guaranteed to