Commit 0e114bd4 authored by lanwei's avatar lanwei Committed by Commit Bot

Support multiple touch pointers

There was an issue when we handled multiple touch pointer actions.
SyntheticPointerAction should handle different actions from multiple
touch pointers.

Bug: 856638
Change-Id: I771181bcfe452631074c95874fd5c1a7807d3e74
Reviewed-on: https://chromium-review.googlesource.com/1113898
Commit-Queue: Lan Wei <lanwei@chromium.org>
Reviewed-by: default avatarElla Ge <eirage@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Reviewed-by: default avatarNavid Zolghadr <nzolghadr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570829}
parent fc7ebb70
...@@ -96,6 +96,22 @@ WebInputEvent::Type ToWebMouseEventType( ...@@ -96,6 +96,22 @@ WebInputEvent::Type ToWebMouseEventType(
return WebInputEvent::kUndefined; return WebInputEvent::kUndefined;
} }
WebInputEvent::Type WebTouchPointStateToEventType(
blink::WebTouchPoint::State state) {
switch (state) {
case blink::WebTouchPoint::kStateReleased:
return WebInputEvent::kTouchEnd;
case blink::WebTouchPoint::kStatePressed:
return WebInputEvent::kTouchStart;
case blink::WebTouchPoint::kStateMoved:
return WebInputEvent::kTouchMove;
case blink::WebTouchPoint::kStateCancelled:
return WebInputEvent::kTouchCancel;
default:
return WebInputEvent::kUndefined;
}
}
class MockSyntheticGesture : public SyntheticGesture { class MockSyntheticGesture : public SyntheticGesture {
public: public:
MockSyntheticGesture(bool* finished, int num_steps) MockSyntheticGesture(bool* finished, int num_steps)
...@@ -541,11 +557,13 @@ class MockSyntheticPointerTouchActionTarget ...@@ -541,11 +557,13 @@ class MockSyntheticPointerTouchActionTarget
const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event); const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
type_ = touch_event.GetType(); type_ = touch_event.GetType();
for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) { for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) {
if (WebTouchPointStateToEventType(touch_event.touches[i].state) != type_)
continue;
indexes_[i] = touch_event.touches[i].id; indexes_[i] = touch_event.touches[i].id;
positions_[i] = gfx::PointF(touch_event.touches[i].PositionInWidget()); positions_[i] = gfx::PointF(touch_event.touches[i].PositionInWidget());
states_[i] = touch_event.touches[i].state; states_[i] = touch_event.touches[i].state;
} }
touch_length_ = touch_event.touches_length;
num_actions_dispatched_++; num_actions_dispatched_++;
} }
...@@ -581,16 +599,12 @@ class MockSyntheticPointerTouchActionTarget ...@@ -581,16 +599,12 @@ class MockSyntheticPointerTouchActionTarget
testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly( testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly(
const std::vector<SyntheticPointerActionParams>& params_list) { const std::vector<SyntheticPointerActionParams>& params_list) {
if (touch_length_ != params_list.size()) {
return testing::AssertionFailure() << "Touch point length was "
<< touch_length_ << ", expected "
<< params_list.size() << ".";
}
testing::AssertionResult result = testing::AssertionSuccess(); testing::AssertionResult result = testing::AssertionSuccess();
for (size_t i = 0; i < params_list.size(); ++i) { for (size_t i = 0; i < params_list.size(); ++i) {
result = SyntheticTouchActionDispatchedCorrectly(params_list[i], if (params_list[i].pointer_action_type() !=
params_list[i].index()); SyntheticPointerActionParams::PointerActionType::IDLE)
result = SyntheticTouchActionDispatchedCorrectly(
params_list[i], params_list[i].index());
if (result == testing::AssertionFailure()) if (result == testing::AssertionFailure())
return result; return result;
} }
...@@ -599,7 +613,6 @@ class MockSyntheticPointerTouchActionTarget ...@@ -599,7 +613,6 @@ class MockSyntheticPointerTouchActionTarget
private: private:
gfx::PointF positions_[kTouchPointersLength]; gfx::PointF positions_[kTouchPointersLength];
unsigned touch_length_;
int indexes_[kTouchPointersLength]; int indexes_[kTouchPointersLength];
WebTouchPoint::State states_[kTouchPointersLength]; WebTouchPoint::State states_[kTouchPointersLength];
}; };
...@@ -1655,7 +1668,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) { ...@@ -1655,7 +1668,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
static_cast<MockSyntheticPointerTouchActionTarget*>(target_); static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
EXPECT_EQ(1, num_success_); EXPECT_EQ(1, num_success_);
EXPECT_EQ(0, num_failure_); EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 1); EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 2);
EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly( EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly(
param_list)); param_list));
...@@ -1676,7 +1689,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) { ...@@ -1676,7 +1689,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
EXPECT_EQ(2, num_success_); EXPECT_EQ(2, num_success_);
EXPECT_EQ(0, num_failure_); EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 2); EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 4);
EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly( EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly(
param_list)); param_list));
...@@ -1693,7 +1706,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) { ...@@ -1693,7 +1706,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
EXPECT_EQ(3, num_success_); EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_); EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 3); EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 5);
EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly( EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly(
param_list)); param_list));
} }
......
...@@ -79,8 +79,9 @@ SyntheticPointerAction::ForwardTouchOrMouseInputEvents( ...@@ -79,8 +79,9 @@ SyntheticPointerAction::ForwardTouchOrMouseInputEvents(
case SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED: case SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED:
return INVALID; return INVALID;
} }
synthetic_pointer_driver_->DispatchEvent(target, timestamp);
} }
synthetic_pointer_driver_->DispatchEvent(target, timestamp);
num_actions_dispatched_++; num_actions_dispatched_++;
if (num_actions_dispatched_ == params_.params.size()) if (num_actions_dispatched_ == params_.params.size())
return DONE; return DONE;
......
...@@ -60,6 +60,22 @@ WebInputEvent::Type ToWebMouseEventType( ...@@ -60,6 +60,22 @@ WebInputEvent::Type ToWebMouseEventType(
return WebInputEvent::kUndefined; return WebInputEvent::kUndefined;
} }
WebInputEvent::Type WebTouchPointStateToEventType(
blink::WebTouchPoint::State state) {
switch (state) {
case blink::WebTouchPoint::kStateReleased:
return WebInputEvent::kTouchEnd;
case blink::WebTouchPoint::kStatePressed:
return WebInputEvent::kTouchStart;
case blink::WebTouchPoint::kStateMoved:
return WebInputEvent::kTouchMove;
case blink::WebTouchPoint::kStateCancelled:
return WebInputEvent::kTouchCancel;
default:
return WebInputEvent::kUndefined;
}
}
class MockSyntheticPointerActionTarget : public SyntheticGestureTarget { class MockSyntheticPointerActionTarget : public SyntheticGestureTarget {
public: public:
MockSyntheticPointerActionTarget() {} MockSyntheticPointerActionTarget() {}
...@@ -107,11 +123,13 @@ class MockSyntheticPointerTouchActionTarget ...@@ -107,11 +123,13 @@ class MockSyntheticPointerTouchActionTarget
const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event); const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
type_ = touch_event.GetType(); type_ = touch_event.GetType();
for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) { for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) {
if (WebTouchPointStateToEventType(touch_event.touches[i].state) != type_)
continue;
indexes_[i] = touch_event.touches[i].id; indexes_[i] = touch_event.touches[i].id;
positions_[i] = gfx::PointF(touch_event.touches[i].PositionInWidget()); positions_[i] = gfx::PointF(touch_event.touches[i].PositionInWidget());
states_[i] = touch_event.touches[i].state; states_[i] = touch_event.touches[i].state;
} }
touch_length_ = touch_event.touches_length;
} }
testing::AssertionResult SyntheticTouchActionDispatchedCorrectly( testing::AssertionResult SyntheticTouchActionDispatchedCorrectly(
...@@ -146,16 +164,12 @@ class MockSyntheticPointerTouchActionTarget ...@@ -146,16 +164,12 @@ class MockSyntheticPointerTouchActionTarget
testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly( testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly(
const std::vector<SyntheticPointerActionParams>& params_list) { const std::vector<SyntheticPointerActionParams>& params_list) {
if (touch_length_ != params_list.size()) {
return testing::AssertionFailure() << "Touch point length was "
<< touch_length_ << ", expected "
<< params_list.size() << ".";
}
testing::AssertionResult result = testing::AssertionSuccess(); testing::AssertionResult result = testing::AssertionSuccess();
for (size_t i = 0; i < params_list.size(); ++i) { for (size_t i = 0; i < params_list.size(); ++i) {
result = SyntheticTouchActionDispatchedCorrectly(params_list[i], if (params_list[i].pointer_action_type() !=
params_list[i].index()); SyntheticPointerActionParams::PointerActionType::IDLE)
result = SyntheticTouchActionDispatchedCorrectly(
params_list[i], params_list[i].index());
if (result == testing::AssertionFailure()) if (result == testing::AssertionFailure())
return result; return result;
} }
...@@ -169,7 +183,6 @@ class MockSyntheticPointerTouchActionTarget ...@@ -169,7 +183,6 @@ class MockSyntheticPointerTouchActionTarget
private: private:
gfx::PointF positions_[WebTouchEvent::kTouchesLengthCap]; gfx::PointF positions_[WebTouchEvent::kTouchesLengthCap];
unsigned touch_length_;
int indexes_[WebTouchEvent::kTouchesLengthCap]; int indexes_[WebTouchEvent::kTouchesLengthCap];
WebTouchPoint::State states_[WebTouchEvent::kTouchesLengthCap]; WebTouchPoint::State states_[WebTouchEvent::kTouchesLengthCap];
}; };
......
...@@ -65,7 +65,8 @@ bool MakeUITouchEventsFromWebTouchEvents( ...@@ -65,7 +65,8 @@ bool MakeUITouchEventsFromWebTouchEvents(
int flags = ui::WebEventModifiersToEventFlags(touch.GetModifiers()); int flags = ui::WebEventModifiersToEventFlags(touch.GetModifiers());
base::TimeTicks timestamp = touch.TimeStamp(); base::TimeTicks timestamp = touch.TimeStamp();
for (unsigned i = 0; i < touch.touches_length; ++i) { unsigned count = 0;
for (unsigned i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; ++i) {
const blink::WebTouchPoint& point = touch.touches[i]; const blink::WebTouchPoint& point = touch.touches[i];
if (WebTouchPointStateToEventType(point.state) != type) if (WebTouchPointStateToEventType(point.state) != type)
continue; continue;
...@@ -84,6 +85,8 @@ bool MakeUITouchEventsFromWebTouchEvents( ...@@ -84,6 +85,8 @@ bool MakeUITouchEventsFromWebTouchEvents(
uievent->set_root_location_f(location); uievent->set_root_location_f(location);
uievent->set_latency(touch_with_latency.latency); uievent->set_latency(touch_with_latency.latency);
list->push_back(std::move(uievent)); list->push_back(std::move(uievent));
if (++count >= touch.touches_length)
break;
} }
return true; return true;
} }
......
...@@ -166,21 +166,26 @@ SyntheticWebTouchEvent::SyntheticWebTouchEvent() : WebTouchEvent() { ...@@ -166,21 +166,26 @@ SyntheticWebTouchEvent::SyntheticWebTouchEvent() : WebTouchEvent() {
void SyntheticWebTouchEvent::ResetPoints() { void SyntheticWebTouchEvent::ResetPoints() {
int activePointCount = 0; int activePointCount = 0;
for (unsigned int i = 0; i < touches_length; ++i) { unsigned count = 0;
for (unsigned int i = 0; i < kTouchesLengthCap; ++i) {
switch (touches[i].state) { switch (touches[i].state) {
case WebTouchPoint::kStatePressed: case WebTouchPoint::kStatePressed:
case WebTouchPoint::kStateMoved: case WebTouchPoint::kStateMoved:
case WebTouchPoint::kStateStationary: case WebTouchPoint::kStateStationary:
touches[i].state = WebTouchPoint::kStateStationary; touches[i].state = WebTouchPoint::kStateStationary;
++activePointCount; ++activePointCount;
++count;
break; break;
case WebTouchPoint::kStateReleased: case WebTouchPoint::kStateReleased:
case WebTouchPoint::kStateCancelled: case WebTouchPoint::kStateCancelled:
touches[i] = WebTouchPoint(); touches[i] = WebTouchPoint();
++count;
break; break;
case WebTouchPoint::kStateUndefined: case WebTouchPoint::kStateUndefined:
break; break;
} }
if (count >= touches_length)
break;
} }
touches_length = activePointCount; touches_length = activePointCount;
type_ = WebInputEvent::kUndefined; type_ = WebInputEvent::kUndefined;
......
...@@ -2366,6 +2366,9 @@ crbug.com/613672 [ Mac ] external/wpt/pointerevents/compat/pointerevent_touch-ac ...@@ -2366,6 +2366,9 @@ crbug.com/613672 [ Mac ] external/wpt/pointerevents/compat/pointerevent_touch-ac
# In addition to having no support on Mac, the following test times out # In addition to having no support on Mac, the following test times out
# regularly on Windows. # regularly on Windows.
crbug.com/613672 [ Mac Win ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ] crbug.com/613672 [ Mac Win ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ]
crbug.com/613672 [ Mac ] fast/events/pointerevents/multi-touch-events.html [ Skip ]
crbug.com/613672 [ Mac ] virtual/user-activation-v2/fast/events/pointerevents/multi-touch-events.html [ Skip ]
crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/multi-touch-events.html [ Skip ]
crbug.com/802067 [ Mac ] external/wpt/pointerlock/movementX_Y_basic-manual.html [ Failure ] crbug.com/802067 [ Mac ] external/wpt/pointerlock/movementX_Y_basic-manual.html [ Failure ]
crbug.com/802067 [ Mac ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy-manual.html [ Failure ] crbug.com/802067 [ Mac ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy-manual.html [ Failure ]
......
<!DOCTYPE html>
<script src='../../../resources/testharness.js'></script>
<script src='../../../resources/testharnessreport.js'></script>
<style type="text/css">
#box {
width: 600px;
height: 600px;
touch-action: none;
}
</style>
<div id="box" ></div>
<script type="text/javascript">
var touchMoveCount = 0;
var touchStartCount = 0;
var touchendCount = 0;
var box = document.getElementById("box");
var targetRect = box.getBoundingClientRect();
var offset = 50;
var x = targetRect.left + offset;
var y = targetRect.top + offset;
function validTouchResult(event) {
if (event.type == 'touchstart')
touchStartCount++;
else if (event.type == 'touchmove')
touchMoveCount++;
else if (event.type == 'touchend')
touchendCount++;
testTouchPointers.step(function () {
assert_equals(event.target.id, "box");
});
}
function callbackValidTouchCount() {
testTouchPointers.step(function () {
assert_equals(touchStartCount, 3);
assert_equals(touchMoveCount, 7);
assert_equals(touchendCount, 3);
});
testTouchPointers.done();
}
function testMultiTouchPointers() {
if (window.chrome && chrome.gpuBenchmarking) {
var pointerActions =
[{source: "touch",
actions: [
{ name: "pointerDown", x: x, y: y },
{ name: "pointerMove", x: x + 30, y: y + 30 },
{ name: "pointerMove", x: x + 50, y: y + 50 },
{ name: "pointerMove", x: x + 90, y: y + 90 },
{ name: "pause", },
{ name: "pointerUp" }]},
{source: "touch",
actions: [
{ name: "pause" },
{ name: "pointerDown", x: x, y: y },
{ name: "pointerMove", x: x + 60, y: y + 60 },
{ name: "pointerUp"}]},
{source: "touch",
actions: [
{ name: "pause" },
{ name: "pause" },
{ name: "pointerDown", x: x, y: y },
{ name: "pointerMove", x: x + 30, y: y + 30 },
{ name: "pointerMove", x: x + 50, y: y },
{ name: "pointerMove", x: x + 60, y: y },
{ name: "pointerUp"}]}];
chrome.gpuBenchmarking.pointerActionSequence(pointerActions, callbackValidTouchCount);
}
}
var testTouchPointers = async_test('Tests that all the touch events are sent correctly when there are multiple finger pointers.');
box.addEventListener('touchstart', validTouchResult);
box.addEventListener('touchmove', validTouchResult);
box.addEventListener('touchend', validTouchResult);
testMultiTouchPointers();
</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