Commit 6b789219 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Revert "Reland "Unify input delay computations""

This reverts commit 4d820bcd.

Reason for revert: causes flakiness in browser_tests (907981).

Original change's description:
> Reland "Unify input delay computations"
> 
> This is a reland of 5d945012
> 
> Original change's description:
> > Unify input delay computations
> >
> > This CL unifies the timestamp computations for FID as reported to UMA and FID as
> > exposed in the Web Perf API. It moves the UMA reporting from the
> > PageWidgetDelegate to the EventTiming class. After this CL, the same types of
> > events are logged by both the UMA metric and the webexposed metric. In addition,
> > this CL removes the check that there are default actions or event handlers from
> > EventTiming, which means that now the webexposed API will expose events even if
> > they have no associated event handlers. In particular, this means that a click
> > will now trigger mousedown, click, and mouseup entries, in that order. This is
> > reflected in changes to the layout tests.
> >
> > Bug: 897656
> > Change-Id: Ibeee0ffe9ff1fc0df74585da96a8fd3a6f2d17dc
> > Reviewed-on: https://chromium-review.googlesource.com/c/1334564
> > Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
> > Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
> > Reviewed-by: Timothy Dresser <tdresser@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#610201}
> 
> TBR=dtapuska@chromium.org
> 
> Bug: 897656, 843184
> Change-Id: I4d97f2731fe957696c0e908d5ef3493235b52d49
> Reviewed-on: https://chromium-review.googlesource.com/c/1348254
> Reviewed-by: Nicolás Peña Moreno <npm@chromium.org>
> Reviewed-by: Timothy Dresser <tdresser@chromium.org>
> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#610499}

TBR=tdresser@chromium.org,dtapuska@chromium.org,npm@chromium.org

Change-Id: Ib5a3717393c14d5455bb97e92187d887465bef88
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 897656, 843184, 907981
Reviewed-on: https://chromium-review.googlesource.com/c/1349253Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610553}
parent e3fa0233
......@@ -5532,10 +5532,6 @@ crbug.com/902645 [ Retina ] transforms/3d/point-mapping/3d-point-mapping-origins
# Test is flaky under load
crbug.com/904389 http/tests/preload/delaying_onload_link_preload_after_discovery.html [ Failure Pass ]
# Tests flaky after an unrelated change involving a new swap promise
crbug.com/843184 xr/events_session_resetpose.html [ Pass Timeout ]
crbug.com/843184 xr/xrFrameOfReference_stage_updates.html [ Pass Failure ]
# These are known failures, being implemented
crbug.com/497522 css3/filters/backdrop-filter-boundary.html [ Failure ]
crbug.com/497522 css3/filters/backdrop-filter-bleeding.html [ Failure ]
......
......@@ -23,28 +23,23 @@
}
function validateEntries() {
const entries = performance.getEntriesByName('mousedown', 'event');
const entries = performance.getEntriesByName('click', 'event');
const onloadTime = performance.timing.loadEventStart - performance.timeOrigin;
const entriesBeforeOnload = entries.filter(
e => e.startTime < onloadTime);
assert_equals(entriesBeforeOnload.length, 1,
"Long latency mousedown events before onload should be buffered.");
"Long latency events before onload should be buffered.");
const entry = entriesBeforeOnload[0];
verifyClickEvent(entry, true);
const clicks = performance.getEntriesByName('click', 'event').filter(
e => e.startTime < onloadTime);
assert_equals(clicks.length, 1,
"Long latency click events before onload should be buffered.");
const click = clicks[0];
assert_greater_than(click.processingStart, processingStartMin,
assert_greater_than(entry.processingStart, processingStartMin,
"The entry should be processed later than processingStartMin.");
assert_greater_than(click.startTime, clickTimeMin,
assert_greater_than(entry.startTime, clickTimeMin,
"The entry's start time should be later than clickTimeMin.");
assert_greater_than_equal(firstClickStart, click.processingStart,
assert_greater_than_equal(firstClickStart, entry.processingStart,
"The processingStart must be before the onclick starts.")
assert_greater_than_equal(click.processingEnd, firstClickEnd,
assert_greater_than_equal(entry.processingEnd, firstClickEnd,
"The processingEnd must be after onclick finishes.");
const entriesAfterOnload = entries.filter(
......
......@@ -67,7 +67,7 @@
async_test(function(t) {
const observerPromise = new Promise((resolve, reject) => {
new PerformanceObserver(function(entryList) {
observedEntries = observedEntries.concat(entryList.getEntries().filter(entry => entry.name === 'mousedown'));
observedEntries = observedEntries.concat(entryList.getEntries());
if (observedEntries.length < 2) return;
resolve(observedEntries);
}).observe({ entryTypes: ['event'] });
......@@ -79,7 +79,7 @@
const bufferPromise = clickAndBlockMain('button').then(wait);
Promise.all([observerPromise, bufferPromise]).then((results) => {
t.step(verifyObserverEntries.bind(null, results[0]));
t.step(verifyBuffer.bind(null, performance.getEntriesByName('mousedown', 'event')));
t.step(verifyBuffer.bind(null, performance.getEntriesByName('click', 'event')));
t.done();
});
});
......
......@@ -22,12 +22,9 @@
new PerformanceObserver(t.step_func((entryList, obs) => {
const observedEntries = entryList.getEntries();
numEventsObserved += observedEntries.filter(entry =>
entry.entryType === 'event' && entry.name === 'mousedown').length;
numFirstInputObserved += observedEntries.filter(entry => {
if (entry.entryType === 'firstInput')
assert_equals(entry.name, 'mousedown');
return entry.entryType === 'firstInput';
}).length;
entry.entryType == 'event').length;
numFirstInputObserved += observedEntries.filter(entry =>
entry.entryType == 'firstInput').length;
if (numEventsObserved >= 2) {
assert_equals(performance.getEntriesByType('event').length, 0,
"There should be no buffered event entries.");
......@@ -35,7 +32,7 @@
"There should be no buffered firstInput entries.");
// There should be 2 event entries and one firstInput entry.
assert_equals(numEventsObserved, 2,
"There should be 2 observed event entries with name 'mousedown'.");
"There should be 2 observed event entries.");
assert_equals(numFirstInputObserved, 1,
"There should be only 1 observed firstInput entry.");
t.done();
......
......@@ -15,17 +15,16 @@ registration are lost
function verifyBufferAndObserverEntries(observedEntries) {
// Verify buffer entries
const bufferedEntries = performance.getEntriesByName('mousedown', 'event');
const bufferedEntries = performance.getEntriesByName('click', 'event');
const bufferedEntriesBeforeObserver = bufferedEntries.filter(e => e.startTime <
observerStart);
assert_equals(bufferedEntries.length, 0,
"Long latency events after onload should not be buffered."
);
// Filter to consider only mousedown, as we could have 'click' and 'mouseup' as well.
clickEntries = observedEntries.filter(entry => entry.name === 'mousedown');
assert_equals(clickEntries.length, 1, "Long latency task after observer start should be observed.");
const entry = clickEntries[0];
// Verify observer entries
assert_equals(observedEntries.length, 1, "Long latency task after observer start should be observed.");
const entry = observedEntries[0];
verifyClickEvent(entry);
assert_greater_than(entry.processingStart, processingStartMin,
"The entry's processing start should be later than processingStartMin.");
......@@ -60,7 +59,7 @@ registration are lost
*/
async_test(function(t) {
on_event(window, 'load', () => {
clickAndBlockMain('button').then(wait).then(()=> {
clickAndBlockMain('button').then(() => {
startObserver(t);
clickAndBlockMain('button').then(wait);
processingStartMin = performance.now();
......
......@@ -24,8 +24,7 @@
const observedEntries = entryList.getEntries();
assert_equals(observedEntries.length, 1);
assert_equals(observedEntries[0].entryType, 'firstInput');
assert_true(observedEntries[0].name === 'mousedown',
'Event type should be mousedown.');
assert_equals(observedEntries[0].name, 'click');
})).observe({ entryTypes: ['firstInput'] });
on_event(window, 'load', () => {
clickAndBlockMain('button').then(wait).then(() => {
......@@ -43,4 +42,4 @@
"Event Timing: check firstInput for a PerformanceObserver observing only firstInput."
);
</script>
</html>
</html>
\ No newline at end of file
......@@ -41,13 +41,13 @@
async_test(function(t) {
new PerformanceObserver(entryList => {
const observerCallbackTime = performance.now();
const entries = entryList.getEntries().filter(entry => entry.name === 'mousedown');
const entries = entryList.getEntries();
t.step(()=>{
assert_equals(entries.length, 1,
"Observe more than one entries: " +
JSON.stringify(entries) + ".");
assert_equals(entries[0].name, 'mousedown',
"The observed entry should be a mousedown");
assert_equals(entries[0].name, 'click',
"The observed entry should be a click");
assert_greater_than(observerCallbackTime, entries[0].startTime,
"assert(untrustedClickStart > entries[0].startTime) failed");
assert_greater_than(entries[0].startTime, trustedClickStart,
......
......@@ -14,7 +14,7 @@
});
window.addEventListener('load', e => {
observerPromise.then((observedEntries) => {
const bufferedEntries = performance.getEntriesByName('mousedown', 'event');
const bufferedEntries = performance.getEntriesByType('event');
const onloadTime = performance.timing.loadEventStart - performance.timeOrigin;
top.postMessage({
"bufferedEntries" : bufferedEntries,
......
function clickOnElement(id, resolve) {
function clickOnElement(id, callback) {
const element = document.getElementById(id);
const rect = element.getBoundingClientRect();
const xCenter = rect.x + rect.width / 2;
......@@ -11,10 +11,16 @@ function clickOnElement(id, resolve) {
{ name: "pointerUp" },
]
}];
var clickHandler = () => {
if (callback)
callback();
element.removeEventListener("click", clickHandler);
};
element.addEventListener("click", clickHandler);
if (!chrome || !chrome.gpuBenchmarking) {
reject();
} else {
chrome.gpuBenchmarking.pointerActionSequence(pointerActions, resolve);
chrome.gpuBenchmarking.pointerActionSequence(pointerActions);
}
}
......@@ -23,12 +29,12 @@ function mainThreadBusy(duration) {
while (performance.now() < now + duration);
}
// This method should receive an entry of type 'event'. |is_first| is true only
// This method should receive an entry of type 'event'. |is_false| is true only
// when the event also happens to correspond to the first event. In this case,
// the timings of the 'firstInput' entry should be equal to those of this entry.
function verifyClickEvent(entry, is_first=false) {
assert_true(entry.cancelable);
assert_equals(entry.name, 'mousedown');
assert_equals(entry.name, 'click');
assert_equals(entry.entryType, 'event');
assert_greater_than(entry.duration, 50,
"The entry's duration should be greater than 50ms.");
......@@ -39,9 +45,9 @@ function verifyClickEvent(entry, is_first=false) {
assert_greater_than_equal(entry.duration, entry.processingEnd - entry.startTime,
"The entry's duration must be at least as large as processingEnd - startTime.");
if (is_first) {
const firstInputs = performance.getEntriesByType('firstInput');
let firstInputs = performance.getEntriesByType('firstInput');
assert_equals(firstInputs.length, 1, 'There should be a single firstInput entry');
const firstInput = firstInputs[0];
let firstInput = firstInputs[0];
assert_equals(firstInput.name, entry.name);
assert_equals(firstInput.entryType, 'firstInput');
assert_equals(firstInput.startTime, entry.startTime);
......
......@@ -98,6 +98,7 @@ Event::Event(const AtomicString& event_type,
default_handled_(false),
was_initialized_(true),
is_trusted_(false),
executed_listener_or_default_action_(false),
prevent_default_called_on_uncancelable_event_(false),
legacy_did_listeners_throw_flag_(false),
fire_only_capture_listeners_at_target_(false),
......@@ -272,6 +273,10 @@ void Event::SetTarget(EventTarget* target) {
ReceivedTarget();
}
void Event::DoneDispatchingEventAtCurrentTarget() {
SetExecutedListenerOrDefaultAction();
}
void Event::SetRelatedTargetIfExists(EventTarget* related_target) {
if (IsMouseEvent()) {
ToMouseEvent(this)->SetRelatedTarget(related_target);
......
......@@ -148,7 +148,7 @@ class CORE_EXPORT Event : public ScriptWrappable {
// at the current target. It should only be used to influence UMA metrics
// and not change functionality since observing the presence of listeners
// is dangerous.
virtual void DoneDispatchingEventAtCurrentTarget() {}
virtual void DoneDispatchingEventAtCurrentTarget();
void SetRelatedTargetIfExists(EventTarget* related_target);
......@@ -292,6 +292,14 @@ class CORE_EXPORT Event : public ScriptWrappable {
return prevent_default_called_on_uncancelable_event_;
}
bool executedListenerOrDefaultAction() const {
return executed_listener_or_default_action_;
}
void SetExecutedListenerOrDefaultAction() {
executed_listener_or_default_action_ = true;
}
bool LegacyDidListenersThrow() const {
return legacy_did_listeners_throw_flag_;
}
......@@ -329,6 +337,9 @@ class CORE_EXPORT Event : public ScriptWrappable {
unsigned default_handled_ : 1;
unsigned was_initialized_ : 1;
unsigned is_trusted_ : 1;
// Only if at least one listeners or default actions are executed on an event
// does Event Timing report it.
unsigned executed_listener_or_default_action_ : 1;
// Whether preventDefault was called when |handling_passive_| is
// true. This field is reset on each call to SetHandlingPassive.
......
......@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/timing/event_timing.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
......@@ -139,10 +140,14 @@ DispatchEventResult EventDispatcher::Dispatch() {
return DispatchEventResult::kNotCanceled;
}
std::unique_ptr<EventTiming> eventTiming;
LocalFrame* frame = node_->GetDocument().GetFrame();
if (frame && frame->DomWindow()) {
eventTiming = std::make_unique<EventTiming>(frame->DomWindow());
eventTiming->WillDispatchEvent(*event_);
if (origin_trials::EventTimingEnabled(&node_->GetDocument())) {
LocalFrame* frame = node_->GetDocument().GetFrame();
if (frame && frame->DomWindow()) {
UseCounter::Count(node_->GetDocument(),
WebFeature::kPerformanceEventTimingConstructor);
eventTiming = std::make_unique<EventTiming>(frame->DomWindow());
eventTiming->WillDispatchEvent(*event_);
}
}
event_->GetEventPath().EnsureWindowEventContext();
......@@ -151,6 +156,7 @@ DispatchEventResult EventDispatcher::Dispatch() {
if (is_click && event_->isTrusted()) {
Document& document = node_->GetDocument();
LocalFrame* frame = document.GetFrame();
if (frame) {
// A genuine mouse click cannot be triggered by script so we don't expect
// there are any script in the stack.
......
......@@ -704,6 +704,7 @@ DispatchEventResult EventTarget::FireEventListeners(Event& event) {
// Only invoke the callback if event listeners were fired for this phase.
if (fired_event_listeners) {
event.DoneDispatchingEventAtCurrentTarget();
event.SetExecutedListenerOrDefaultAction();
// Only count uma metrics if we really fired an event listener.
Editor::CountEvent(GetExecutionContext(), event);
......
......@@ -5324,12 +5324,6 @@ TEST_F(WebViewTest, PointerDownUpFirstInputDelay) {
frame_test_helpers::LoadHTMLString(web_view->MainFrameImpl(),
"<html><body></body></html>", base_url);
// Add an event listener for pointerdown to ensure it is not optimized out
// before reaching the EventDispatcher.
WebLocalFrame* frame = web_view_helper_.LocalMainFrame();
frame->ExecuteScript(
WebScriptSource("addEventListener('pointerdown', function() {});"));
LocalFrame* main_frame = web_view->MainFrameImpl()->GetFrame();
ASSERT_NE(nullptr, main_frame);
......@@ -5347,9 +5341,6 @@ TEST_F(WebViewTest, PointerDownUpFirstInputDelay) {
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch), 5, 5);
pointer_down.SetTimeStamp(CurrentTimeTicks());
// Set this to the left button, needed for testing to behave properly.
pointer_down.SetModifiers(WebInputEvent::kLeftButtonDown);
pointer_down.button = WebPointerProperties::Button::kLeft;
clock.Advance(TimeDelta::FromMilliseconds(50));
web_view->HandleInputEvent(WebCoalescedInputEvent(pointer_down));
......@@ -5380,12 +5371,6 @@ TEST_F(WebViewTest, PointerDownCancelFirstInputDelay) {
frame_test_helpers::LoadHTMLString(web_view->MainFrameImpl(),
"<html><body></body></html>", base_url);
// Add an event listener for pointerdown to ensure it is not optimized out
// before reaching the EventDispatcher.
WebLocalFrame* frame = web_view_helper_.LocalMainFrame();
frame->ExecuteScript(
WebScriptSource("addEventListener('pointerdown', function() {});"));
LocalFrame* main_frame = web_view->MainFrameImpl()->GetFrame();
ASSERT_NE(nullptr, main_frame);
......@@ -5402,9 +5387,6 @@ TEST_F(WebViewTest, PointerDownCancelFirstInputDelay) {
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch), 5, 5);
pointer_down.SetTimeStamp(CurrentTimeTicks());
// Set this to the left button, needed for testing to behave properly.
pointer_down.SetModifiers(WebInputEvent::kLeftButtonDown);
pointer_down.button = WebPointerProperties::Button::kLeft;
clock.Advance(TimeDelta::FromMilliseconds(50));
web_view->HandleInputEvent(WebCoalescedInputEvent(pointer_down));
......
......@@ -4,8 +4,8 @@
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/platform/histogram.h"
......@@ -171,33 +171,37 @@ bool InteractiveDetector::PageWasBackgroundedSinceEvent(TimeTicks event_time) {
// This is called early enough in the pipeline that we don't need to worry about
// javascript dispatching untrusted input events.
void InteractiveDetector::HandleForInputDelay(const Event& event,
TimeTicks event_timestamp,
TimeTicks processing_start) {
// // This only happens sometimes on tests unrelated to InteractiveDetector.
// It's safe to ignore events that are not properly initialized.
if (event_timestamp.is_null())
void InteractiveDetector::HandleForInputDelay(const WebInputEvent& event) {
DCHECK(event.GetType() != WebInputEvent::kTouchStart);
// This only happens sometimes on tests unrelated to InteractiveDetector. It
// is safe to ignore events that are not properly initialized.
if (event.TimeStamp().is_null())
return;
// We can't report a pointerDown until the pointerUp, in case it turns into a
// scroll.
if (event.type() == event_type_names::kPointerdown) {
pending_pointerdown_delay_ = processing_start - event_timestamp;
pending_pointerdown_timestamp_ = event_timestamp;
if (event.GetType() == WebInputEvent::kPointerDown) {
pending_pointerdown_delay_ = CurrentTimeTicks() - event.TimeStamp();
pending_pointerdown_timestamp_ = event.TimeStamp();
return;
}
bool event_is_meaningful = event.type() == event_type_names::kPointerup ||
event.type() == event_type_names::kClick ||
event.type() == event_type_names::kKeydown ||
event.type() == event_type_names::kMousedown;
bool event_is_meaningful =
event.GetType() == WebInputEvent::kMouseDown ||
event.GetType() == WebInputEvent::kKeyDown ||
event.GetType() == WebInputEvent::kRawKeyDown ||
// We need to explicitly include tap, as if there are no listeners, we
// won't receive the pointer events.
event.GetType() == WebInputEvent::kGestureTap ||
event.GetType() == WebInputEvent::kPointerUp;
if (!event_is_meaningful)
return;
TimeDelta delay;
TimeTicks input_timestamp;
if (event.type() == event_type_names::kPointerup) {
TimeTicks event_timestamp;
if (event.GetType() == WebInputEvent::kPointerUp) {
// PointerUp by itself is not considered a significant input.
if (pending_pointerdown_timestamp_.is_null())
return;
......@@ -207,10 +211,10 @@ void InteractiveDetector::HandleForInputDelay(const Event& event,
// user gesture started by this event contained some non-scroll input, so we
// consider it reasonable to use the delay of the initial event.
delay = pending_pointerdown_delay_;
input_timestamp = pending_pointerdown_timestamp_;
event_timestamp = pending_pointerdown_timestamp_;
} else {
delay = processing_start - event_timestamp;
input_timestamp = event_timestamp;
delay = CurrentTimeTicks() - event.TimeStamp();
event_timestamp = event.TimeStamp();
}
pending_pointerdown_delay_ = base::TimeDelta();
......@@ -219,7 +223,7 @@ void InteractiveDetector::HandleForInputDelay(const Event& event,
if (page_event_times_.first_input_delay.is_zero()) {
page_event_times_.first_input_delay = delay;
page_event_times_.first_input_timestamp = input_timestamp;
page_event_times_.first_input_timestamp = event_timestamp;
input_delay_metrics_changed = true;
}
......@@ -227,16 +231,16 @@ void InteractiveDetector::HandleForInputDelay(const Event& event,
base::TimeDelta::FromMilliseconds(1),
base::TimeDelta::FromSeconds(60), 50);
UMA_HISTOGRAM_CUSTOM_TIMES(kHistogramInputTimestamp,
input_timestamp - page_event_times_.nav_start,
event_timestamp - page_event_times_.nav_start,
base::TimeDelta::FromMilliseconds(10),
base::TimeDelta::FromMinutes(10), 100);
// Only update longest input delay if page was not backgrounded while the
// input was queued.
if (delay > page_event_times_.longest_input_delay &&
!PageWasBackgroundedSinceEvent(input_timestamp)) {
!PageWasBackgroundedSinceEvent(event_timestamp)) {
page_event_times_.longest_input_delay = delay;
page_event_times_.longest_input_timestamp = input_timestamp;
page_event_times_.longest_input_timestamp = event_timestamp;
input_delay_metrics_changed = true;
}
......
......@@ -22,7 +22,7 @@
namespace blink {
class Document;
class Event;
class WebInputEvent;
// Detects when a page reaches First Idle and Time to Interactive. See
// https://goo.gl/SYt55W for detailed description and motivation of First Idle
......@@ -105,9 +105,7 @@ class CORE_EXPORT InteractiveDetector
// Process an input event, updating first_input_delay and
// first_input_timestamp if needed.
void HandleForInputDelay(const Event&,
TimeTicks event_timestamp,
TimeTicks processing_start);
void HandleForInputDelay(const WebInputEvent&);
// ContextLifecycleObserver
void ContextDestroyed(ExecutionContext*) override;
......
......@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/jank_tracker.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/page/autoscroll_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
......@@ -134,6 +135,14 @@ WebInputEventResult PageWidgetDelegate::HandleInputEvent(
Document* document = root->GetDocument();
DCHECK(document);
InteractiveDetector* interactive_detector(
InteractiveDetector::From(*document));
// interactive_detector is null in the OOPIF case.
// TODO(crbug.com/808089): report across OOPIFs.
if (interactive_detector)
interactive_detector->HandleForInputDelay(event);
if (RuntimeEnabledFeatures::JankTrackingEnabled()) {
if (LocalFrameView* view = document->View())
view->GetJankTracker().NotifyInput(event);
......
......@@ -7,9 +7,6 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
......@@ -28,75 +25,40 @@ bool EventTiming::ShouldReportForEventTiming(const Event& event) const {
event.isTrusted();
}
bool EventTiming::ShouldLogEvent(const Event& event) const {
return event.type() == event_type_names::kPointerdown ||
event.type() == event_type_names::kPointerup ||
event.type() == event_type_names::kClick ||
event.type() == event_type_names::kKeydown ||
event.type() == event_type_names::kMousedown;
}
void EventTiming::WillDispatchEvent(const Event& event) {
// Assume each event can be dispatched only once.
DCHECK(!finished_will_dispatch_event_);
if (!performance_ || !ShouldReportForEventTiming(event))
return;
// |event_is_important| is used to keep track of whether this event merits
// computing its processing start time. This should be the case in the
// following scenarios: 1. When the event is relevant to the logs sent to
// UMA/UKM/CrUX, as determined by ShouldLogEvent(). 2. When the EventTiming
// API is enabled, the buffer is not full, and we're still buffering entries
// (currently, before onload). 3. When the EventTiming API is enabled and
// there is a PerformanceObserver that could listen to an entry caused by this
// event.
bool event_is_important = ShouldLogEvent(event);
if (origin_trials::EventTimingEnabled(performance_->GetExecutionContext())) {
// TODO(npm): Get rid of this counter or at least rename it once origin
// trial is done.
UseCounter::Count(performance_->GetExecutionContext(),
WebFeature::kPerformanceEventTimingConstructor);
event_is_important |= performance_->ShouldBufferEventTiming() &&
!performance_->IsEventTimingBufferFull();
event_is_important |=
performance_->HasObserverFor(PerformanceEntry::kEvent);
event_is_important |=
performance_->HasObserverFor(PerformanceEntry::kFirstInput) &&
!performance_->FirstInputDetected();
}
if (event_is_important) {
// Although we screen the events for timing by setting these conditions here,
// we cannot assume that the conditions should still hold true in
// DidDispatchEvent. These conditions have to be re-tested before an entry is
// dispatched.
if ((performance_->ShouldBufferEventTiming() &&
!performance_->IsEventTimingBufferFull()) ||
performance_->HasObserverFor(PerformanceEntry::kEvent)
|| (performance_->HasObserverFor(PerformanceEntry::kFirstInput)
&& !performance_->FirstInputDetected())) {
processing_start_ = CurrentTimeTicks();
finished_will_dispatch_event_ = true;
}
}
void EventTiming::DidDispatchEvent(const Event& event) {
if (!finished_will_dispatch_event_)
if (!finished_will_dispatch_event_ ||
(!event.executedListenerOrDefaultAction() && !event.DefaultHandled())) {
return;
}
TimeTicks event_timestamp;
TimeTicks start_time;
if (event.IsPointerEvent())
event_timestamp = ToPointerEvent(&event)->OldestPlatformTimeStamp();
start_time = ToPointerEvent(&event)->OldestPlatformTimeStamp();
else
event_timestamp = event.PlatformTimeStamp();
start_time = event.PlatformTimeStamp();
if (origin_trials::EventTimingEnabled(performance_->GetExecutionContext())) {
performance_->RegisterEventTiming(event.type(), event_timestamp,
processing_start_, CurrentTimeTicks(),
event.cancelable());
}
Document* document = DynamicTo<Document>(performance_->GetExecutionContext());
if (!document)
return;
InteractiveDetector* interactive_detector =
InteractiveDetector::From(*document);
if (interactive_detector) {
interactive_detector->HandleForInputDelay(event, event_timestamp,
processing_start_);
}
performance_->RegisterEventTiming(event.type(), start_time, processing_start_,
CurrentTimeTicks(), event.cancelable());
}
} // namespace blink
......@@ -27,7 +27,6 @@ class CORE_EXPORT EventTiming final {
private:
bool ShouldReportForEventTiming(const Event& event) const;
bool ShouldLogEvent(const Event& event) const;
// The time the first event handler or default action started to execute.
TimeTicks processing_start_;
bool finished_will_dispatch_event_ = false;
......
......@@ -340,11 +340,11 @@ void WindowPerformance::RegisterEventTiming(const AtomicString& event_type,
bool cancelable) {
DCHECK(origin_trials::EventTimingEnabled(GetExecutionContext()));
DCHECK(!start_time.is_null());
DCHECK(!processing_start.is_null());
DCHECK(!processing_end.is_null());
DCHECK_GE(processing_end, processing_start);
// |start_time| could be null on some tests.
if (start_time.is_null() || !GetFrame())
if (!GetFrame())
return;
PerformanceEventTiming* entry = PerformanceEventTiming::Create(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment