Commit 40c01af7 authored by Lan Wei's avatar Lan Wei Committed by Commit Bot

[Chromedriver] Fix PerformAction to support multi touch points cases

For the multiple touch points case, if we have one point move and the
other point stay still, such as
point 1: pointerdown, pointermove, pointerup
point 2: pointerdown, pause, pointerup
We should send five touch point events of "pointerdown", "pointerdown",
"pointermove", "pointerup", "pointerup" with pointer id 1, 2, 1, 1, 2.


Bug: 1020674
Change-Id: I2a738154fee5a4356b64467fd9483c69429217d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1895861Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Commit-Queue: Lan Wei <lanwei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712684}
parent c8f79f6a
......@@ -1358,7 +1358,9 @@ Status ExecutePerformActions(Session* session,
if (action_type == "pause") {
GetOptionalInt(action, "duration", &duration);
tick_duration = std::max(tick_duration, duration);
} else {
}
if (type != "none") {
bool async_dispatch_event = true;
if (j == last_action_index) {
async_dispatch_event = false;
......@@ -1366,28 +1368,30 @@ Status ExecutePerformActions(Session* session,
}
if (type == "key") {
std::list<KeyEvent> dispatch_key_events;
KeyEventBuilder builder;
Status status = ConvertKeyActionToKeyEvent(action, input_state,
action_type == "keyDown",
&dispatch_key_events);
if (status.IsError())
return status;
if (dispatch_key_events.size() > 0) {
const KeyEvent& event = dispatch_key_events.front();
if (action_type == "keyDown") {
session->input_cancel_list.emplace_back(
action_input_states[j], nullptr, nullptr, &event);
session->sticky_modifiers |= KeyToKeyModifiers(event.key);
} else if (action_type == "keyUp") {
session->sticky_modifiers &= ~KeyToKeyModifiers(event.key);
}
Status status = web_view->DispatchKeyEvents(dispatch_key_events,
async_dispatch_event);
if (action_type != "pause") {
std::list<KeyEvent> dispatch_key_events;
KeyEventBuilder builder;
Status status = ConvertKeyActionToKeyEvent(
action, input_state, action_type == "keyDown",
&dispatch_key_events);
if (status.IsError())
return status;
if (dispatch_key_events.size() > 0) {
const KeyEvent& event = dispatch_key_events.front();
if (action_type == "keyDown") {
session->input_cancel_list.emplace_back(
action_input_states[j], nullptr, nullptr, &event);
session->sticky_modifiers |= KeyToKeyModifiers(event.key);
} else if (action_type == "keyUp") {
session->sticky_modifiers &= ~KeyToKeyModifiers(event.key);
}
Status status = web_view->DispatchKeyEvents(
dispatch_key_events, async_dispatch_event);
if (status.IsError())
return status;
}
}
} else if (type == "pointer") {
std::string pointer_type;
......@@ -1433,54 +1437,57 @@ Status ExecutePerformActions(Session* session,
}
if (pointer_type == "mouse" || pointer_type == "pen") {
std::list<MouseEvent> dispatch_mouse_events;
int click_count = 0;
if (action_type == "pointerDown" || action_type == "pointerUp") {
std::string button;
action->GetString("button", &button);
button_type[id] = button;
click_count = 1;
} else if (buttons[id] == 0) {
button_type[id].clear();
}
MouseEvent event(StringToMouseEventType(action_type),
StringToMouseButton(button_type[id]),
action_locations[id].x(),
action_locations[id].y(), 0, buttons[id],
click_count);
event.pointer_type = StringToPointerType(pointer_type);
event.modifiers = session->sticky_modifiers;
if (event.type == kPressedMouseEventType) {
base::TimeTicks timestamp = base::TimeTicks::Now();
bool is_repeated_click = IsRepeatedClickEvent(
event.x, event.y, session->mouse_position.x,
session->mouse_position.y, session->click_count, timestamp,
session->mouse_click_timestamp);
event.click_count = is_repeated_click ? 2 : 1;
buttons[id] |= StringToModifierMouseButton(button_type[id]);
session->mouse_position = WebPoint(event.x, event.y);
session->click_count = event.click_count;
session->mouse_click_timestamp = timestamp;
session->input_cancel_list.emplace_back(
action_input_states[j], &event, nullptr, nullptr);
action_input_states[j]->SetInteger(
"pressed",
action_input_states[j]->FindKey("pressed")->GetInt() |
(1 << event.button));
} else if (event.type == kReleasedMouseEventType) {
event.click_count = session->click_count;
buttons[id] &= ~StringToModifierMouseButton(button_type[id]);
action_input_states[j]->SetInteger(
"pressed",
action_input_states[j]->FindKey("pressed")->GetInt() &
~(1 << event.button));
if (action_type != "pause") {
std::list<MouseEvent> dispatch_mouse_events;
int click_count = 0;
if (action_type == "pointerDown" ||
action_type == "pointerUp") {
std::string button;
action->GetString("button", &button);
button_type[id] = button;
click_count = 1;
} else if (buttons[id] == 0) {
button_type[id].clear();
}
MouseEvent event(StringToMouseEventType(action_type),
StringToMouseButton(button_type[id]),
action_locations[id].x(),
action_locations[id].y(), 0, buttons[id],
click_count);
event.pointer_type = StringToPointerType(pointer_type);
event.modifiers = session->sticky_modifiers;
if (event.type == kPressedMouseEventType) {
base::TimeTicks timestamp = base::TimeTicks::Now();
bool is_repeated_click = IsRepeatedClickEvent(
event.x, event.y, session->mouse_position.x,
session->mouse_position.y, session->click_count,
timestamp, session->mouse_click_timestamp);
event.click_count = is_repeated_click ? 2 : 1;
buttons[id] |= StringToModifierMouseButton(button_type[id]);
session->mouse_position = WebPoint(event.x, event.y);
session->click_count = event.click_count;
session->mouse_click_timestamp = timestamp;
session->input_cancel_list.emplace_back(
action_input_states[j], &event, nullptr, nullptr);
action_input_states[j]->SetInteger(
"pressed",
action_input_states[j]->FindKey("pressed")->GetInt() |
(1 << event.button));
} else if (event.type == kReleasedMouseEventType) {
event.click_count = session->click_count;
buttons[id] &= ~StringToModifierMouseButton(button_type[id]);
action_input_states[j]->SetInteger(
"pressed",
action_input_states[j]->FindKey("pressed")->GetInt() &
~(1 << event.button));
}
dispatch_mouse_events.push_back(event);
Status status = web_view->DispatchMouseEvents(
dispatch_mouse_events, session->GetCurrentFrameId(),
async_dispatch_event);
if (status.IsError())
return status;
}
dispatch_mouse_events.push_back(event);
Status status = web_view->DispatchMouseEvents(
dispatch_mouse_events, session->GetCurrentFrameId(),
async_dispatch_event);
if (status.IsError())
return status;
} else if (pointer_type == "touch") {
if (action_type == "pointerDown")
has_touch_start[id] = true;
......@@ -1497,12 +1504,12 @@ Status ExecutePerformActions(Session* session,
if (has_touch_start[id]) {
event.id = dispatch_touch_events.size();
dispatch_touch_events.push_back(event);
if (j == last_touch_index) {
Status status = web_view->DispatchTouchEventWithMultiPoints(
dispatch_touch_events, async_dispatch_event);
if (status.IsError())
return status;
}
}
if (j == last_touch_index) {
Status status = web_view->DispatchTouchEventWithMultiPoints(
dispatch_touch_events, async_dispatch_event);
if (status.IsError())
return status;
}
if (action_type == "pointerUp")
has_touch_start[id] = false;
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>TestDriver actions: two touch points with one moving one pause</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<style>
div#test1{
position: fixed;
top: 0;
left: 0;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<div id="test1">
</div>
<script>
let event_type = [];
let event_id = [];
async_test(t => {
let test1 = document.getElementById("test1");
document.getElementById("test1").addEventListener("pointerdown",
e => {event_type.push(e.type); event_id.push(e.pointerId);});
document.getElementById("test1").addEventListener("pointerup",
e => {event_type.push(e.type); event_id.push(e.pointerId);});
document.getElementById("test1").addEventListener("pointermove",
e => {event_type.push(e.type); event_id.push(e.pointerId);});
let actions = new test_driver.Actions()
.addPointer("touchPointer1", "touch")
.addPointer("touchPointer2", "touch")
.pointerMove(0, 0, {origin: test1, sourceName: "touchPointer1"})
.pointerMove(10, 0, {origin: test1, sourceName: "touchPointer2"})
.pointerDown({sourceName: "touchPointer1"})
.pointerDown({sourceName: "touchPointer2"})
.pointerMove(0, 10, {origin: test1, sourceName: "touchPointer1"})
.pointerUp({sourceName: "touchPointer1"})
.pointerUp({sourceName: "touchPointer2"});
actions.send()
.then(t.step_func_done(() => {assert_array_equals(event_type, ["pointerdown", "pointerdown", "pointermove", "pointerup", "pointerup"]);
assert_array_equals(event_id, [2, 3, 2, 2, 3]);}))
.catch(e => t.step_func(() => assert_unreached("Actions sequence failed " + e)));
});
</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