| 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 |