OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/logging.h" | 6 #include "base/logging.h" |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "content/browser/renderer_host/input/timeout_monitor.h" | 9 #include "content/browser/renderer_host/input/timeout_monitor.h" |
10 #include "content/browser/renderer_host/input/touch_event_queue.h" | 10 #include "content/browser/renderer_host/input/touch_event_queue.h" |
11 #include "content/common/input/synthetic_web_input_event_builders.h" | 11 #include "content/common/input/synthetic_web_input_event_builders.h" |
| 12 #include "content/common/input/web_touch_event_traits.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
13 #include "third_party/WebKit/public/web/WebInputEvent.h" | 14 #include "third_party/WebKit/public/web/WebInputEvent.h" |
14 | 15 |
15 using blink::WebGestureEvent; | 16 using blink::WebGestureEvent; |
16 using blink::WebInputEvent; | 17 using blink::WebInputEvent; |
17 using blink::WebTouchEvent; | 18 using blink::WebTouchEvent; |
18 using blink::WebTouchPoint; | 19 using blink::WebTouchPoint; |
19 | 20 |
20 namespace content { | 21 namespace content { |
21 namespace { | 22 namespace { |
22 | 23 |
23 const double kMinSecondsBetweenThrottledTouchmoves = 0.2; | 24 const double kMinSecondsBetweenThrottledTouchmoves = 0.2; |
| 25 const float kSlopLengthDips = 10; |
| 26 const float kHalfSlopLengthDips = kSlopLengthDips / 2; |
24 | 27 |
25 base::TimeDelta DefaultTouchTimeoutDelay() { | 28 base::TimeDelta DefaultTouchTimeoutDelay() { |
26 return base::TimeDelta::FromMilliseconds(1); | 29 return base::TimeDelta::FromMilliseconds(1); |
27 } | 30 } |
28 } // namespace | 31 } // namespace |
29 | 32 |
30 class TouchEventQueueTest : public testing::Test, | 33 class TouchEventQueueTest : public testing::Test, |
31 public TouchEventQueueClient { | 34 public TouchEventQueueClient { |
32 public: | 35 public: |
33 TouchEventQueueTest() | 36 TouchEventQueueTest() |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 queue_->OnGestureScrollEvent( | 74 queue_->OnGestureScrollEvent( |
72 GestureEventWithLatencyInfo(*followup_gesture_event, | 75 GestureEventWithLatencyInfo(*followup_gesture_event, |
73 ui::LatencyInfo())); | 76 ui::LatencyInfo())); |
74 } | 77 } |
75 } | 78 } |
76 | 79 |
77 protected: | 80 protected: |
78 TouchEventQueue::Config CreateConfig() { | 81 TouchEventQueue::Config CreateConfig() { |
79 TouchEventQueue::Config config; | 82 TouchEventQueue::Config config; |
80 config.touch_scrolling_mode = touch_scrolling_mode_; | 83 config.touch_scrolling_mode = touch_scrolling_mode_; |
81 config.touchmove_slop_suppression_length_dips = slop_length_dips_; | |
82 return config; | 84 return config; |
83 } | 85 } |
84 | 86 |
85 void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) { | 87 void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) { |
86 touch_scrolling_mode_ = mode; | 88 touch_scrolling_mode_ = mode; |
87 ResetQueueWithConfig(CreateConfig()); | 89 ResetQueueWithConfig(CreateConfig()); |
88 } | 90 } |
89 | 91 |
90 void SetUpForTouchMoveSlopTesting(double slop_length_dips) { | 92 void SetUpForTouchMoveSlopTesting(double slop_length_dips) { |
91 slop_length_dips_ = slop_length_dips; | 93 slop_length_dips_ = slop_length_dips; |
92 ResetQueueWithConfig(CreateConfig()); | |
93 } | 94 } |
94 | 95 |
95 void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) { | 96 void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) { |
96 TouchEventQueue::Config config = CreateConfig(); | 97 TouchEventQueue::Config config = CreateConfig(); |
97 config.touch_ack_timeout_delay = timeout_delay; | 98 config.touch_ack_timeout_delay = timeout_delay; |
98 config.touch_ack_timeout_supported = true; | 99 config.touch_ack_timeout_supported = true; |
99 ResetQueueWithConfig(config); | 100 ResetQueueWithConfig(config); |
100 } | 101 } |
101 | 102 |
102 void SendTouchEvent(const WebTouchEvent& event) { | 103 void SendTouchEvent(WebTouchEvent event) { |
| 104 if (slop_length_dips_) { |
| 105 event.causesScrollingIfUncanceled = false; |
| 106 if (WebTouchEventTraits::IsTouchSequenceStart(event)) |
| 107 anchor_ = event.touches[0].position; |
| 108 if (event.type == WebInputEvent::TouchMove) { |
| 109 gfx::Vector2dF delta = anchor_ - event.touches[0].position; |
| 110 if (delta.LengthSquared() > slop_length_dips_ * slop_length_dips_) |
| 111 event.causesScrollingIfUncanceled = true; |
| 112 } |
| 113 } else { |
| 114 event.causesScrollingIfUncanceled = |
| 115 event.type == WebInputEvent::TouchMove; |
| 116 } |
103 queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo())); | 117 queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo())); |
104 } | 118 } |
105 | 119 |
106 void SendGestureEvent(WebInputEvent::Type type) { | 120 void SendGestureEvent(WebInputEvent::Type type) { |
107 WebGestureEvent event; | 121 WebGestureEvent event; |
108 event.type = type; | 122 event.type = type; |
109 queue_->OnGestureScrollEvent( | 123 queue_->OnGestureScrollEvent( |
110 GestureEventWithLatencyInfo(event, ui::LatencyInfo())); | 124 GestureEventWithLatencyInfo(event, ui::LatencyInfo())); |
111 } | 125 } |
112 | 126 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 size_t sent_event_count_; | 256 size_t sent_event_count_; |
243 size_t acked_event_count_; | 257 size_t acked_event_count_; |
244 WebTouchEvent last_sent_event_; | 258 WebTouchEvent last_sent_event_; |
245 WebTouchEvent last_acked_event_; | 259 WebTouchEvent last_acked_event_; |
246 InputEventAckState last_acked_event_state_; | 260 InputEventAckState last_acked_event_state_; |
247 SyntheticWebTouchEvent touch_event_; | 261 SyntheticWebTouchEvent touch_event_; |
248 scoped_ptr<WebTouchEvent> followup_touch_event_; | 262 scoped_ptr<WebTouchEvent> followup_touch_event_; |
249 scoped_ptr<WebGestureEvent> followup_gesture_event_; | 263 scoped_ptr<WebGestureEvent> followup_gesture_event_; |
250 scoped_ptr<InputEventAckState> sync_ack_result_; | 264 scoped_ptr<InputEventAckState> sync_ack_result_; |
251 double slop_length_dips_; | 265 double slop_length_dips_; |
| 266 gfx::PointF anchor_; |
252 TouchEventQueue::TouchScrollingMode touch_scrolling_mode_; | 267 TouchEventQueue::TouchScrollingMode touch_scrolling_mode_; |
253 base::MessageLoopForUI message_loop_; | 268 base::MessageLoopForUI message_loop_; |
254 }; | 269 }; |
255 | 270 |
256 | 271 |
257 // Tests that touch-events are queued properly. | 272 // Tests that touch-events are queued properly. |
258 TEST_F(TouchEventQueueTest, Basic) { | 273 TEST_F(TouchEventQueueTest, Basic) { |
259 PressTouchPoint(1, 1); | 274 PressTouchPoint(1, 1); |
260 EXPECT_EQ(1U, queued_event_count()); | 275 EXPECT_EQ(1U, queued_event_count()); |
261 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 276 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 | 1449 |
1435 // Subsequent events should be handled normally. | 1450 // Subsequent events should be handled normally. |
1436 PressTouchPoint(0, 1); | 1451 PressTouchPoint(0, 1); |
1437 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 1452 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
1438 EXPECT_EQ(0U, GetAndResetAckedEventCount()); | 1453 EXPECT_EQ(0U, GetAndResetAckedEventCount()); |
1439 } | 1454 } |
1440 | 1455 |
1441 // Tests that TouchMove's are dropped if within the boundary-inclusive slop | 1456 // Tests that TouchMove's are dropped if within the boundary-inclusive slop |
1442 // suppression region for an unconsumed TouchStart. | 1457 // suppression region for an unconsumed TouchStart. |
1443 TEST_F(TouchEventQueueTest, TouchMoveSuppressionIncludingSlopBoundary) { | 1458 TEST_F(TouchEventQueueTest, TouchMoveSuppressionIncludingSlopBoundary) { |
1444 const float kSlopLengthDips = 10; | |
1445 const float kHalfSlopLengthDips = kSlopLengthDips / 2; | |
1446 SetUpForTouchMoveSlopTesting(kSlopLengthDips); | 1459 SetUpForTouchMoveSlopTesting(kSlopLengthDips); |
1447 | 1460 |
1448 // Queue a TouchStart. | 1461 // Queue a TouchStart. |
1449 PressTouchPoint(0, 0); | 1462 PressTouchPoint(0, 0); |
1450 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 1463 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
1451 ASSERT_EQ(1U, GetAndResetSentEventCount()); | 1464 ASSERT_EQ(1U, GetAndResetSentEventCount()); |
1452 ASSERT_EQ(1U, GetAndResetAckedEventCount()); | 1465 ASSERT_EQ(1U, GetAndResetAckedEventCount()); |
1453 | 1466 |
1454 // TouchMove's within the region should be suppressed. | 1467 // TouchMove's within the region should be suppressed. |
1455 MoveTouchPoint(0, 0, kHalfSlopLengthDips); | 1468 MoveTouchPoint(0, 0, kHalfSlopLengthDips); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 | 1532 |
1520 MoveTouchPoint(0, kSlopLengthDips, 0); | 1533 MoveTouchPoint(0, kSlopLengthDips, 0); |
1521 EXPECT_EQ(0U, queued_event_count()); | 1534 EXPECT_EQ(0U, queued_event_count()); |
1522 EXPECT_EQ(0U, GetAndResetSentEventCount()); | 1535 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
1523 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 1536 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
1524 } | 1537 } |
1525 | 1538 |
1526 // Tests that TouchMove's are not dropped within the slop suppression region if | 1539 // Tests that TouchMove's are not dropped within the slop suppression region if |
1527 // the touchstart was consumed. | 1540 // the touchstart was consumed. |
1528 TEST_F(TouchEventQueueTest, NoTouchMoveSuppressionAfterTouchConsumed) { | 1541 TEST_F(TouchEventQueueTest, NoTouchMoveSuppressionAfterTouchConsumed) { |
1529 const float kSlopLengthDips = 10; | |
1530 const float kHalfSlopLengthDips = kSlopLengthDips / 2; | |
1531 SetUpForTouchMoveSlopTesting(kSlopLengthDips); | 1542 SetUpForTouchMoveSlopTesting(kSlopLengthDips); |
1532 | 1543 |
1533 // Queue a TouchStart. | 1544 // Queue a TouchStart. |
1534 PressTouchPoint(0, 0); | 1545 PressTouchPoint(0, 0); |
1535 SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED); | 1546 SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED); |
1536 ASSERT_EQ(1U, GetAndResetSentEventCount()); | 1547 ASSERT_EQ(1U, GetAndResetSentEventCount()); |
1537 ASSERT_EQ(1U, GetAndResetAckedEventCount()); | 1548 ASSERT_EQ(1U, GetAndResetAckedEventCount()); |
1538 | 1549 |
1539 // TouchMove's within the region should not be suppressed, as a touch was | 1550 // TouchMove's within the region should not be suppressed, as a touch was |
1540 // consumed. | 1551 // consumed. |
(...skipping 12 matching lines...) Expand all Loading... |
1553 ASSERT_EQ(1U, GetAndResetSentEventCount()); | 1564 ASSERT_EQ(1U, GetAndResetSentEventCount()); |
1554 ASSERT_EQ(1U, GetAndResetAckedEventCount()); | 1565 ASSERT_EQ(1U, GetAndResetAckedEventCount()); |
1555 | 1566 |
1556 // Small TouchMove's should not be suppressed. | 1567 // Small TouchMove's should not be suppressed. |
1557 MoveTouchPoint(0, 0.001f, 0.001f); | 1568 MoveTouchPoint(0, 0.001f, 0.001f); |
1558 EXPECT_EQ(1U, queued_event_count()); | 1569 EXPECT_EQ(1U, queued_event_count()); |
1559 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 1570 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
1560 EXPECT_EQ(0U, GetAndResetAckedEventCount()); | 1571 EXPECT_EQ(0U, GetAndResetAckedEventCount()); |
1561 } | 1572 } |
1562 | 1573 |
1563 // Tests that TouchMove's are not dropped due to incorrect handling of DPI | |
1564 // scaling. | |
1565 TEST_F(TouchEventQueueTest, TouchMoveSuppressionWithDIPScaling) { | |
1566 const float kSlopLengthPixels = 7.f; | |
1567 const float kDPIScale = 3.f; | |
1568 SetUpForTouchMoveSlopTesting(kSlopLengthPixels / kDPIScale); | |
1569 | |
1570 // Queue a TouchStart. | |
1571 PressTouchPoint(0, 0); | |
1572 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | |
1573 ASSERT_EQ(1U, GetAndResetSentEventCount()); | |
1574 ASSERT_EQ(1U, GetAndResetAckedEventCount()); | |
1575 | |
1576 // TouchMove's along the slop boundary should be suppresed. | |
1577 MoveTouchPoint(0, 0, kSlopLengthPixels / kDPIScale); | |
1578 EXPECT_EQ(0U, queued_event_count()); | |
1579 EXPECT_EQ(0U, GetAndResetSentEventCount()); | |
1580 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | |
1581 | |
1582 // Reset the touch sequence. | |
1583 ReleaseTouchPoint(0); | |
1584 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | |
1585 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | |
1586 GetAndResetSentEventCount(); | |
1587 GetAndResetAckedEventCount(); | |
1588 | |
1589 // Queue a TouchStart. | |
1590 PressTouchPoint(0, 0); | |
1591 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | |
1592 ASSERT_EQ(1U, GetAndResetSentEventCount()); | |
1593 ASSERT_EQ(1U, GetAndResetAckedEventCount()); | |
1594 | |
1595 // TouchMove's outside the region should not be suppressed. | |
1596 const float kPixelCoordOutsideSlopRegion = kSlopLengthPixels + 0.5f; | |
1597 MoveTouchPoint(0, 0, kPixelCoordOutsideSlopRegion / kDPIScale); | |
1598 EXPECT_EQ(1U, queued_event_count()); | |
1599 EXPECT_EQ(1U, GetAndResetSentEventCount()); | |
1600 EXPECT_EQ(0U, GetAndResetAckedEventCount()); | |
1601 } | |
1602 | |
1603 // Tests that TouchMove's are not dropped if a secondary pointer is present | 1574 // Tests that TouchMove's are not dropped if a secondary pointer is present |
1604 // during any movement. | 1575 // during any movement. |
1605 TEST_F(TouchEventQueueTest, NoTouchMoveSuppressionAfterMultiTouch) { | 1576 TEST_F(TouchEventQueueTest, NoTouchMoveSuppressionAfterMultiTouch) { |
1606 const float kSlopLengthDips = 10; | |
1607 const float kHalfSlopLengthDips = kSlopLengthDips / 2; | |
1608 SetUpForTouchMoveSlopTesting(kSlopLengthDips); | 1577 SetUpForTouchMoveSlopTesting(kSlopLengthDips); |
1609 | 1578 |
1610 // Queue a TouchStart. | 1579 // Queue a TouchStart. |
1611 PressTouchPoint(0, 0); | 1580 PressTouchPoint(0, 0); |
1612 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 1581 SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
1613 ASSERT_EQ(1U, GetAndResetSentEventCount()); | 1582 ASSERT_EQ(1U, GetAndResetSentEventCount()); |
1614 ASSERT_EQ(1U, GetAndResetAckedEventCount()); | 1583 ASSERT_EQ(1U, GetAndResetAckedEventCount()); |
1615 | 1584 |
1616 // TouchMove's within the region should be suppressed. | 1585 // TouchMove's within the region should be suppressed. |
1617 MoveTouchPoint(0, 0, kHalfSlopLengthDips); | 1586 MoveTouchPoint(0, 0, kHalfSlopLengthDips); |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 | 2188 |
2220 // Give the touchmove a valid id; it should be sent. | 2189 // Give the touchmove a valid id; it should be sent. |
2221 event.touches[0].id = press_id; | 2190 event.touches[0].id = press_id; |
2222 SendTouchEvent(event); | 2191 SendTouchEvent(event); |
2223 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 2192 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
2224 SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED); | 2193 SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED); |
2225 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 2194 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
2226 } | 2195 } |
2227 | 2196 |
2228 } // namespace content | 2197 } // namespace content |
OLD | NEW |