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 if (n == 2) | |
67 return 2; | |
68 return n * Factorial(n - 1); | |
69 } | |
70 | |
60 } // namespace | 71 } // namespace |
61 | 72 |
62 class TouchExplorationTest : public aura::test::AuraTestBase { | 73 class TouchExplorationTest : public aura::test::AuraTestBase { |
63 public: | 74 public: |
64 TouchExplorationTest() | 75 TouchExplorationTest() |
65 : simulated_clock_(new base::SimpleTestTickClock()) {} | 76 : simulated_clock_(new base::SimpleTestTickClock()) {} |
66 virtual ~TouchExplorationTest() {} | 77 virtual ~TouchExplorationTest() {} |
67 | 78 |
68 virtual void SetUp() OVERRIDE { | 79 virtual void SetUp() OVERRIDE { |
69 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) | 80 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) |
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 EXPECT_EQ(first_touch_location, captured_events[0]->location()); | 952 EXPECT_EQ(first_touch_location, captured_events[0]->location()); |
942 ClearCapturedEvents(); | 953 ClearCapturedEvents(); |
943 | 954 |
944 ui::TouchEvent first_touch_release( | 955 ui::TouchEvent first_touch_release( |
945 ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now()); | 956 ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now()); |
946 generator_->Dispatch(&first_touch_release); | 957 generator_->Dispatch(&first_touch_release); |
947 ASSERT_EQ(captured_events.size(), 1u); | 958 ASSERT_EQ(captured_events.size(), 1u); |
948 EXPECT_TRUE(IsInNoFingersDownState()); | 959 EXPECT_TRUE(IsInNoFingersDownState()); |
949 } | 960 } |
950 | 961 |
962 TEST_F(TouchExplorationTest, AllFingerPermutations) { | |
963 SwitchTouchExplorationMode(true); | |
964 | |
965 // We will test all permutations of events from three different fingers | |
966 // to ensure that we return to NO_FINGERS_DOWN when fingers have been | |
967 // released. | |
968 ScopedVector<ui::TouchEvent> all_events; | |
969 for (int touch_id = 0; touch_id < 3; touch_id++){ | |
970 int x = 10*touch_id + 1; | |
aboxhall
2014/06/30 18:19:36
I think you might want to initialise these outside
evy
2014/06/30 18:35:26
Oh, yeah I guess I can just increment by one each.
| |
971 int y = 10*touch_id + 2; | |
972 all_events.push_back(new TouchEvent( | |
973 ui::ET_TOUCH_PRESSED, gfx::Point(x, y), touch_id, Now())); | |
974 x += 2; | |
975 y += 2; | |
976 all_events.push_back( | |
977 new TouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(x, y), touch_id, Now())); | |
978 x += 2; | |
979 y += 2; | |
980 all_events.push_back(new TouchEvent( | |
981 ui::ET_TOUCH_RELEASED, gfx::Point(x, y), touch_id, Now())); | |
982 } | |
983 | |
984 // I'm going to explain this algorithm, and use an example in parenthesis. | |
985 // The example will be all permutations of a b c d. | |
986 // There are four letters and 4! = 24 permutations. | |
987 const int num_events = all_events.size(); | |
988 const int num_permutations = Factorial(num_events); | |
989 | |
990 for (int p = 0; p < num_permutations; p++) { | |
991 std::vector<ui::TouchEvent*> queued_events = all_events.get(); | |
992 std::vector<bool> fingers_pressed(3, false); | |
993 // Branching out from the first event, there are num_permutations | |
994 // permutations, and each value of p is associated with one of these | |
995 // permutations. However, once the first event is chosen, there | |
996 // are now num_events - 1 events left, so the number of permutations | |
997 // for the rest of the events changes, and will always be equal to | |
998 // the factorial of the events_left. | |
999 // (e.g. There are 3! = 6 permutations that start with 'a', so if we | |
1000 // start with 'a' there will be 6 ways to then choose from b c d.) | |
1001 int current_num_permutations = num_permutations; | |
1002 for (int events_left = num_events; events_left > 0; events_left--) { | |
1003 // p indexes to each permutation when there are num_permutations | |
1004 // permutations. (e.g. 0 is abcd and 1 is abdc.) | |
1005 // But how do we find the index for current_num_permutations? | |
aboxhall
2014/06/30 18:19:36
This sentence took me a couple of goes to understa
evy
2014/06/30 18:35:26
Done.
| |
1006 // We need a number between 0 and current_num_permutations - 1. | |
1007 // (e.g. if we already chose the first letter, there are 3! = 6 | |
1008 // options left, so we do p % 6. So current_permutation would go | |
1009 // from 0 to 5 and then reset to 0 again, for all combinations of | |
1010 // whichever three letters are remaining, as we loop through the | |
1011 // permutations) | |
1012 int current_permutation = p % current_num_permutations; | |
1013 // Since this is is the total number of permutations starting with | |
1014 // this event and including future events, there could be multiple | |
1015 // values of current_permutation that will generate the same event | |
1016 // in this iteration. | |
1017 // (e.g. If we chose 'a' but have b c d to choose from, we choose b when | |
1018 // current_permutation = 0, 1 and c when current_permutation = 2, 3.) | |
1019 // So to figure out what current event we want to choose, we divide | |
aboxhall
2014/06/30 18:19:36
This step is still a little unclear to me. I think
evy
2014/06/30 18:35:26
Done.
| |
1020 // current_num_permutations by the number of events to choose from, | |
1021 // events_left. We then integer divide the current permutation by | |
1022 // this new value. | |
1023 // (e.g. If there are 4 letters a b c d and 24 permutations, we divide | |
1024 // by 24/4 = 6. Values 0 to 5 when divided by 6 equals 0, so the first | |
1025 // 6 permutations start with 'a', and the last 6 will start with 'd'.) | |
1026 int index = | |
1027 current_permutation / (current_num_permutations / events_left); | |
1028 // We now adjust the current_num_permutations to be equal to the | |
1029 // factorial of the next number of events left. | |
1030 current_num_permutations /= events_left; | |
aboxhall
2014/06/30 18:19:36
I think it's worth noting that this is just set-up
evy
2014/06/30 18:35:26
Done.
| |
1031 | |
1032 ui::TouchEvent* next_dispatch = queued_events[index]; | |
1033 ASSERT_TRUE(next_dispatch != NULL); | |
1034 // |next_dispatch| has to be put in this container so that its time | |
1035 // stamp can be changed to this point in the test, when it is being | |
1036 // dispatched.. | |
1037 EventTestApi test_dispatch(next_dispatch); | |
1038 test_dispatch.set_time_stamp(Now()); | |
1039 generator_->Dispatch(next_dispatch); | |
1040 queued_events.erase(queued_events.begin() + index); | |
1041 // Keep track of what fingers have been pressed, to release | |
1042 // only those fingers at the end, so the check for being in | |
1043 // no fingers down can be accurate. | |
1044 if (next_dispatch->type() == ET_TOUCH_PRESSED) { | |
1045 fingers_pressed[next_dispatch->touch_id()] = true; | |
1046 } else if (next_dispatch->type() == ET_TOUCH_RELEASED) { | |
1047 fingers_pressed[next_dispatch->touch_id()] = false; | |
1048 } | |
1049 } | |
1050 ASSERT_EQ(queued_events.size(), 0u); | |
1051 | |
1052 // Release fingers recorded as pressed. | |
1053 for(int j = 0; j < int(fingers_pressed.size()); j++){ | |
1054 if (fingers_pressed[j] == true) { | |
1055 generator_->ReleaseTouchId(j); | |
1056 fingers_pressed[j] = false; | |
1057 } | |
1058 } | |
1059 AdvanceSimulatedTimePastTapDelay(); | |
1060 EXPECT_TRUE(IsInNoFingersDownState()); | |
1061 ClearCapturedEvents(); | |
1062 } | |
1063 } | |
1064 | |
951 } // namespace ui | 1065 } // namespace ui |
OLD | NEW |