summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlanwei <lanwei@chromium.org>2015-05-11 09:56:55 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-11 16:58:17 +0000
commit901538b70297c3984afc8c045381ebff5bfdaa9e (patch)
treea8d7d639dca559d1c739234cc9ae68230786c5bb
parent2117e7503ed5ee06a9e80e6e02b01786b73ed3b1 (diff)
downloadchromium_src-901538b70297c3984afc8c045381ebff5bfdaa9e.zip
chromium_src-901538b70297c3984afc8c045381ebff5bfdaa9e.tar.gz
chromium_src-901538b70297c3984afc8c045381ebff5bfdaa9e.tar.bz2
Make sure send one WebTouchEvent ack per ui::TouchEvent
In our current code (RenderWidgetHostViewAura), we may send more than one ack for one WebTouchEvent in the multi-touch scenario, but we should only send one WebTouchEvent ack for each ui::TouchEvent. For touchmove and touchcancel, we will only change the state for the actual touch point which causes this touchevent for multi-touch. BUG=484276 Review URL: https://codereview.chromium.org/1120293003 Cr-Commit-Position: refs/heads/master@{#329161}
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc26
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura_unittest.cc90
2 files changed, 111 insertions, 5 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 420f475..93a4e93 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -277,6 +277,20 @@ bool IsFractionalScaleFactor(float scale_factor) {
return (scale_factor - static_cast<int>(scale_factor)) > 0;
}
+// Reset unchanged touch point to StateStationary for touchmove and
+// touchcancel.
+void MarkUnchangedTouchPointsAsStationary(
+ blink::WebTouchEvent* event,
+ int changed_touch_id) {
+ if (event->type == blink::WebInputEvent::TouchMove ||
+ event->type == blink::WebInputEvent::TouchCancel) {
+ for (size_t i = 0; i < event->touchesLength; ++i) {
+ if (event->touches[i].id != changed_touch_id)
+ event->touches[i].state = blink::WebTouchPoint::StateStationary;
+ }
+ }
+}
+
} // namespace
// We need to watch for mouse events outside a Web Popup or its parent
@@ -1278,10 +1292,14 @@ void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
break;
}
- // Only send acks for changed touches.
+ // Only send acks for one changed touch point.
+ bool sent_ack = false;
for (size_t i = 0; i < touch.event.touchesLength; ++i) {
- if (touch.event.touches[i].state == required_state)
+ if (touch.event.touches[i].state == required_state) {
+ DCHECK(!sent_ack);
host->dispatcher()->ProcessedTouchEvent(window_, result);
+ sent_ack = true;
+ }
}
}
@@ -2180,6 +2198,10 @@ void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
// processed by the gesture recognizer before events currently awaiting
// dispatch in the touch queue.
event->DisableSynchronousHandling();
+
+ // Set unchanged touch point to StateStationary for touchmove and
+ // touchcancel to make sure only send one ack per WebTouchEvent.
+ MarkUnchangedTouchPointsAsStationary(&touch_event, event->touch_id());
host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
}
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index aba2b57..eb32f72 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -223,8 +223,10 @@ class FakeWindowEventDispatcher : public aura::WindowEventDispatcher {
processed_touch_event_count_++;
}
- size_t processed_touch_event_count() {
- return processed_touch_event_count_;
+ size_t GetAndResetProcessedTouchEventCount() {
+ size_t count = processed_touch_event_count_;
+ processed_touch_event_count_ = 0;
+ return count;
}
private:
@@ -1124,6 +1126,88 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
EXPECT_EQ(nullptr, view_->touch_event_);
}
+// Checks that touch-event state is maintained correctly for multiple touch
+// points.
+TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
+ view_->InitAsFullscreen(parent_view_);
+ view_->Show();
+ view_->UseFakeDispatcher();
+ GetSentMessageCountAndResetSink();
+
+ ui::TouchEvent press0(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0,
+ ui::EventTimeForNow());
+
+ view_->OnTouchEvent(&press0);
+ SendInputEventACK(blink::WebInputEvent::TouchStart,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
+ EXPECT_EQ(1U, view_->touch_event_->touchesLength);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+
+ ui::TouchEvent move0(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
+ ui::EventTimeForNow());
+
+ view_->OnTouchEvent(&move0);
+ SendInputEventACK(blink::WebInputEvent::TouchMove,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
+ EXPECT_EQ(1U, view_->touch_event_->touchesLength);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+
+ // For the second touchstart, only the state of the second touch point is
+ // StatePressed, the state of the first touch point is StateStationary.
+ ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1,
+ ui::EventTimeForNow());
+
+ view_->OnTouchEvent(&press1);
+ SendInputEventACK(blink::WebInputEvent::TouchStart,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
+ EXPECT_EQ(2U, view_->touch_event_->touchesLength);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+
+ // For the touchmove of second point, the state of the second touch point is
+ // StateMoved, the state of the first touch point is StateStationary.
+ ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(30, 30), 1,
+ ui::EventTimeForNow());
+
+ view_->OnTouchEvent(&move1);
+ SendInputEventACK(blink::WebInputEvent::TouchMove,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
+ EXPECT_EQ(2U, view_->touch_event_->touchesLength);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+
+ // For the touchmove of first point, the state of the first touch point is
+ // StateMoved, the state of the second touch point is StateStationary.
+ ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(10, 10), 0,
+ ui::EventTimeForNow());
+
+ view_->OnTouchEvent(&move2);
+ SendInputEventACK(blink::WebInputEvent::TouchMove,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
+ EXPECT_EQ(2U, view_->touch_event_->touchesLength);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+
+ ui::TouchEvent cancel0(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 10), 0,
+ ui::EventTimeForNow());
+
+ // For the touchcancel, only the state of the current touch point is
+ // StateCancelled, the state of the other touch point is StateStationary.
+ view_->OnTouchEvent(&cancel0);
+ EXPECT_EQ(blink::WebInputEvent::TouchCancel, view_-> touch_event_->type);
+ EXPECT_EQ(1U, view_->touch_event_->touchesLength);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+
+ ui::TouchEvent cancel1(ui::ET_TOUCH_CANCELLED, gfx::Point(30, 30), 1,
+ ui::EventTimeForNow());
+
+ view_->OnTouchEvent(&cancel1);
+ EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
+ EXPECT_EQ(nullptr, view_->touch_event_);
+}
+
// Checks that touch-events are queued properly when there is a touch-event
// handler on the page.
TEST_F(RenderWidgetHostViewAuraTest, TouchEventSyncAsync) {
@@ -3321,7 +3405,7 @@ TEST_F(RenderWidgetHostViewAuraTest, CorrectNumberOfAcksAreDispatched) {
SendInputEventACK(blink::WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(2U, view_->dispatcher_->processed_touch_event_count());
+ EXPECT_EQ(2U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
}
// Tests that the scroll deltas stored within the overscroll controller get