Implement support for Chrome task origin tracing. #2/4

This prepares TaskQueueBase sub classes to be able to migrate to
the location and traits-based API. It re-introduces a Location class
into the webrtc namespace, which is meant to be overridden by Chromium.

Bug: chromium:1416199
Change-Id: I712c7806a71b3b99b2a2bf95e555b357c21c15ae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/294381
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Markus Handell <handellm@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39400}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index d1b2c23..c336bee 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -65,6 +65,17 @@
   }
 }
 
+rtc_library("location") {
+  visibility = [ "*" ]
+  deps = [ "../rtc_base/system:rtc_export" ]
+  if (build_with_chromium) {
+    sources = [ "../../webrtc_overrides/api/location.h" ]
+    deps += [ "//base" ]
+  } else {
+    sources = [ "location.h" ]
+  }
+}
+
 rtc_library("rtp_headers") {
   visibility = [ "*" ]
   sources = [
diff --git a/api/location.h b/api/location.h
new file mode 100644
index 0000000..81e9a15
--- /dev/null
+++ b/api/location.h
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 2023 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_LOCATION_H_
+#define API_LOCATION_H_
+
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Location provides basic info where of an object was constructed, or was
+// significantly brought to life. This is a stripped down version of
+// https://source.chromium.org/chromium/chromium/src/+/main:base/location.h
+// that only specifies an interface compatible to how base::Location is
+// supposed to be used.
+// The declaration is overriden inside the Chromium build.
+class RTC_EXPORT Location {
+ public:
+  static Location Current() { return Location(); }
+};
+
+}  // namespace webrtc
+
+#endif  // API_LOCATION_H_
diff --git a/api/task_queue/BUILD.gn b/api/task_queue/BUILD.gn
index 69393b8..65bb1ae 100644
--- a/api/task_queue/BUILD.gn
+++ b/api/task_queue/BUILD.gn
@@ -17,6 +17,7 @@
   sources = [ "task_queue_base.cc" ]
 
   deps = [
+    "..:location",
     "../../rtc_base:checks",
     "../../rtc_base:macromagic",
     "../../rtc_base/system:rtc_export",
diff --git a/api/task_queue/task_queue_base.h b/api/task_queue/task_queue_base.h
index f78600d..9c4fdd7 100644
--- a/api/task_queue/task_queue_base.h
+++ b/api/task_queue/task_queue_base.h
@@ -14,6 +14,7 @@
 #include <utility>
 
 #include "absl/functional/any_invocable.h"
+#include "api/location.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/system/rtc_export.h"
 #include "rtc_base/thread_annotations.h"
@@ -62,7 +63,11 @@
   // Note that this guarantee does not apply to delayed tasks.
   //
   // May be called on any thread or task queue, including this task queue.
-  virtual void PostTask(absl::AnyInvocable<void() &&> task) = 0;
+  // TODO(crbug.com/1416199): Remove virtual and pass location of the caller
+  // once subclasses migrated.
+  virtual void PostTask(absl::AnyInvocable<void() &&> task) {
+    PostTaskImpl(std::move(task), PostTaskTraits{}, Location::Current());
+  }
 
   // Prefer PostDelayedTask() over PostDelayedHighPrecisionTask() whenever
   // possible.
@@ -87,8 +92,14 @@
   // https://crbug.com/webrtc/13583 for more information.
   //
   // May be called on any thread or task queue, including this task queue.
+  // TODO(crbug.com/1416199): Remove virtual and pass location of the caller
+  // once subclasses migrated.
   virtual void PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                               TimeDelta delay) = 0;
+                               TimeDelta delay) {
+    PostDelayedTaskImpl(std::move(task), delay,
+                        PostDelayedTaskTraits{.high_precision = false},
+                        Location::Current());
+  }
 
   // Prefer PostDelayedTask() over PostDelayedHighPrecisionTask() whenever
   // possible.
@@ -106,8 +117,14 @@
   // battery, when the timer precision can be as poor as 15 ms.
   //
   // May be called on any thread or task queue, including this task queue.
+  // TODO(crbug.com/1416199): Remove virtual and pass location of the caller
+  // once subclasses migrated.
   virtual void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                            TimeDelta delay) = 0;
+                                            TimeDelta delay) {
+    PostDelayedTaskImpl(std::move(task), delay,
+                        PostDelayedTaskTraits{.high_precision = true},
+                        Location::Current());
+  }
 
   // As specified by `precision`, calls either PostDelayedTask() or
   // PostDelayedHighPrecisionTask().
@@ -131,6 +148,18 @@
   bool IsCurrent() const { return Current() == this; }
 
  protected:
+  // This is currently only present here to simplify introduction of future
+  // planned task queue changes.
+  struct PostTaskTraits {};
+
+  struct PostDelayedTaskTraits {
+    // If `high_precision` is false, tasks may execute within up to a 17 ms
+    // leeway in addition to OS timer precision. Otherwise the task should be
+    // limited to OS timer precision. See PostDelayedTask() and
+    // PostDelayedHighPrecisionTask() for more information.
+    bool high_precision = false;
+  };
+
   class RTC_EXPORT CurrentTaskQueueSetter {
    public:
     explicit CurrentTaskQueueSetter(TaskQueueBase* task_queue);
@@ -142,6 +171,22 @@
     TaskQueueBase* const previous_;
   };
 
+  // Subclasses should implement this method to support the behavior defined in
+  // the PostTask and PostTaskTraits docs above.
+  // TODO(crbug.com/1416199): make pure virtual once subclasses migrate.
+  virtual void PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                            const PostTaskTraits& traits,
+                            const Location& location) {}
+
+  // Subclasses should implement this method to support the behavior defined in
+  // the PostDelayedTask/PostHighPrecisionDelayedTask and PostDelayedTaskTraits
+  // docs above.
+  // TODO(crbug.com/1416199): make pure virtual once subclasses migrate.
+  virtual void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                                   TimeDelta delay,
+                                   const PostDelayedTaskTraits& traits,
+                                   const Location& location) {}
+
   // Users of the TaskQueue should call Delete instead of directly deleting
   // this object.
   virtual ~TaskQueueBase() = default;
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 0d8bd4f..fc92b01 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -671,6 +671,7 @@
     deps = [
       ":checks",
       ":logging",
+      "../api:location",
       "../api/task_queue",
       "../api/units:time_delta",
       "synchronization:mutex",
@@ -976,6 +977,7 @@
     ":socket_server",
     ":timeutils",
     "../api:function_view",
+    "../api:location",
     "../api:refcountedbase",
     "../api:scoped_refptr",
     "../api:sequence_checker",
diff --git a/rtc_base/task_queue_gcd.cc b/rtc_base/task_queue_gcd.cc
index 6612b45..fb870e7 100644
--- a/rtc_base/task_queue_gcd.cc
+++ b/rtc_base/task_queue_gcd.cc
@@ -21,6 +21,7 @@
 
 #include "absl/functional/any_invocable.h"
 #include "absl/strings/string_view.h"
+#include "api/location.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/checks.h"
@@ -46,11 +47,15 @@
   TaskQueueGcd(absl::string_view queue_name, int gcd_priority);
 
   void Delete() override;
-  void PostTask(absl::AnyInvocable<void() &&> task) override;
-  void PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                       TimeDelta delay) override;
-  void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                    TimeDelta delay) override;
+
+ protected:
+  void PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                    const PostTaskTraits& traits,
+                    const Location& location) override;
+  void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                           TimeDelta delay,
+                           const PostDelayedTaskTraits& traits,
+                           const Location& location) override;
 
  private:
   struct TaskContext {
@@ -100,24 +105,22 @@
   dispatch_release(queue_);
 }
 
-void TaskQueueGcd::PostTask(absl::AnyInvocable<void() &&> task) {
+void TaskQueueGcd::PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                                const PostTaskTraits& traits,
+                                const Location& location) {
   auto* context = new TaskContext(this, std::move(task));
   dispatch_async_f(queue_, context, &RunTask);
 }
 
-void TaskQueueGcd::PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                                   TimeDelta delay) {
+void TaskQueueGcd::PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                                       TimeDelta delay,
+                                       const PostDelayedTaskTraits& traits,
+                                       const Location& location) {
   auto* context = new TaskContext(this, std::move(task));
   dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, delay.us() * NSEC_PER_USEC),
                    queue_, context, &RunTask);
 }
 
-void TaskQueueGcd::PostDelayedHighPrecisionTask(
-    absl::AnyInvocable<void() &&> task,
-    TimeDelta delay) {
-  PostDelayedTask(std::move(task), delay);
-}
-
 // static
 void TaskQueueGcd::RunTask(void* task_context) {
   std::unique_ptr<TaskContext> tc(static_cast<TaskContext*>(task_context));
diff --git a/rtc_base/task_queue_libevent.cc b/rtc_base/task_queue_libevent.cc
index 63633b5..e27c6ef 100644
--- a/rtc_base/task_queue_libevent.cc
+++ b/rtc_base/task_queue_libevent.cc
@@ -107,11 +107,15 @@
   TaskQueueLibevent(absl::string_view queue_name, rtc::ThreadPriority priority);
 
   void Delete() override;
-  void PostTask(absl::AnyInvocable<void() &&> task) override;
-  void PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                       TimeDelta delay) override;
-  void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                    TimeDelta delay) override;
+
+ protected:
+  void PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                    const PostTaskTraits& traits,
+                    const Location& location) override;
+  void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                           TimeDelta delay,
+                           const PostDelayedTaskTraits& traits,
+                           const Location& location) override;
 
  private:
   struct TimerEvent;
@@ -211,7 +215,9 @@
   delete this;
 }
 
-void TaskQueueLibevent::PostTask(absl::AnyInvocable<void() &&> task) {
+void TaskQueueLibevent::PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                                     const PostTaskTraits& traits,
+                                     const Location& location) {
   {
     MutexLock lock(&pending_lock_);
     bool had_pending_tasks = !pending_.empty();
@@ -250,8 +256,10 @@
   event_add(&timer->ev, &tv);
 }
 
-void TaskQueueLibevent::PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                                        TimeDelta delay) {
+void TaskQueueLibevent::PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                                            TimeDelta delay,
+                                            const PostDelayedTaskTraits& traits,
+                                            const Location& location) {
   if (IsCurrent()) {
     PostDelayedTaskOnTaskQueue(std::move(task), delay);
   } else {
@@ -265,12 +273,6 @@
   }
 }
 
-void TaskQueueLibevent::PostDelayedHighPrecisionTask(
-    absl::AnyInvocable<void() &&> task,
-    TimeDelta delay) {
-  PostDelayedTask(std::move(task), delay);
-}
-
 // static
 void TaskQueueLibevent::OnWakeup(int socket,
                                  short flags,  // NOLINT
diff --git a/rtc_base/task_queue_stdlib.cc b/rtc_base/task_queue_stdlib.cc
index 300873a..1ac01e1 100644
--- a/rtc_base/task_queue_stdlib.cc
+++ b/rtc_base/task_queue_stdlib.cc
@@ -52,11 +52,15 @@
   ~TaskQueueStdlib() override = default;
 
   void Delete() override;
-  void PostTask(absl::AnyInvocable<void() &&> task) override;
-  void PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                       TimeDelta delay) override;
-  void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                    TimeDelta delay) override;
+
+ protected:
+  void PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                    const PostTaskTraits& traits,
+                    const Location& location) override;
+  void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                           TimeDelta delay,
+                           const PostDelayedTaskTraits& traits,
+                           const Location& location) override;
 
  private:
   using OrderId = uint64_t;
@@ -156,7 +160,9 @@
   delete this;
 }
 
-void TaskQueueStdlib::PostTask(absl::AnyInvocable<void() &&> task) {
+void TaskQueueStdlib::PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                                   const PostTaskTraits& traits,
+                                   const Location& location) {
   {
     MutexLock lock(&pending_lock_);
     pending_queue_.push(
@@ -166,8 +172,10 @@
   NotifyWake();
 }
 
-void TaskQueueStdlib::PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                                      TimeDelta delay) {
+void TaskQueueStdlib::PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                                          TimeDelta delay,
+                                          const PostDelayedTaskTraits& traits,
+                                          const Location& location) {
   DelayedEntryTimeout delayed_entry;
   delayed_entry.next_fire_at_us = rtc::TimeMicros() + delay.us();
 
@@ -180,12 +188,6 @@
   NotifyWake();
 }
 
-void TaskQueueStdlib::PostDelayedHighPrecisionTask(
-    absl::AnyInvocable<void() &&> task,
-    TimeDelta delay) {
-  PostDelayedTask(std::move(task), delay);
-}
-
 TaskQueueStdlib::NextTask TaskQueueStdlib::GetNextTask() {
   NextTask result;
 
diff --git a/rtc_base/task_queue_win.cc b/rtc_base/task_queue_win.cc
index 9ea7fc6..7e46d58 100644
--- a/rtc_base/task_queue_win.cc
+++ b/rtc_base/task_queue_win.cc
@@ -160,11 +160,15 @@
   ~TaskQueueWin() override = default;
 
   void Delete() override;
-  void PostTask(absl::AnyInvocable<void() &&> task) override;
-  void PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                       TimeDelta delay) override;
-  void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                    TimeDelta delay) override;
+
+ protected:
+  void PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                    const PostTaskTraits& traits,
+                    const Location& location) override;
+  void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                           TimeDelta delay,
+                           const PostDelayedTaskTraits& traits,
+                           const Location& location) override;
   void RunPendingTasks();
 
  private:
@@ -217,14 +221,18 @@
   delete this;
 }
 
-void TaskQueueWin::PostTask(absl::AnyInvocable<void() &&> task) {
+void TaskQueueWin::PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                                const PostTaskTraits& traits,
+                                const Location& location) {
   MutexLock lock(&pending_lock_);
   pending_.push(std::move(task));
   ::SetEvent(in_queue_);
 }
 
-void TaskQueueWin::PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                                   TimeDelta delay) {
+void TaskQueueWin::PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                                       TimeDelta delay,
+                                       const PostDelayedTaskTraits& traits,
+                                       const Location& location) {
   if (delay <= TimeDelta::Zero()) {
     PostTask(std::move(task));
     return;
@@ -239,12 +247,6 @@
   }
 }
 
-void TaskQueueWin::PostDelayedHighPrecisionTask(
-    absl::AnyInvocable<void() &&> task,
-    TimeDelta delay) {
-  PostDelayedTask(std::move(task), delay);
-}
-
 void TaskQueueWin::RunPendingTasks() {
   while (true) {
     absl::AnyInvocable<void() &&> task;
diff --git a/rtc_base/thread.cc b/rtc_base/thread.cc
index 4790a6f..6f101ac 100644
--- a/rtc_base/thread.cc
+++ b/rtc_base/thread.cc
@@ -455,7 +455,9 @@
   return nullptr;
 }
 
-void Thread::PostTask(absl::AnyInvocable<void() &&> task) {
+void Thread::PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                          const PostTaskTraits& traits,
+                          const webrtc::Location& location) {
   if (IsQuitting()) {
     return;
   }
@@ -471,8 +473,10 @@
   WakeUpSocketServer();
 }
 
-void Thread::PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                          webrtc::TimeDelta delay) {
+void Thread::PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                                 webrtc::TimeDelta delay,
+                                 const PostDelayedTaskTraits& traits,
+                                 const webrtc::Location& location) {
   if (IsQuitting()) {
     return;
   }
@@ -719,7 +723,8 @@
   Join();
 }
 
-void Thread::BlockingCall(rtc::FunctionView<void()> functor) {
+void Thread::BlockingCallImpl(rtc::FunctionView<void()> functor,
+                              const webrtc::Location& location) {
   TRACE_EVENT0("webrtc", "Thread::BlockingCall");
 
   RTC_DCHECK(!IsQuitting());
@@ -823,12 +828,6 @@
   delete this;
 }
 
-void Thread::PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                             webrtc::TimeDelta delay) {
-  // This implementation does not support low precision yet.
-  PostDelayedHighPrecisionTask(std::move(task), delay);
-}
-
 bool Thread::IsProcessingMessagesForTesting() {
   return (owned_ || IsCurrent()) && !IsQuitting();
 }
diff --git a/rtc_base/thread.h b/rtc_base/thread.h
index 276a2e7..b3c824c 100644
--- a/rtc_base/thread.h
+++ b/rtc_base/thread.h
@@ -31,6 +31,7 @@
 #include "absl/base/attributes.h"
 #include "absl/functional/any_invocable.h"
 #include "api/function_view.h"
+#include "api/location.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/checks.h"
@@ -308,7 +309,11 @@
   // See ScopedDisallowBlockingCalls for details.
   // NOTE: Blocking calls are DISCOURAGED, consider if what you're doing can
   // be achieved with PostTask() and callbacks instead.
-  virtual void BlockingCall(FunctionView<void()> functor);
+  // TODO(crbug.com/1416199): Remove virtual and pass location of the caller
+  // once subclasses migrated.
+  virtual void BlockingCall(FunctionView<void()> functor) {
+    BlockingCallImpl(std::move(functor), webrtc::Location::Current());
+  }
 
   template <typename Functor,
             typename ReturnT = std::invoke_result_t<Functor>,
@@ -336,11 +341,6 @@
 
   // From TaskQueueBase
   void Delete() override;
-  void PostTask(absl::AnyInvocable<void() &&> task) override;
-  void PostDelayedTask(absl::AnyInvocable<void() &&> task,
-                       webrtc::TimeDelta delay) override;
-  void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
-                                    webrtc::TimeDelta delay) override;
 
   // ProcessMessages will process I/O and dispatch messages until:
   //  1) cms milliseconds have elapsed (returns true)
@@ -412,6 +412,18 @@
     mutable absl::AnyInvocable<void() &&> functor;
   };
 
+  // TaskQueueBase implementation.
+  void PostTaskImpl(absl::AnyInvocable<void() &&> task,
+                    const PostTaskTraits& traits,
+                    const webrtc::Location& location) override;
+  void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
+                           webrtc::TimeDelta delay,
+                           const PostDelayedTaskTraits& traits,
+                           const webrtc::Location& location) override;
+
+  virtual void BlockingCallImpl(FunctionView<void()> functor,
+                                const webrtc::Location& location);
+
   // Perform initialization, subclasses must call this from their constructor
   // if false was passed as init_queue to the Thread constructor.
   void DoInit();