OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ui/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
6 | 6 |
7 #include "base/test/simple_test_tick_clock.h" | 7 #include "base/test/simple_test_tick_clock.h" |
8 #include "base/time/time.h" | 8 #include "base/time/time.h" |
9 #include "ui/aura/client/cursor_client.h" | 9 #include "ui/aura/client/cursor_client.h" |
10 #include "ui/aura/test/aura_test_base.h" | 10 #include "ui/aura/test/aura_test_base.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 } else if (on && !touch_exploration_controller_.get()) { | 117 } else if (on && !touch_exploration_controller_.get()) { |
118 touch_exploration_controller_.reset( | 118 touch_exploration_controller_.reset( |
119 new ui::TouchExplorationController(root_window())); | 119 new ui::TouchExplorationController(root_window())); |
120 touch_exploration_controller_->SetEventHandlerForTesting( | 120 touch_exploration_controller_->SetEventHandlerForTesting( |
121 &event_capturer_); | 121 &event_capturer_); |
122 cursor_client()->ShowCursor(); | 122 cursor_client()->ShowCursor(); |
123 cursor_client()->DisableMouseEvents(); | 123 cursor_client()->DisableMouseEvents(); |
124 } | 124 } |
125 } | 125 } |
126 | 126 |
| 127 void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) { |
| 128 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now()); |
| 129 generator_->Dispatch(&touch_press); |
| 130 AdvanceSimulatedTimePastTapDelay(); |
| 131 EXPECT_TRUE(IsInTouchToMouseMode()); |
| 132 } |
| 133 |
127 bool IsInTouchToMouseMode() { | 134 bool IsInTouchToMouseMode() { |
128 aura::client::CursorClient* cursor_client = | 135 aura::client::CursorClient* cursor_client = |
129 aura::client::GetCursorClient(root_window()); | 136 aura::client::GetCursorClient(root_window()); |
130 return cursor_client && | 137 return cursor_client && |
131 cursor_client->IsMouseEventsEnabled() && | 138 cursor_client->IsMouseEventsEnabled() && |
132 !cursor_client->IsCursorVisible(); | 139 !cursor_client->IsCursorVisible(); |
133 } | 140 } |
134 | 141 |
135 bool IsInNoFingersDownState() { | 142 bool IsInNoFingersDownState() { |
136 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); | 143 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 // This should result in a single touch long press and release | 685 // This should result in a single touch long press and release |
679 // at the location of the tap, not at the location of the double-tap. | 686 // at the location of the tap, not at the location of the double-tap. |
680 // There should be a time delay between the touch press and release. | 687 // There should be a time delay between the touch press and release. |
681 gfx::Point first_tap_location(33, 34); | 688 gfx::Point first_tap_location(33, 34); |
682 generator_->set_current_location(first_tap_location); | 689 generator_->set_current_location(first_tap_location); |
683 generator_->PressTouch(); | 690 generator_->PressTouch(); |
684 generator_->ReleaseTouch(); | 691 generator_->ReleaseTouch(); |
685 gfx::Point second_tap_location(23, 24); | 692 gfx::Point second_tap_location(23, 24); |
686 generator_->set_current_location(second_tap_location); | 693 generator_->set_current_location(second_tap_location); |
687 generator_->PressTouch(); | 694 generator_->PressTouch(); |
688 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(8000)); | 695 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout); |
689 generator_->ReleaseTouch(); | 696 generator_->ReleaseTouch(); |
690 | 697 |
691 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); | 698 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
692 ASSERT_EQ(2U, captured_events.size()); | 699 ASSERT_EQ(2U, captured_events.size()); |
693 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); | 700 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); |
694 EXPECT_EQ(tap_location, captured_events[0]->location()); | 701 EXPECT_EQ(tap_location, captured_events[0]->location()); |
695 base::TimeDelta pressed_time = captured_events[0]->time_stamp(); | 702 base::TimeDelta pressed_time = captured_events[0]->time_stamp(); |
696 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); | 703 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); |
697 EXPECT_EQ(tap_location, captured_events[1]->location()); | 704 EXPECT_EQ(tap_location, captured_events[1]->location()); |
698 base::TimeDelta released_time = captured_events[1]->time_stamp(); | 705 base::TimeDelta released_time = captured_events[1]->time_stamp(); |
699 EXPECT_EQ( | 706 EXPECT_EQ(gesture_detector_config_.longpress_timeout, |
700 base::TimeDelta::FromMilliseconds(8000), | 707 released_time - pressed_time); |
701 released_time - pressed_time); | 708 } |
702 } | 709 |
| 710 // Double-tapping without coming from touch exploration (no previous touch |
| 711 // exploration event) should not generate any events. |
| 712 TEST_F(TouchExplorationTest, DoubleTapNoTouchExplore) { |
| 713 SwitchTouchExplorationMode(true); |
| 714 |
| 715 // Double-tap without any previous touch. |
| 716 // Touch exploration mode has not been entered, so there is no previous |
| 717 // touch exploration event. The double-tap should be discarded, and no events |
| 718 // should be generated at all. |
| 719 gfx::Point double_tap_location(33, 34); |
| 720 generator_->set_current_location(double_tap_location); |
| 721 generator_->PressTouch(); |
| 722 generator_->ReleaseTouch(); |
| 723 generator_->PressTouch(); |
| 724 generator_->ReleaseTouch(); |
| 725 |
| 726 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
| 727 ASSERT_EQ(0U, captured_events.size()); |
| 728 } |
| 729 |
| 730 // Tapping and releasing with a second finger when in touch exploration mode |
| 731 // should send a touch press and released to the location of the last |
| 732 // successful touch exploration and return to touch explore. |
| 733 TEST_F(TouchExplorationTest, SplitTap) { |
| 734 SwitchTouchExplorationMode(true); |
| 735 gfx::Point initial_touch_location(11, 12); |
| 736 gfx::Point second_touch_location(33, 34); |
| 737 |
| 738 // Tap and hold at one location, and get a mouse move event in touch explore. |
| 739 EnterTouchExplorationModeAtLocation(initial_touch_location); |
| 740 std::vector<ui::LocatedEvent*> events = |
| 741 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED); |
| 742 ASSERT_EQ(1U, events.size()); |
| 743 |
| 744 EXPECT_EQ(initial_touch_location, events[0]->location()); |
| 745 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); |
| 746 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); |
| 747 ClearCapturedEvents(); |
| 748 |
| 749 // Now tap and release at a different location. This should result in a |
| 750 // single touch and release at the location of the first (held) tap, |
| 751 // not at the location of the second tap and release. |
| 752 // After the release, there is still a finger in touch explore mode. |
| 753 ui::TouchEvent split_tap_press( |
| 754 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); |
| 755 generator_->Dispatch(&split_tap_press); |
| 756 ui::TouchEvent split_tap_release( |
| 757 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now()); |
| 758 generator_->Dispatch(&split_tap_release); |
| 759 EXPECT_FALSE(IsInNoFingersDownState()); |
| 760 |
| 761 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
| 762 ASSERT_EQ(2U, captured_events.size()); |
| 763 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); |
| 764 EXPECT_EQ(initial_touch_location, captured_events[0]->location()); |
| 765 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); |
| 766 EXPECT_EQ(initial_touch_location, captured_events[1]->location()); |
| 767 } |
| 768 |
| 769 // If split tap is started but the touch explore finger is released first, |
| 770 // there should still be a touch press and release sent to the location of |
| 771 // the last successful touch exploration. |
| 772 // Both fingers should be released after the click goes through. |
| 773 TEST_F(TouchExplorationTest, SplitTapRelease) { |
| 774 SwitchTouchExplorationMode(true); |
| 775 |
| 776 gfx::Point initial_touch_location(11, 12); |
| 777 gfx::Point second_touch_location(33, 34); |
| 778 |
| 779 // Tap and hold at one location, and get a mouse move event in touch explore. |
| 780 EnterTouchExplorationModeAtLocation(initial_touch_location); |
| 781 |
| 782 std::vector<ui::LocatedEvent*> events = |
| 783 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED); |
| 784 ASSERT_EQ(1U, events.size()); |
| 785 |
| 786 ClearCapturedEvents(); |
| 787 |
| 788 // Now tap at a different location. Release at the first location, |
| 789 // then release at the second. This should result in a |
| 790 // single touch and release at the location of the first (held) tap, |
| 791 // not at the location of the second tap and release. |
| 792 ui::TouchEvent split_tap_press( |
| 793 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); |
| 794 generator_->Dispatch(&split_tap_press); |
| 795 ui::TouchEvent touch_explore_release( |
| 796 ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now()); |
| 797 generator_->Dispatch(&touch_explore_release); |
| 798 ui::TouchEvent split_tap_release( |
| 799 ui::ET_TOUCH_RELEASED, second_touch_location , 1, Now()); |
| 800 generator_->Dispatch(&split_tap_release); |
| 801 EXPECT_TRUE(IsInNoFingersDownState()); |
| 802 |
| 803 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
| 804 ASSERT_EQ(2U, captured_events.size()); |
| 805 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); |
| 806 EXPECT_EQ(initial_touch_location, captured_events[0]->location()); |
| 807 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); |
| 808 EXPECT_EQ(initial_touch_location, captured_events[1]->location()); |
| 809 } |
| 810 |
| 811 // When in touch exploration mode, making a long press with a second finger |
| 812 // should send a touch press and released to the location of the last |
| 813 // successful touch exploration. There should be a delay between the |
| 814 // touch and release events (right click). |
| 815 TEST_F(TouchExplorationTest, SplitTapLongPress) { |
| 816 SwitchTouchExplorationMode(true); |
| 817 gfx::Point initial_touch_location(11, 12); |
| 818 gfx::Point second_touch_location(33, 34); |
| 819 |
| 820 // Tap and hold at one location, and get a mouse move event in touch explore. |
| 821 EnterTouchExplorationModeAtLocation(initial_touch_location); |
| 822 |
| 823 std::vector<ui::LocatedEvent*> events = |
| 824 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED); |
| 825 ASSERT_EQ(1U, events.size()); |
| 826 |
| 827 ClearCapturedEvents(); |
| 828 |
| 829 // Now tap and release at a different location. This should result in a |
| 830 // single touch and release at the location of the first (held) tap, |
| 831 // not at the location of the second tap and release. |
| 832 // After the release, there is still a finger in touch explore mode. |
| 833 ui::TouchEvent split_tap_press( |
| 834 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); |
| 835 generator_->Dispatch(&split_tap_press); |
| 836 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout); |
| 837 ui::TouchEvent split_tap_release( |
| 838 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now()); |
| 839 generator_->Dispatch(&split_tap_release); |
| 840 EXPECT_FALSE(IsInNoFingersDownState()); |
| 841 |
| 842 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
| 843 ASSERT_EQ(2U, captured_events.size()); |
| 844 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); |
| 845 EXPECT_EQ(initial_touch_location, captured_events[0]->location()); |
| 846 base::TimeDelta pressed_time = captured_events[0]->time_stamp(); |
| 847 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); |
| 848 EXPECT_EQ(initial_touch_location, captured_events[1]->location()); |
| 849 base::TimeDelta released_time = captured_events[1]->time_stamp(); |
| 850 EXPECT_EQ(gesture_detector_config_.longpress_timeout, |
| 851 released_time - pressed_time); |
| 852 } |
| 853 |
| 854 // If split tap is started but the touch explore finger is released first, |
| 855 // there should still be a touch press and release sent to the location of |
| 856 // the last successful touch exploration. If the remaining finger is held |
| 857 // as a longpress, there should be a delay between the sent touch and release |
| 858 // events (right click).All fingers should be released after the click |
| 859 // goes through. |
| 860 TEST_F(TouchExplorationTest, SplitTapReleaseLongPress) { |
| 861 SwitchTouchExplorationMode(true); |
| 862 gfx::Point initial_touch_location(11, 12); |
| 863 gfx::Point second_touch_location(33, 34); |
| 864 |
| 865 // Tap and hold at one location, and get a mouse move event in touch explore. |
| 866 EnterTouchExplorationModeAtLocation(initial_touch_location); |
| 867 |
| 868 std::vector<ui::LocatedEvent*> events = |
| 869 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED); |
| 870 ASSERT_EQ(1U, events.size()); |
| 871 ClearCapturedEvents(); |
| 872 |
| 873 // Now tap at a different location. Release at the first location, |
| 874 // then release at the second. This should result in a |
| 875 // single touch and release at the location of the first (held) tap, |
| 876 // not at the location of the second tap and release. |
| 877 // After the release, TouchToMouseMode should still be on. |
| 878 ui::TouchEvent split_tap_press( |
| 879 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); |
| 880 generator_->Dispatch(&split_tap_press); |
| 881 ui::TouchEvent touch_explore_release( |
| 882 ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now()); |
| 883 generator_->Dispatch(&touch_explore_release); |
| 884 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout); |
| 885 ui::TouchEvent split_tap_release( |
| 886 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now()); |
| 887 generator_->Dispatch(&split_tap_release); |
| 888 EXPECT_TRUE(IsInTouchToMouseMode()); |
| 889 |
| 890 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
| 891 ASSERT_EQ(2U, captured_events.size()); |
| 892 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); |
| 893 EXPECT_EQ(initial_touch_location, captured_events[0]->location()); |
| 894 base::TimeDelta pressed_time = captured_events[0]->time_stamp(); |
| 895 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); |
| 896 EXPECT_EQ(initial_touch_location, captured_events[1]->location()); |
| 897 base::TimeDelta released_time = captured_events[1]->time_stamp(); |
| 898 EXPECT_EQ(gesture_detector_config_.longpress_timeout, |
| 899 released_time - pressed_time); |
| 900 } |
| 901 |
703 | 902 |
704 } // namespace ui | 903 } // namespace ui |
OLD | NEW |