LoAF: Refactor user callback probes

Instead of using the current probes with a state machine,
introduce new probes (InvokeEventHandler & InvokeCallback), which
also pass along the necessary parameters to extract source location
and the callback name without requiring the CallFunction probe.

Instead of relying on adding UserCallback probes everywhere,
rely on the callback name generated into CallbackFunctionBase.
(e.g. FrameRequestCallback instead of requestAnimationFrame).

Doing the above makes it so that all current user callbacks are
captured by default, without having to add new probes everywhere.

Source location capturing is simpler without CallFunction, and
also resolves bound functions.

Had to call the probe specifically for DOMTimers because the default
one doesn't have the correct name.

Removed several UserCallback probes introduced previously by a LoAF
CL.

TODO: perhaps we can move inspector-agent to use the new probes.

Bug: 1392685
Change-Id: I780a60513dc49fa15c7ea2d732f6dfad2530d5e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4376773
Reviewed-by: Yuki Shiino <yukishiino@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Reviewed-by: Yoav Weiss <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1125817}
diff --git a/long-animation-frame/tentative/loaf-desired-exec-time.html b/long-animation-frame/tentative/loaf-desired-exec-time.html
index fc1f2e8..dd35007 100644
--- a/long-animation-frame/tentative/loaf-desired-exec-time.html
+++ b/long-animation-frame/tentative/loaf-desired-exec-time.html
@@ -55,8 +55,8 @@
     timeAfterSetup = performance.now();
   });
   const entry = await entryPromise;
-  const script = entry.scripts.find(s => s.name === "Window.setTimeout");
-  assert_greater_than_equal(script.desiredExecutionStart, timeBeforeSetup + delay);
+  const script = entry.scripts.find(s => s.name === "TimerHandler:setTimeout");
+  assert_greater_than_equal(script.desiredExecutionStart, timeBeforeSetup + delay - 5);
   assert_less_than_equal(script.desiredExecutionStart, timeAfterSetup + delay);
 }, "desiredExecutionStart for setTimeout should be the setup time + delay");
 
@@ -72,7 +72,7 @@
     timeAfterSetup = performance.now();
   });
   const entry = await entryPromise;
-  const script = entry.scripts.find(s => s.name === "Scheduler.postTask");
+  const script = entry.scripts.find(s => s.name === "SchedulerPostTaskCallback");
   assert_greater_than_equal(script.desiredExecutionStart, timeBeforeSetup);
   assert_less_than_equal(script.desiredExecutionStart, timeAfterSetup);
 }, "desiredExecutionStart for Scheduler.postTask should be the time it was called");
@@ -82,7 +82,7 @@
   const rafPromise = new Promise(resolve => {
     // We fire two rAFs to ensure both of them receive the same
     // desiredExecutionStart
-    requestAnimationFrame(rafTime => {
+  requestAnimationFrame(rafTime => {
       busy_wait();
     })
     requestAnimationFrame(rafTime => {
@@ -93,7 +93,7 @@
   const entry = await entryPromise;
   const rafTime = await rafPromise;
   const scripts = entry.scripts.filter(
-    s => s.name === "Window.requestAnimationFrame");
+    s => s.name === "FrameRequestCallback");
   for (const script of scripts) {
     assert_approx_equals(script.desiredExecutionStart, rafTime, INTERNAL_OVERHEAD_DELAY_EPSILON);
   }
diff --git a/long-animation-frame/tentative/loaf-pause-duration.html b/long-animation-frame/tentative/loaf-pause-duration.html
index e70d011..6894164 100644
--- a/long-animation-frame/tentative/loaf-pause-duration.html
+++ b/long-animation-frame/tentative/loaf-pause-duration.html
@@ -19,7 +19,7 @@
     sync_xhr.open("GET", `/xhr/resources/delay.py?ms=${pause_duration}`, /*async=*/false);
     sync_xhr.send();
   }, 0), script => (
-        script.name === "Window.setTimeout" &&
+        script.name === "TimerHandler:setTimeout" &&
         script.duration >= very_long_frame_duration), t);
   assert_true("pauseDuration" in script);
   assert_greater_than(script.pauseDuration, pause_duration);
diff --git a/long-animation-frame/tentative/loaf-source-location-bound.html b/long-animation-frame/tentative/loaf-source-location-bound.html
new file mode 100644
index 0000000..8e80191
--- /dev/null
+++ b/long-animation-frame/tentative/loaf-source-location-bound.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Long Animation Frame Timing: source location extraction</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<h1>Long Animation Frame: source location extraction</h1>
+<div id="log"></div>
+<script>
+
+promise_test(async t => {
+  const [entry, script] = await expect_long_frame_with_script(() => {
+    const object = {};
+    requestAnimationFrame((function my_bound_function() {
+      busy_wait();
+    }).bind(object));
+  }, script => script.name === "FrameRequestCallback", t);
+  assert_true(script.sourceLocation.startsWith("my_bound_function"));
+}, "Source location should be extracted from bound functions");
+</script>
+</body>
diff --git a/long-animation-frame/tentative/loaf-user-callback.html b/long-animation-frame/tentative/loaf-user-callback.html
index bc8fdd0..3d868af 100644
--- a/long-animation-frame/tentative/loaf-user-callback.html
+++ b/long-animation-frame/tentative/loaf-user-callback.html
@@ -11,18 +11,17 @@
 <div id="log"></div>
 <script>
 
-
 test_self_user_callback(t =>
-    t.step_timeout(() => busy_wait()), "Window.setTimeout");
+    t.step_timeout(() => busy_wait()), "TimerHandler:setTimeout");
 
 test_self_user_callback(() => {
     const interval = setInterval(() => {
         busy_wait();
         clearInterval(interval);
     }, 10);
-}, "Window.setInterval");
+}, "TimerHandler:setInterval");
 test_self_user_callback(() =>
-    requestAnimationFrame(() => busy_wait()), "Window.requestAnimationFrame");
+    requestAnimationFrame(() => busy_wait()), "FrameRequestCallback");
 
 test_self_user_callback(t => {
     const element = document.createElement("div");
@@ -32,7 +31,7 @@
             busy_wait(very_long_frame_duration);
             observer.disconnect();
         }).observe(element);
-}, "ResizeObserver.callback");
+}, "ResizeObserverCallback");
 
 test_self_user_callback(t => {
     const element = document.createElement("div");
@@ -43,10 +42,15 @@
         observer.disconnect();
     }).observe(element);
     document.body.appendChild(element);
-}, "IntersectionObserver.callback");
+}, "IntersectionObserverCallback");
 
 test_self_user_callback(t =>
-    scheduler.postTask(() => busy_wait()), "Scheduler.postTask");
+    scheduler.postTask(() => busy_wait()), "SchedulerPostTaskCallback");
+
+  test_self_user_callback(t => {
+    new PerformanceObserver(() => busy_wait()).observe(
+      {type: "navigation", buffered: true});
+}, "PerformanceObserverCallback");
 
 </script>
 </body>
diff --git a/long-animation-frame/tentative/resources/utils.js b/long-animation-frame/tentative/resources/utils.js
index f956ed4..8781252 100644
--- a/long-animation-frame/tentative/resources/utils.js
+++ b/long-animation-frame/tentative/resources/utils.js
@@ -114,8 +114,8 @@
 
 }
 
-function test_self_user_callback(cb, name) {
-    test_loaf_script(cb, name, "user-callback");
+function test_self_user_callback(cb, name, label) {
+    test_loaf_script(cb, name, "user-callback", label);
 }
 
 function test_self_event_listener(cb, name) {