| 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 "content/browser/renderer_host/input/mock_web_input_event_builders.h" | 8 #include "content/browser/renderer_host/input/mock_web_input_event_builders.h" |
| 9 #include "content/browser/renderer_host/input/touch_event_queue.h" | 9 #include "content/browser/renderer_host/input/touch_event_queue.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include "third_party/WebKit/public/web/WebInputEvent.h" | 11 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 12 | 12 |
| 13 using WebKit::WebGestureEvent; |
| 13 using WebKit::WebInputEvent; | 14 using WebKit::WebInputEvent; |
| 14 using WebKit::WebTouchEvent; | 15 using WebKit::WebTouchEvent; |
| 15 using WebKit::WebTouchPoint; | 16 using WebKit::WebTouchPoint; |
| 16 | 17 |
| 17 namespace content { | 18 namespace content { |
| 18 | 19 |
| 19 class TouchEventQueueTest : public testing::Test, | 20 class TouchEventQueueTest : public testing::Test, |
| 20 public TouchEventQueueClient { | 21 public TouchEventQueueClient { |
| 21 public: | 22 public: |
| 22 TouchEventQueueTest() | 23 TouchEventQueueTest() |
| (...skipping 23 matching lines...) Expand all Loading... |
| 46 const TouchEventWithLatencyInfo& event, | 47 const TouchEventWithLatencyInfo& event, |
| 47 InputEventAckState ack_result) OVERRIDE { | 48 InputEventAckState ack_result) OVERRIDE { |
| 48 ++acked_event_count_; | 49 ++acked_event_count_; |
| 49 last_acked_event_ = event.event; | 50 last_acked_event_ = event.event; |
| 50 last_acked_event_state_ = ack_result; | 51 last_acked_event_state_ = ack_result; |
| 51 if (followup_touch_event_) { | 52 if (followup_touch_event_) { |
| 52 scoped_ptr<WebTouchEvent> followup_touch_event = | 53 scoped_ptr<WebTouchEvent> followup_touch_event = |
| 53 followup_touch_event_.Pass(); | 54 followup_touch_event_.Pass(); |
| 54 SendTouchEvent(*followup_touch_event); | 55 SendTouchEvent(*followup_touch_event); |
| 55 } | 56 } |
| 57 if (followup_gesture_event_) { |
| 58 scoped_ptr<WebGestureEvent> followup_gesture_event = |
| 59 followup_gesture_event_.Pass(); |
| 60 queue_->OnGestureScrollEvent( |
| 61 GestureEventWithLatencyInfo(*followup_gesture_event, |
| 62 ui::LatencyInfo())); |
| 63 } |
| 56 } | 64 } |
| 57 | 65 |
| 58 protected: | 66 protected: |
| 59 | 67 |
| 60 void SendTouchEvent(const WebTouchEvent& event) { | 68 void SendTouchEvent(const WebTouchEvent& event) { |
| 61 queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo())); | 69 queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo())); |
| 62 } | 70 } |
| 63 | 71 |
| 64 void SendTouchEvent() { | 72 void SendTouchEvent() { |
| 65 SendTouchEvent(touch_event_); | 73 SendTouchEvent(touch_event_); |
| 66 touch_event_.ResetPoints(); | 74 touch_event_.ResetPoints(); |
| 67 } | 75 } |
| 68 | 76 |
| 77 void SendGestureEvent(WebInputEvent::Type type) { |
| 78 WebGestureEvent event; |
| 79 event.type = type; |
| 80 queue_->OnGestureScrollEvent( |
| 81 GestureEventWithLatencyInfo(event, ui::LatencyInfo())); |
| 82 } |
| 83 |
| 69 void SendTouchEventACK(InputEventAckState ack_result) { | 84 void SendTouchEventACK(InputEventAckState ack_result) { |
| 70 queue_->ProcessTouchAck(ack_result, ui::LatencyInfo()); | 85 queue_->ProcessTouchAck(ack_result, ui::LatencyInfo()); |
| 71 } | 86 } |
| 72 | 87 |
| 73 void SetFollowupEvent(const WebTouchEvent& event) { | 88 void SetFollowupEvent(const WebTouchEvent& event) { |
| 74 followup_touch_event_.reset(new WebTouchEvent(event)); | 89 followup_touch_event_.reset(new WebTouchEvent(event)); |
| 75 } | 90 } |
| 76 | 91 |
| 92 void SetFollowupEvent(const WebGestureEvent& event) { |
| 93 followup_gesture_event_.reset(new WebGestureEvent(event)); |
| 94 } |
| 95 |
| 77 int PressTouchPoint(int x, int y) { | 96 int PressTouchPoint(int x, int y) { |
| 78 return touch_event_.PressPoint(x, y); | 97 return touch_event_.PressPoint(x, y); |
| 79 } | 98 } |
| 80 | 99 |
| 81 void MoveTouchPoint(int index, int x, int y) { | 100 void MoveTouchPoint(int index, int x, int y) { |
| 82 touch_event_.MovePoint(index, x, y); | 101 touch_event_.MovePoint(index, x, y); |
| 83 } | 102 } |
| 84 | 103 |
| 85 void ReleaseTouchPoint(int index) { | 104 void ReleaseTouchPoint(int index) { |
| 86 touch_event_.ReleasePoint(index); | 105 touch_event_.ReleasePoint(index); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 107 } | 126 } |
| 108 | 127 |
| 109 const WebTouchEvent& latest_event() const { | 128 const WebTouchEvent& latest_event() const { |
| 110 return queue_->GetLatestEvent().event; | 129 return queue_->GetLatestEvent().event; |
| 111 } | 130 } |
| 112 | 131 |
| 113 const WebTouchEvent& acked_event() const { | 132 const WebTouchEvent& acked_event() const { |
| 114 return last_acked_event_; | 133 return last_acked_event_; |
| 115 } | 134 } |
| 116 | 135 |
| 136 const WebTouchEvent& sent_event() const { |
| 137 return last_sent_event_; |
| 138 } |
| 139 |
| 117 InputEventAckState acked_event_state() const { | 140 InputEventAckState acked_event_state() const { |
| 118 return last_acked_event_state_; | 141 return last_acked_event_state_; |
| 119 } | 142 } |
| 120 | 143 |
| 121 void set_no_touch_to_renderer(bool no_touch) { | 144 void set_no_touch_to_renderer(bool no_touch) { |
| 122 queue_->no_touch_to_renderer_ = no_touch; | 145 queue_->no_touch_to_renderer_ = no_touch; |
| 123 } | 146 } |
| 124 | 147 |
| 125 bool no_touch_to_renderer() const { | 148 bool no_touch_to_renderer() const { |
| 126 return queue_->no_touch_to_renderer_; | 149 return queue_->no_touch_to_renderer_; |
| 127 } | 150 } |
| 128 | 151 |
| 129 private: | 152 private: |
| 130 scoped_ptr<TouchEventQueue> queue_; | 153 scoped_ptr<TouchEventQueue> queue_; |
| 131 size_t sent_event_count_; | 154 size_t sent_event_count_; |
| 132 size_t acked_event_count_; | 155 size_t acked_event_count_; |
| 133 WebTouchEvent last_sent_event_; | 156 WebTouchEvent last_sent_event_; |
| 134 WebTouchEvent last_acked_event_; | 157 WebTouchEvent last_acked_event_; |
| 135 InputEventAckState last_acked_event_state_; | 158 InputEventAckState last_acked_event_state_; |
| 136 MockWebTouchEvent touch_event_; | 159 MockWebTouchEvent touch_event_; |
| 137 scoped_ptr<WebTouchEvent> followup_touch_event_; | 160 scoped_ptr<WebTouchEvent> followup_touch_event_; |
| 161 scoped_ptr<WebGestureEvent> followup_gesture_event_; |
| 138 }; | 162 }; |
| 139 | 163 |
| 140 | 164 |
| 141 // Tests that touch-events are queued properly. | 165 // Tests that touch-events are queued properly. |
| 142 TEST_F(TouchEventQueueTest, Basic) { | 166 TEST_F(TouchEventQueueTest, Basic) { |
| 143 PressTouchPoint(1, 1); | 167 PressTouchPoint(1, 1); |
| 144 SendTouchEvent(); | 168 SendTouchEvent(); |
| 145 EXPECT_EQ(1U, queued_event_count()); | 169 EXPECT_EQ(1U, queued_event_count()); |
| 146 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 170 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 147 | 171 |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 stationary_event.touches[0].state = WebTouchPoint::StateStationary; | 641 stationary_event.touches[0].state = WebTouchPoint::StateStationary; |
| 618 SendTouchEvent(stationary_event); | 642 SendTouchEvent(stationary_event); |
| 619 | 643 |
| 620 EXPECT_EQ(1U, queued_event_count()); | 644 EXPECT_EQ(1U, queued_event_count()); |
| 621 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 645 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 622 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 646 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 623 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); | 647 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); |
| 624 EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type); | 648 EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type); |
| 625 } | 649 } |
| 626 | 650 |
| 627 // Tests that no touch move events are sent to renderer during scrolling. | 651 // Tests basic TouchEvent forwarding suppression. |
| 628 TEST_F(TouchEventQueueTest, NoTouchMove) { | 652 TEST_F(TouchEventQueueTest, NoTouchBasic) { |
| 629 // First touch press. | 653 // Disable TouchEvent forwarding. |
| 654 set_no_touch_to_renderer(true); |
| 655 MoveTouchPoint(0, 30, 5); |
| 656 SendTouchEvent(); |
| 657 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 658 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 659 |
| 660 // TouchMove should not be sent to renderer. |
| 661 MoveTouchPoint(0, 65, 10); |
| 662 SendTouchEvent(); |
| 663 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 664 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 665 |
| 666 // TouchEnd should not be sent to renderer. |
| 667 ReleaseTouchPoint(0); |
| 668 SendTouchEvent(); |
| 669 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 670 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 671 |
| 672 // TouchStart should not be sent to renderer. |
| 673 PressTouchPoint(5, 5); |
| 674 SendTouchEvent(); |
| 675 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 676 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 677 |
| 678 // Enable TouchEvent forwarding. |
| 679 set_no_touch_to_renderer(false); |
| 680 |
| 681 PressTouchPoint(80, 10); |
| 682 SendTouchEvent(); |
| 683 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 684 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 685 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 686 |
| 687 MoveTouchPoint(0, 80, 20); |
| 688 SendTouchEvent(); |
| 689 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 690 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 691 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 692 |
| 693 ReleaseTouchPoint(0); |
| 694 SendTouchEvent(); |
| 695 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 696 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 697 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 698 } |
| 699 |
| 700 // Tests that no TouchEvents are sent to renderer during scrolling. |
| 701 TEST_F(TouchEventQueueTest, NoTouchOnScroll) { |
| 702 // Queue a TouchStart. |
| 630 PressTouchPoint(0, 1); | 703 PressTouchPoint(0, 1); |
| 631 SendTouchEvent(); | 704 SendTouchEvent(); |
| 632 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 705 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 633 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 706 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 634 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 707 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 635 | 708 |
| 636 // Touch moves may trigger scroll. | |
| 637 MoveTouchPoint(0, 20, 5); | 709 MoveTouchPoint(0, 20, 5); |
| 638 SendTouchEvent(); | 710 SendTouchEvent(); |
| 711 EXPECT_EQ(1U, queued_event_count()); |
| 639 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 712 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 713 |
| 714 // Queue another TouchStart. |
| 715 PressTouchPoint(20, 20); |
| 716 SendTouchEvent(); |
| 717 EXPECT_EQ(2U, queued_event_count()); |
| 718 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 719 EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type); |
| 720 |
| 721 // GestureScrollBegin inserts a synthetic TouchCancel before the TouchStart. |
| 722 WebGestureEvent followup_scroll; |
| 723 followup_scroll.type = WebInputEvent::GestureScrollBegin; |
| 724 SetFollowupEvent(followup_scroll); |
| 725 ASSERT_FALSE(no_touch_to_renderer()); |
| 640 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 726 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 727 EXPECT_TRUE(no_touch_to_renderer()); |
| 728 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 641 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 729 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 730 EXPECT_EQ(2U, queued_event_count()); |
| 731 EXPECT_EQ(WebInputEvent::TouchCancel, sent_event().type); |
| 732 EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type); |
| 642 | 733 |
| 643 // Touch move should not be sent to renderer (e.g., when scrolling starts). | 734 // Acking the TouchCancel will result in dispatch of the next TouchStart. |
| 644 set_no_touch_to_renderer(true); | 735 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 736 // The synthetic TouchCancel should not reach client, only the TouchStart. |
| 737 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 738 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 739 EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type); |
| 740 |
| 741 // TouchMove should not be sent to renderer. |
| 645 MoveTouchPoint(0, 30, 5); | 742 MoveTouchPoint(0, 30, 5); |
| 646 SendTouchEvent(); | 743 SendTouchEvent(); |
| 744 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 647 EXPECT_EQ(0U, GetAndResetSentEventCount()); | 745 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 648 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 746 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); |
| 649 | 747 |
| 650 // Touch move should not be sent to renderer. | 748 // GestureScrollUpdates should not change affect touch forwarding. |
| 651 MoveTouchPoint(0, 65, 10); | 749 SendGestureEvent(WebInputEvent::GestureScrollUpdate); |
| 652 SendTouchEvent(); | 750 EXPECT_TRUE(no_touch_to_renderer()); |
| 653 EXPECT_EQ(0U, GetAndResetSentEventCount()); | |
| 654 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | |
| 655 | 751 |
| 656 // Touch end should not be sent to renderer. | 752 // TouchEnd should not be sent to renderer. |
| 657 ReleaseTouchPoint(0); | 753 ReleaseTouchPoint(0); |
| 658 SendTouchEvent(); | 754 SendTouchEvent(); |
| 755 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 659 EXPECT_EQ(0U, GetAndResetSentEventCount()); | 756 EXPECT_EQ(0U, GetAndResetSentEventCount()); |
| 660 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 757 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); |
| 661 | 758 |
| 662 // Resume sending touch moves to renderer (e.g., when scrolling ends). | 759 // GestureScrollEnd will resume the sending of TouchEvents to renderer. |
| 663 set_no_touch_to_renderer(false); | 760 SendGestureEvent(WebKit::WebInputEvent::GestureScrollEnd); |
| 761 EXPECT_FALSE(no_touch_to_renderer()); |
| 664 | 762 |
| 665 // Now touch events should come through to renderer. | 763 // Now TouchEvents should be forwarded normally. |
| 666 PressTouchPoint(80, 10); | 764 PressTouchPoint(80, 10); |
| 667 SendTouchEvent(); | 765 SendTouchEvent(); |
| 668 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 766 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 669 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 767 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 670 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 768 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 671 | 769 |
| 672 MoveTouchPoint(0, 80, 20); | 770 MoveTouchPoint(0, 80, 20); |
| 673 SendTouchEvent(); | 771 SendTouchEvent(); |
| 674 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 772 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 675 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 773 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 676 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 774 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 677 | 775 |
| 678 ReleaseTouchPoint(0); | 776 ReleaseTouchPoint(0); |
| 679 SendTouchEvent(); | 777 SendTouchEvent(); |
| 680 EXPECT_EQ(1U, GetAndResetSentEventCount()); | 778 EXPECT_EQ(1U, GetAndResetSentEventCount()); |
| 681 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 779 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 682 EXPECT_EQ(1U, GetAndResetAckedEventCount()); | 780 EXPECT_EQ(1U, GetAndResetAckedEventCount()); |
| 683 } | 781 } |
| 684 | 782 |
| 685 } // namespace content | 783 } // namespace content |
| OLD | NEW |