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" |
11 #include "ui/aura/test/event_generator.h" | 11 #include "ui/aura/test/event_generator.h" |
12 #include "ui/aura/test/test_cursor_client.h" | 12 #include "ui/aura/test/test_cursor_client.h" |
13 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
14 #include "ui/events/event.h" | 14 #include "ui/events/event.h" |
15 #include "ui/events/event_utils.h" | 15 #include "ui/events/event_utils.h" |
16 #include "ui/events/test/events_test_utils.h" | |
16 #include "ui/gfx/geometry/point.h" | 17 #include "ui/gfx/geometry/point.h" |
17 #include "ui/gl/gl_implementation.h" | 18 #include "ui/gl/gl_implementation.h" |
18 #include "ui/gl/gl_surface.h" | 19 #include "ui/gl/gl_surface.h" |
19 | 20 |
20 namespace ui { | 21 namespace ui { |
21 | 22 |
22 namespace { | 23 namespace { |
23 // Records all mouse and touch events. | 24 // Records all mouse and touch events. |
24 class EventCapturer : public ui::EventHandler { | 25 class EventCapturer : public ui::EventHandler { |
25 public: | 26 public: |
(...skipping 24 matching lines...) Expand all Loading... | |
50 const ScopedVector<ui::LocatedEvent>& captured_events() const { | 51 const ScopedVector<ui::LocatedEvent>& captured_events() const { |
51 return events_; | 52 return events_; |
52 } | 53 } |
53 | 54 |
54 private: | 55 private: |
55 ScopedVector<ui::LocatedEvent> events_; | 56 ScopedVector<ui::LocatedEvent> events_; |
56 | 57 |
57 DISALLOW_COPY_AND_ASSIGN(EventCapturer); | 58 DISALLOW_COPY_AND_ASSIGN(EventCapturer); |
58 }; | 59 }; |
59 | 60 |
61 int Factorial(int n) { | |
62 if (n <= 0) | |
63 return 0; | |
64 if (n == 1) | |
65 return 1; | |
66 return n * Factorial(n - 1); | |
67 } | |
68 | |
60 } // namespace | 69 } // namespace |
61 | 70 |
62 class TouchExplorationTest : public aura::test::AuraTestBase { | 71 class TouchExplorationTest : public aura::test::AuraTestBase { |
63 public: | 72 public: |
64 TouchExplorationTest() | 73 TouchExplorationTest() |
65 : simulated_clock_(new base::SimpleTestTickClock()) {} | 74 : simulated_clock_(new base::SimpleTestTickClock()) {} |
66 virtual ~TouchExplorationTest() {} | 75 virtual ~TouchExplorationTest() {} |
67 | 76 |
68 virtual void SetUp() OVERRIDE { | 77 virtual void SetUp() OVERRIDE { |
69 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) | 78 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 | 113 |
105 void ClearCapturedEvents() { | 114 void ClearCapturedEvents() { |
106 event_capturer_.Reset(); | 115 event_capturer_.Reset(); |
107 } | 116 } |
108 | 117 |
109 void AdvanceSimulatedTimePastTapDelay() { | 118 void AdvanceSimulatedTimePastTapDelay() { |
110 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); | 119 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); |
111 touch_exploration_controller_->CallTapTimerNowForTesting(); | 120 touch_exploration_controller_->CallTapTimerNowForTesting(); |
112 } | 121 } |
113 | 122 |
123 void AdvanceSimulatedTimePastPotentialTapDelay() { | |
124 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); | |
125 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); | |
126 } | |
127 | |
128 void SwitchVLOG(bool turn_on) { | |
129 touch_exploration_controller_->SwitchVLOG(turn_on); | |
130 } | |
131 | |
114 void SwitchTouchExplorationMode(bool on) { | 132 void SwitchTouchExplorationMode(bool on) { |
115 if (!on && touch_exploration_controller_.get()) { | 133 if (!on && touch_exploration_controller_.get()) { |
116 touch_exploration_controller_.reset(); | 134 touch_exploration_controller_.reset(); |
117 } else if (on && !touch_exploration_controller_.get()) { | 135 } else if (on && !touch_exploration_controller_.get()) { |
118 touch_exploration_controller_.reset( | 136 touch_exploration_controller_.reset( |
119 new ui::TouchExplorationController(root_window())); | 137 new ui::TouchExplorationController(root_window())); |
120 touch_exploration_controller_->SetEventHandlerForTesting( | 138 touch_exploration_controller_->SetEventHandlerForTesting( |
121 &event_capturer_); | 139 &event_capturer_); |
122 cursor_client()->ShowCursor(); | 140 cursor_client()->ShowCursor(); |
123 cursor_client()->DisableMouseEvents(); | 141 cursor_client()->DisableMouseEvents(); |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
834 // in TwoToOneFinger. | 852 // in TwoToOneFinger. |
835 TEST_F(TouchExplorationTest, TwoToOneFingerRelaseFirst) { | 853 TEST_F(TouchExplorationTest, TwoToOneFingerRelaseFirst) { |
836 gfx::Point first_touch_location = gfx::Point(11,12); | 854 gfx::Point first_touch_location = gfx::Point(11,12); |
837 gfx::Point second_touch_location = gfx::Point(21, 22); | 855 gfx::Point second_touch_location = gfx::Point(21, 22); |
838 EnterTwoToOne(first_touch_location, second_touch_location); | 856 EnterTwoToOne(first_touch_location, second_touch_location); |
839 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); | 857 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); |
840 ASSERT_EQ(captured_events.size(), 1u); | 858 ASSERT_EQ(captured_events.size(), 1u); |
841 ClearCapturedEvents(); | 859 ClearCapturedEvents(); |
842 | 860 |
843 // Actions before release have already been tested in the previous test. | 861 // Actions before release have already been tested in the previous test. |
844 | 862 |
dmazzoni
2014/07/02 23:05:58
Delete extra line
| |
845 // A release of the first finger should send an event, as the state | 863 // A release of the first finger should send an event, as the state |
846 // changes to the wait state. | 864 // changes to the wait state. |
847 ui::TouchEvent first_touch_release( | 865 ui::TouchEvent first_touch_release( |
848 ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now()); | 866 ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now()); |
849 generator_->Dispatch(&first_touch_release); | 867 generator_->Dispatch(&first_touch_release); |
850 ASSERT_EQ(captured_events.size(), 1u); | 868 ASSERT_EQ(captured_events.size(), 1u); |
851 ClearCapturedEvents(); | 869 ClearCapturedEvents(); |
852 | 870 |
853 // No events should be sent after the second finger is lifted. | 871 // No events should be sent after the second finger is lifted. |
854 | 872 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 EXPECT_EQ(first_touch_location, captured_events[0]->location()); | 959 EXPECT_EQ(first_touch_location, captured_events[0]->location()); |
942 ClearCapturedEvents(); | 960 ClearCapturedEvents(); |
943 | 961 |
944 ui::TouchEvent first_touch_release( | 962 ui::TouchEvent first_touch_release( |
945 ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now()); | 963 ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now()); |
946 generator_->Dispatch(&first_touch_release); | 964 generator_->Dispatch(&first_touch_release); |
947 ASSERT_EQ(captured_events.size(), 1u); | 965 ASSERT_EQ(captured_events.size(), 1u); |
948 EXPECT_TRUE(IsInNoFingersDownState()); | 966 EXPECT_TRUE(IsInNoFingersDownState()); |
949 } | 967 } |
950 | 968 |
969 TEST_F(TouchExplorationTest, AllFingerPermutations) { | |
970 SwitchTouchExplorationMode(true); | |
971 SwitchVLOG(false); | |
972 // We will test all permutations of events from three different fingers | |
973 // to ensure that we return to NO_FINGERS_DOWN when fingers have been | |
974 // released. | |
975 ScopedVector<ui::TouchEvent> all_events; | |
976 for (int touch_id = 0; touch_id < 3; touch_id++){ | |
977 int x = 10*touch_id + 1; | |
978 int y = 10*touch_id + 2; | |
979 all_events.push_back(new TouchEvent( | |
980 ui::ET_TOUCH_PRESSED, gfx::Point(x++, y++), touch_id, Now())); | |
981 all_events.push_back(new TouchEvent( | |
982 ui::ET_TOUCH_MOVED, gfx::Point(x++, y++), touch_id, Now())); | |
983 all_events.push_back(new TouchEvent( | |
984 ui::ET_TOUCH_RELEASED, gfx::Point(x, y), touch_id, Now())); | |
985 } | |
986 | |
987 // I'm going to explain this algorithm, and use an example in parentheses. | |
988 // The example will be all permutations of a b c d. | |
989 // There are four letters and 4! = 24 permutations. | |
990 const int num_events = all_events.size(); | |
991 const int num_permutations = Factorial(num_events); | |
992 | |
993 for (int p = 0; p < num_permutations; p++) { | |
994 std::vector<ui::TouchEvent*> queued_events = all_events.get(); | |
995 std::vector<bool> fingers_pressed(3, false); | |
996 | |
997 int current_num_permutations = num_permutations; | |
998 for (int events_left = num_events; events_left > 0; events_left--) { | |
999 // |p| indexes to each permutation when there are num_permutations | |
1000 // permutations. (e.g. 0 is abcd, 1 is abdc, 2 is acbd, 3 is acdb...) | |
1001 // But how do we find the index for the current number of permutations? | |
1002 // To find the permutation within the part of the sequence we're | |
1003 // currently looking at, we need a number between 0 and | |
1004 // |current_num_permutations| - 1. | |
1005 // (e.g. if we already chose the first letter, there are 3! = 6 | |
1006 // options left, so we do p % 6. So |current_permutation| would go | |
1007 // from 0 to 5 and then reset to 0 again, for all combinations of | |
1008 // whichever three letters are remaining, as we loop through the | |
1009 // permutations) | |
1010 int current_permutation = p % current_num_permutations; | |
1011 | |
1012 // Since this is is the total number of permutations starting with | |
1013 // this event and including future events, there could be multiple | |
1014 // values of current_permutation that will generate the same event | |
1015 // in this iteration. | |
1016 // (e.g. If we chose 'a' but have b c d to choose from, we choose b when | |
1017 // |current_permutation| = 0, 1 and c when |current_permutation| = 2, 3. | |
1018 // Note that each letter gets two numbers, which is the next | |
1019 // current_num_permutations, 2! for the two letters left.) | |
1020 | |
1021 // Branching out from the first event, there are num_permutations | |
1022 // permutations, and each value of |p| is associated with one of these | |
1023 // permutations. However, once the first event is chosen, there | |
1024 // are now |num_events| - 1 events left, so the number of permutations | |
1025 // for the rest of the events changes, and will always be equal to | |
1026 // the factorial of the events_left. | |
1027 // (e.g. There are 3! = 6 permutations that start with 'a', so if we | |
1028 // start with 'a' there will be 6 ways to then choose from b c d.) | |
1029 // So we now set-up for the next iteration by setting | |
1030 // current_num_permutations to the factorial of the next number of | |
1031 // events left. | |
1032 current_num_permutations /= events_left; | |
1033 | |
1034 // To figure out what current event we want to choose, we integer | |
1035 // divide the current permutation by the next current_num_permutations. | |
1036 // (e.g. If there are 4 letters a b c d and 24 permutations, we divide | |
1037 // by 24/4 = 6. Values 0 to 5 when divided by 6 equals 0, so the first | |
1038 // 6 permutations start with 'a', and the last 6 will start with 'd'. | |
1039 // Note that there are 6 that start with 'a' because there are 6 | |
1040 // permutations for the next three letters that follow 'a'.) | |
1041 int index = current_permutation / current_num_permutations; | |
1042 | |
1043 ui::TouchEvent* next_dispatch = queued_events[index]; | |
1044 ASSERT_TRUE(next_dispatch != NULL); | |
1045 | |
1046 // |next_dispatch| has to be put in this container so that its time | |
1047 // stamp can be changed to this point in the test, when it is being | |
1048 // dispatched.. | |
1049 EventTestApi test_dispatch(next_dispatch); | |
1050 test_dispatch.set_time_stamp(Now()); | |
1051 generator_->Dispatch(next_dispatch); | |
1052 queued_events.erase(queued_events.begin() + index); | |
1053 | |
1054 // Keep track of what fingers have been pressed, to release | |
1055 // only those fingers at the end, so the check for being in | |
1056 // no fingers down can be accurate. | |
1057 if (next_dispatch->type() == ET_TOUCH_PRESSED) { | |
1058 fingers_pressed[next_dispatch->touch_id()] = true; | |
1059 } else if (next_dispatch->type() == ET_TOUCH_RELEASED) { | |
1060 fingers_pressed[next_dispatch->touch_id()] = false; | |
1061 } | |
1062 } | |
1063 ASSERT_EQ(queued_events.size(), 0u); | |
1064 | |
1065 // Release fingers recorded as pressed. | |
1066 for(int j = 0; j < int(fingers_pressed.size()); j++){ | |
1067 if (fingers_pressed[j] == true) { | |
1068 generator_->ReleaseTouchId(j); | |
1069 fingers_pressed[j] = false; | |
1070 } | |
1071 } | |
1072 AdvanceSimulatedTimePastPotentialTapDelay(); | |
1073 EXPECT_TRUE(IsInNoFingersDownState()); | |
1074 ClearCapturedEvents(); | |
1075 } | |
1076 } | |
1077 | |
951 } // namespace ui | 1078 } // namespace ui |
OLD | NEW |