Commit 123e7153 authored by Haiyang Pan's avatar Haiyang Pan Committed by Commit Bot

Revert "Rewrite hr-timestamp/input-events.html to a browser test"

This reverts commit 4f6da930.

Reason for revert: InputEventBrowserTest.TouchStartEventTimeStamp is flaky in android pie CQ builder: https://analysis.chromium.org/p/chromium/flake-portal/flakes/occurrences?key=ag9zfmZpbmRpdC1mb3ItbWVyVwsSBUZsYWtlIkxjaHJvbWl1bUBjb250ZW50X2Jyb3dzZXJ0ZXN0c0BJbnB1dEV2ZW50QnJvd3NlclRlc3QuVG91Y2hTdGFydEV2ZW50VGltZVN0YW1wDA

It is flaky in several waterfall builders as well, starting at
https://ci.chromium.org/p/chromium/builders/ci/android-pie-x86-rel/1565
https://ci.chromium.org/p/chromium/builders/ci/android-pie-arm64-rel/5952
https://ci.chromium.org/p/chromium/builders/ci/android-asan/7107

Original change's description:
> Rewrite hr-timestamp/input-events.html to a browser test
> 
> hr-timestamp/input-events.htmlEvent timestamp tests that the received
> events on the page should be equal to the timestamp provided by the
> eventSender's recorded last event. But we should deprecate eventSender in
> the future, and GpuBenchmarking sends events based on the current system
> time, which cannot be equal to the received events' timestamp.
> 
> 
> Bug: 1047176
> Change-Id: I225dec07b1928ae254d61e8a8384ebfc7dab75e6
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2173421
> Commit-Queue: Lan Wei <lanwei@chromium.org>
> Reviewed-by: David Bokan <bokan@chromium.org>
> Reviewed-by: Majid Valipour <majidvp@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#790868}

TBR=bokan@chromium.org,lanwei@chromium.org,majidvp@chromium.org

Change-Id: Ifd5238546ed74824628a5d126b69a9fa37958ee3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1047176
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2314806Reviewed-by: default avatarHaiyang Pan <hypan@google.com>
Commit-Queue: Haiyang Pan <hypan@google.com>
Cr-Commit-Position: refs/heads/master@{#791011}
parent 00e78acc
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/browser/renderer_host/input/synthetic_pointer_driver.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/shell/browser/shell.h"
#include "content/shell/common/shell_switches.h"
#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "ui/events/blink/blink_features.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
namespace {
const std::string kEventListenerDataURL = R"HTML(
<!DOCTYPE html>
<meta name='viewport' content='width=device-width'/>
<style>
html, body {
margin: 0;
}
.spacer { height: 10000px; }
</style>
<div class=spacer></div>
<script type="text/javascript">
window.eventCounts =
{mousedown: 0, keydown: 0, touchstart: 0, click: 0, wheel: 0};
window.eventTimeStamp =
{mousedown: 0, keydown: 0, touchstart: 0, click: 0, wheel: 0};
function recordEvent(e) {
eventCounts[e.type]++;
if (eventCounts[e.type] == 1)
eventTimeStamp[e.type] = e.timeStamp;
}
for (var evt in eventCounts) {
document.addEventListener(evt, recordEvent);
}
document.title='ready';
</script>)HTML";
} // namespace
namespace content {
class InputEventBrowserTest : public ContentBrowserTest {
public:
InputEventBrowserTest() = default;
~InputEventBrowserTest() override = default;
RenderWidgetHostImpl* GetWidgetHost() {
return RenderWidgetHostImpl::From(
shell()->web_contents()->GetRenderViewHost()->GetWidget());
}
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
ContentBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kExposeInternalsForTesting);
}
void LoadURL(const std::string& page_data) {
const GURL data_url("data:text/html," + page_data);
EXPECT_TRUE(NavigateToURL(shell(), data_url));
RenderWidgetHostImpl* host = GetWidgetHost();
frame_observer_ = std::make_unique<RenderFrameSubmissionObserver>(
host->render_frame_metadata_provider());
host->GetView()->SetSize(gfx::Size(400, 400));
base::string16 ready_title(base::ASCIIToUTF16("ready"));
TitleWatcher watcher(shell()->web_contents(), ready_title);
ignore_result(watcher.WaitAndGetTitle());
// We need to wait until hit test data is available. We use our own
// HitTestRegionObserver here because we have the RenderWidgetHostImpl
// available.
HitTestRegionObserver observer(host->GetFrameSinkId());
observer.WaitForHitTestData();
}
// ContentBrowserTest:
void PostRunTestOnMainThread() override {
// Delete this before the WebContents is destroyed.
frame_observer_.reset();
ContentBrowserTest::PostRunTestOnMainThread();
}
bool URLLoaded() {
base::string16 ready_title(base::ASCIIToUTF16("ready"));
TitleWatcher watcher(shell()->web_contents(), ready_title);
const base::string16 title = watcher.WaitAndGetTitle();
return title == ready_title;
}
int ExecuteScriptAndExtractInt(const std::string& script) {
int value = 0;
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
shell(), "domAutomationController.send(" + script + ")", &value));
return value;
}
double ExecuteScriptAndExtractDouble(const std::string& script) {
double value = 0;
EXPECT_TRUE(content::ExecuteScriptAndExtractDouble(
shell(), "domAutomationController.send(" + script + ")", &value));
return value;
}
void SimulateSyntheticMousePressAt(base::TimeTicks event_time) {
DCHECK(URLLoaded());
std::unique_ptr<SyntheticPointerDriver> synthetic_pointer_driver =
SyntheticPointerDriver::Create(SyntheticGestureParams::MOUSE_INPUT);
RenderWidgetHostImpl* render_widget_host = GetWidgetHost();
auto* root_view = render_widget_host->GetView()->GetRootView();
std::unique_ptr<SyntheticGestureTarget> synthetic_gesture_target;
if (root_view)
synthetic_gesture_target = root_view->CreateSyntheticGestureTarget();
else
synthetic_gesture_target =
render_widget_host->GetView()->CreateSyntheticGestureTarget();
synthetic_pointer_driver->Press(50, 50, 0,
SyntheticPointerActionParams::Button::LEFT);
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(),
event_time);
synthetic_pointer_driver->Release(
0, SyntheticPointerActionParams::Button::LEFT);
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(),
event_time);
}
void SimulateSyntheticKeyDown(base::TimeTicks event_time) {
DCHECK(URLLoaded());
content::NativeWebKeyboardEvent event(
blink::WebKeyboardEvent::Type::kRawKeyDown,
blink::WebInputEvent::kNoModifiers, event_time);
event.windows_key_code = ui::VKEY_DOWN;
event.native_key_code =
ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::ARROW_DOWN);
event.dom_code = static_cast<int>(ui::DomCode::ARROW_DOWN);
event.dom_key = ui::DomKey::ARROW_DOWN;
GetWidgetHost()->ForwardKeyboardEvent(event);
}
void SimulateSyntheticTouchTapAt(base::TimeTicks event_time) {
DCHECK(URLLoaded());
std::unique_ptr<SyntheticPointerDriver> synthetic_pointer_driver =
SyntheticPointerDriver::Create(SyntheticGestureParams::TOUCH_INPUT);
RenderWidgetHostImpl* render_widget_host = GetWidgetHost();
auto* root_view = render_widget_host->GetView()->GetRootView();
std::unique_ptr<SyntheticGestureTarget> synthetic_gesture_target;
if (root_view)
synthetic_gesture_target = root_view->CreateSyntheticGestureTarget();
else
synthetic_gesture_target =
render_widget_host->GetView()->CreateSyntheticGestureTarget();
synthetic_pointer_driver->Press(50, 50, 0,
SyntheticPointerActionParams::Button::LEFT);
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(),
event_time);
synthetic_pointer_driver->Release(
0, SyntheticPointerActionParams::Button::LEFT);
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(),
event_time);
}
void SimulateSyntheticWheelScroll(base::TimeTicks event_time) {
DCHECK(URLLoaded());
double x = 50;
double y = 50;
blink::WebMouseWheelEvent wheel_event =
blink::SyntheticWebMouseWheelEventBuilder::Build(
x, y, x, y, 20, 20, 0,
ui::ScrollGranularity::kScrollByPrecisePixel);
wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
wheel_event.SetTimeStamp(event_time);
GetWidgetHost()->ForwardWheelEvent(wheel_event);
}
private:
std::unique_ptr<RenderFrameSubmissionObserver> frame_observer_;
DISALLOW_COPY_AND_ASSIGN(InputEventBrowserTest);
};
#if defined(OS_ANDROID)
// Android does not support synthetic mouse events.
// TODO(lanwei): support dispatching WebMouseEvent in
// SyntheticGestureTargetAndroid.
#define MAYBE_MouseDownEventTimeStamp DISABLED_MouseDownEventTimeStamp
#else
#define MAYBE_MouseDownEventTimeStamp MouseDownEventTimeStamp
#endif
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, MAYBE_MouseDownEventTimeStamp) {
LoadURL(kEventListenerDataURL);
MainThreadFrameObserver frame_observer(
shell()->web_contents()->GetRenderViewHost()->GetWidget());
base::TimeTicks event_time = base::TimeTicks::Now();
int64_t event_time_ms = event_time.since_origin().InMilliseconds();
SimulateSyntheticMousePressAt(event_time);
while (ExecuteScriptAndExtractInt("eventCounts.mousedown") == 0)
frame_observer.Wait();
int64_t monotonic_time = ExecuteScriptAndExtractDouble(
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp."
"mousedown)");
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.mousedown"));
EXPECT_EQ(event_time_ms, monotonic_time);
}
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, KeyDownEventTimeStamp) {
LoadURL(kEventListenerDataURL);
MainThreadFrameObserver frame_observer(
shell()->web_contents()->GetRenderViewHost()->GetWidget());
base::TimeTicks event_time = base::TimeTicks::Now();
int64_t event_time_ms = event_time.since_origin().InMilliseconds();
SimulateSyntheticKeyDown(event_time);
while (ExecuteScriptAndExtractInt("eventCounts.keydown") == 0)
frame_observer.Wait();
int64_t monotonic_time = ExecuteScriptAndExtractDouble(
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp."
"keydown)");
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.keydown"));
EXPECT_EQ(event_time_ms, monotonic_time);
}
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, TouchStartEventTimeStamp) {
LoadURL(kEventListenerDataURL);
MainThreadFrameObserver frame_observer(
shell()->web_contents()->GetRenderViewHost()->GetWidget());
base::TimeTicks event_time = base::TimeTicks::Now();
int64_t event_time_ms = event_time.since_origin().InMilliseconds();
SimulateSyntheticTouchTapAt(event_time);
while (ExecuteScriptAndExtractInt("eventCounts.touchstart") == 0)
frame_observer.Wait();
int64_t monotonic_time = ExecuteScriptAndExtractDouble(
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp."
"touchstart)");
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchstart"));
EXPECT_EQ(event_time_ms, monotonic_time);
}
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, ClickEventTimeStamp) {
LoadURL(kEventListenerDataURL);
MainThreadFrameObserver frame_observer(
shell()->web_contents()->GetRenderViewHost()->GetWidget());
base::TimeTicks event_time = base::TimeTicks::Now();
int64_t event_time_ms = event_time.since_origin().InMilliseconds();
SimulateSyntheticTouchTapAt(event_time);
while (ExecuteScriptAndExtractInt("eventCounts.click") == 0)
frame_observer.Wait();
int64_t monotonic_time = ExecuteScriptAndExtractDouble(
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp."
"click)");
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.click"));
EXPECT_EQ(event_time_ms, monotonic_time);
}
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, WheelEventTimeStamp) {
LoadURL(kEventListenerDataURL);
MainThreadFrameObserver frame_observer(
shell()->web_contents()->GetRenderViewHost()->GetWidget());
base::TimeTicks event_time = base::TimeTicks::Now();
int64_t event_time_ms = event_time.since_origin().InMilliseconds();
SimulateSyntheticWheelScroll(event_time);
while (ExecuteScriptAndExtractInt("eventCounts.wheel") == 0)
frame_observer.Wait();
int64_t monotonic_time = ExecuteScriptAndExtractDouble(
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp."
"wheel)");
EXPECT_GE(ExecuteScriptAndExtractInt("eventCounts.wheel"), 1);
EXPECT_EQ(event_time_ms, monotonic_time);
}
} // namespace content
...@@ -134,7 +134,7 @@ void SyntheticGestureTargetAura::DispatchWebGestureEventToPlatform( ...@@ -134,7 +134,7 @@ void SyntheticGestureTargetAura::DispatchWebGestureEventToPlatform(
: ui::EventMomentumPhase::END; : ui::EventMomentumPhase::END;
ui::ScrollEvent scroll_event(event_type, web_gesture.PositionInWidget(), ui::ScrollEvent scroll_event(event_type, web_gesture.PositionInWidget(),
web_gesture.PositionInWidget(), web_gesture.PositionInWidget(),
web_gesture.TimeStamp(), flags, ui::EventTimeForNow(), flags,
web_gesture.data.fling_start.velocity_x, web_gesture.data.fling_start.velocity_x,
web_gesture.data.fling_start.velocity_y, 0, 0, 2, web_gesture.data.fling_start.velocity_y, 0, 0, 2,
momentum_phase, ui::ScrollEventPhase::kNone); momentum_phase, ui::ScrollEventPhase::kNone);
...@@ -157,8 +157,8 @@ void SyntheticGestureTargetAura::DispatchWebMouseEventToPlatform( ...@@ -157,8 +157,8 @@ void SyntheticGestureTargetAura::DispatchWebMouseEventToPlatform(
} }
ui::MouseEvent mouse_event(event_type, web_mouse_event.PositionInWidget(), ui::MouseEvent mouse_event(event_type, web_mouse_event.PositionInWidget(),
web_mouse_event.PositionInWidget(), web_mouse_event.PositionInWidget(),
web_mouse_event.TimeStamp(), flags, ui::EventTimeForNow(), flags, changed_button_flags,
changed_button_flags, pointer_details); pointer_details);
aura::Window* window = GetWindow(); aura::Window* window = GetWindow();
mouse_event.ConvertLocationToTarget(window, window->GetRootWindow()); mouse_event.ConvertLocationToTarget(window, window->GetRootWindow());
......
...@@ -1036,7 +1036,6 @@ test("content_browsertests") { ...@@ -1036,7 +1036,6 @@ test("content_browsertests") {
"../browser/renderer_host/input/compositor_event_ack_browsertest.cc", "../browser/renderer_host/input/compositor_event_ack_browsertest.cc",
"../browser/renderer_host/input/event_latency_aura_browsertest.cc", "../browser/renderer_host/input/event_latency_aura_browsertest.cc",
"../browser/renderer_host/input/fling_browsertest.cc", "../browser/renderer_host/input/fling_browsertest.cc",
"../browser/renderer_host/input/input_event_browsertest.cc",
"../browser/renderer_host/input/interaction_mq_dynamic_browsertest.cc", "../browser/renderer_host/input/interaction_mq_dynamic_browsertest.cc",
"../browser/renderer_host/input/main_thread_event_queue_browsertest.cc", "../browser/renderer_host/input/main_thread_event_queue_browsertest.cc",
"../browser/renderer_host/input/mouse_latency_browsertest.cc", "../browser/renderer_host/input/mouse_latency_browsertest.cc",
......
...@@ -90,16 +90,6 @@ base::TimeDelta DocumentLoadTiming::MonotonicTimeToPseudoWallTime( ...@@ -90,16 +90,6 @@ base::TimeDelta DocumentLoadTiming::MonotonicTimeToPseudoWallTime(
return monotonic_time + reference_wall_time_ - reference_monotonic_time_; return monotonic_time + reference_wall_time_ - reference_monotonic_time_;
} }
int64_t DocumentLoadTiming::ZeroBasedDocumentTimeToMonotonicTime(
double dom_event_time) const {
if (reference_monotonic_time_.is_null())
return 0;
base::TimeTicks monotonic_time =
reference_monotonic_time_ +
base::TimeDelta::FromMillisecondsD(dom_event_time);
return monotonic_time.since_origin().InMilliseconds();
}
void DocumentLoadTiming::MarkNavigationStart() { void DocumentLoadTiming::MarkNavigationStart() {
// Allow the embedder to override navigationStart before we record it if // Allow the embedder to override navigationStart before we record it if
// they have a more accurate timestamp. // they have a more accurate timestamp.
......
...@@ -50,7 +50,6 @@ class CORE_EXPORT DocumentLoadTiming final { ...@@ -50,7 +50,6 @@ class CORE_EXPORT DocumentLoadTiming final {
base::TimeDelta MonotonicTimeToZeroBasedDocumentTime(base::TimeTicks) const; base::TimeDelta MonotonicTimeToZeroBasedDocumentTime(base::TimeTicks) const;
base::TimeDelta MonotonicTimeToPseudoWallTime(base::TimeTicks) const; base::TimeDelta MonotonicTimeToPseudoWallTime(base::TimeTicks) const;
int64_t ZeroBasedDocumentTimeToMonotonicTime(double dom_event_time) const;
void MarkNavigationStart(); void MarkNavigationStart();
void SetNavigationStart(base::TimeTicks); void SetNavigationStart(base::TimeTicks);
......
...@@ -3317,11 +3317,6 @@ double Internals::monotonicTimeToZeroBasedDocumentTime( ...@@ -3317,11 +3317,6 @@ double Internals::monotonicTimeToZeroBasedDocumentTime(
.InSecondsF(); .InSecondsF();
} }
int64_t Internals::zeroBasedDocumentTimeToMonotonicTime(double dom_event_time) {
return document_->Loader()->GetTiming().ZeroBasedDocumentTimeToMonotonicTime(
dom_event_time);
}
int64_t Internals::currentTimeTicks() { int64_t Internals::currentTimeTicks() {
return base::TimeTicks::Now().since_origin().InMicroseconds(); return base::TimeTicks::Now().since_origin().InMicroseconds();
} }
......
...@@ -543,10 +543,6 @@ class Internals final : public ScriptWrappable { ...@@ -543,10 +543,6 @@ class Internals final : public ScriptWrappable {
// document time in seconds // document time in seconds
double monotonicTimeToZeroBasedDocumentTime(double, ExceptionState&); double monotonicTimeToZeroBasedDocumentTime(double, ExceptionState&);
// Translate an event's DOMHighResTimeStamp in seconds into a monotonic time
// in milliseconds.
int64_t zeroBasedDocumentTimeToMonotonicTime(double dom_event_time);
// Returns the current time ticks (in microseconds). // Returns the current time ticks (in microseconds).
int64_t currentTimeTicks(); int64_t currentTimeTicks();
......
...@@ -366,11 +366,6 @@ ...@@ -366,11 +366,6 @@
boolean setScrollbarVisibilityInScrollableArea(Node node, boolean visible); boolean setScrollbarVisibilityInScrollableArea(Node node, boolean visible);
[RaisesException] double monotonicTimeToZeroBasedDocumentTime(double platformTime); [RaisesException] double monotonicTimeToZeroBasedDocumentTime(double platformTime);
// Translate an event's DOMHighResTimeStamp in seconds into a monotonic time
// in milliseconds.
long long zeroBasedDocumentTimeToMonotonicTime(double domHighResTimeStamp);
long long currentTimeTicks(); long long currentTimeTicks();
DOMString getScrollAnimationState(Node node); DOMString getScrollAnimationState(Node node);
......
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script type="text/javascript">
'use strict';
const testCases = {
'mousedown': () => eventSender.mouseDown(),
'keydown': () => eventSender.keyDown('x'),
'touchstart': () => {
eventSender.addTouchPoint(1, 1);
eventSender.touchStart();
},
'click': () => eventSender.gestureTap(1, 1),
'wheel': () => eventSender.mouseScrollBy(0, -50),
};
let receivedEvents = [];
for (let eventName in testCases)
createTest(eventName, testCases[eventName]);
function createTest(eventName, dispatchEventFn) {
async_test(function(t) {
document.addEventListener(eventName, t.step_func(function(e) {
receivedEvents.push(eventName);
// Prevent default to ensure contextmenu is not shown which can
// potentially hijack other events.
e.preventDefault();
const platformTimestamp = eventSender.lastEventTimestamp(); // in seconds
const expectedUnclampedTimestamp = internals.monotonicTimeToZeroBasedDocumentTime(platformTimestamp) * 1000; // in milliseconds
// Time clamping logic in Blink can introduce at most 2*100us of
// difference. Use 0.200001 instead of 0.2 to deal with floating
// point comparison issues.
assert_approx_equals(e.timeStamp, expectedUnclampedTimestamp, 0.200001);
t.done();
}));
dispatchEventFn();
t.step_timeout(function() {
assert_unreached("timeout with received events: " + receivedEvents.join(', '));
}, 5000);
}, "Event timestamp should be equal to the timestamp provided by the platform for " + eventName);
}
</script>
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