Commit aa383484 authored by Joel Einbinder's avatar Joel Einbinder Committed by Commit Bot

DevTools: Wait for TapGesture before acking Input.dispatchTouchEvent

A follow up patch will convert chromedriver to use dispatchTouchEvent.

Bug: chromedriver:2144
Change-Id: Ib6b04791bb46f1d09dc1fc92de257f8160d5a4f8
Reviewed-on: https://chromium-review.googlesource.com/818086
Commit-Queue: Joel Einbinder <einbinder@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523965}
parent 159ff63c
...@@ -69,7 +69,8 @@ TouchEmulator::TouchEmulator(TouchEmulatorClient* client, ...@@ -69,7 +69,8 @@ TouchEmulator::TouchEmulator(TouchEmulatorClient* client,
double_tap_enabled_(true), double_tap_enabled_(true),
use_2x_cursors_(false), use_2x_cursors_(false),
emulated_stream_active_sequence_count_(0), emulated_stream_active_sequence_count_(0),
native_stream_active_sequence_count_(0) { native_stream_active_sequence_count_(0),
pending_taps_count_(0) {
DCHECK(client_); DCHECK(client_);
ResetState(); ResetState();
InitCursors(device_scale_factor, true); InitCursors(device_scale_factor, true);
...@@ -309,13 +310,15 @@ bool TouchEmulator::HandleTouchEventAck( ...@@ -309,13 +310,15 @@ bool TouchEmulator::HandleTouchEventAck(
if (is_sequence_end) if (is_sequence_end)
emulated_stream_active_sequence_count_--; emulated_stream_active_sequence_count_--;
int taps_count_before = pending_taps_count_;
const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
if (gesture_provider_) { if (gesture_provider_) {
gesture_provider_->OnTouchEventAck( gesture_provider_->OnTouchEventAck(
event.unique_touch_event_id, event_consumed, event.unique_touch_event_id, event_consumed,
InputEventAckStateIsSetNonBlocking(ack_result)); InputEventAckStateIsSetNonBlocking(ack_result));
} }
OnInjectedTouchCompleted(); if (pending_taps_count_ == taps_count_before)
OnInjectedTouchCompleted();
return true; return true;
} }
...@@ -326,6 +329,15 @@ bool TouchEmulator::HandleTouchEventAck( ...@@ -326,6 +329,15 @@ bool TouchEmulator::HandleTouchEventAck(
return false; return false;
} }
void TouchEmulator::OnGestureEventAck(const WebGestureEvent& event) {
if (event.GetType() != WebInputEvent::kGestureTap)
return;
if (pending_taps_count_) {
pending_taps_count_--;
OnInjectedTouchCompleted();
}
}
void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) { void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
WebGestureEvent gesture_event = WebGestureEvent gesture_event =
ui::CreateWebGestureEventFromGestureEventData(gesture); ui::CreateWebGestureEventFromGestureEventData(gesture);
...@@ -386,6 +398,11 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) { ...@@ -386,6 +398,11 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
suppress_next_fling_cancel_ = false; suppress_next_fling_cancel_ = false;
break; break;
case WebInputEvent::kGestureTap:
pending_taps_count_++;
client_->ForwardEmulatedGestureEvent(gesture_event);
break;
default: default:
// Everything else goes through. // Everything else goes through.
client_->ForwardEmulatedGestureEvent(gesture_event); client_->ForwardEmulatedGestureEvent(gesture_event);
......
...@@ -62,6 +62,8 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient { ...@@ -62,6 +62,8 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient {
bool HandleKeyboardEvent(const blink::WebKeyboardEvent& event); bool HandleKeyboardEvent(const blink::WebKeyboardEvent& event);
bool HandleTouchEvent(const blink::WebTouchEvent& event); bool HandleTouchEvent(const blink::WebTouchEvent& event);
void OnGestureEventAck(const blink::WebGestureEvent& event);
// Returns |true| if the event ack was consumed. Consumed ack should not // Returns |true| if the event ack was consumed. Consumed ack should not
// propagate any further. // propagate any further.
bool HandleTouchEventAck(const blink::WebTouchEvent& event, bool HandleTouchEventAck(const blink::WebTouchEvent& event,
...@@ -138,6 +140,10 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient { ...@@ -138,6 +140,10 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient {
blink::WebTouchEvent touch_event_; blink::WebTouchEvent touch_event_;
int emulated_stream_active_sequence_count_; int emulated_stream_active_sequence_count_;
int native_stream_active_sequence_count_; int native_stream_active_sequence_count_;
// TODO(einbinder): this relies on synchronous tap gesture generation and does
// not work for any other gestures. We should switch to callbacks which go
// through touches and gestures once that's available.
int pending_taps_count_;
// Whether we should suppress next fling cancel. This may happen when we // Whether we should suppress next fling cancel. This may happen when we
// did not send fling start in pinch mode. // did not send fling start in pinch mode.
......
...@@ -2388,6 +2388,9 @@ void RenderWidgetHostImpl::OnGestureEventAck( ...@@ -2388,6 +2388,9 @@ void RenderWidgetHostImpl::OnGestureEventAck(
for (auto& input_event_observer : input_event_observers_) for (auto& input_event_observer : input_event_observers_)
input_event_observer.OnInputEventAck(ack_source, ack_result, event.event); input_event_observer.OnInputEventAck(ack_source, ack_result, event.event);
if (touch_emulator_)
touch_emulator_->OnGestureEventAck(event.event);
if (view_) if (view_)
view_->GestureEventAck(event.event, ack_result); view_->GestureEventAck(event.event, ack_result);
} }
......
Tests that Input.dispatchTouchEvent waits for JavaScript event handlers to finish.
Dispatching event
touchEventPromise for has not resolved yet
Paused on debugger statement
Resumed
Recieved ack
(async function(testRunner) {
let {page, session, dp} = await testRunner.startBlank(`Tests that Input.dispatchTouchEvent waits for JavaScript event handlers to finish.`);
await session.evaluate(`
window.got = 'nope';
window.addEventListener('click', pauseEvent);
function pauseEvent(event) {
debugger;
event.preventDefault();
}
`);
function dumpError(message) {
if (message.error)
testRunner.log('Error: ' + message.error.message);
}
let resolved = false;
await dp.Debugger.enable();
await dp.Emulation.setTouchEmulationEnabled({enabled: true});
await dp.Emulation.setEmitTouchEventsForMouse({enabled: true});
testRunner.log('Dispatching event');
await dp.Input.dispatchTouchEvent({
type: 'touchStart',
touchPoints: [{
x: 100,
y: 100
}]
});
let touchEventPromise = dp.Input.dispatchTouchEvent({
type: 'touchEnd',
touchPoints: []
});
touchEventPromise.then(() => resolved = true);
await dp.Debugger.oncePaused();
await Promise.resolve(); // just in case
testRunner.log(resolved ? `touchEventPromise was resolved too early` : `touchEventPromise for has not resolved yet`)
testRunner.log('Paused on debugger statement');
await dp.Debugger.resume();
testRunner.log('Resumed');
dumpError(await touchEventPromise);
testRunner.log(`Recieved ack`);
testRunner.completeTest();
})
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