Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(607)

Side by Side Diff: ui/chromeos/touch_exploration_controller_unittest.cc

Issue 358693004: Added touch event permutations test to touch_exploration_controller. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new_passthrough
Patch Set: rebased again because failure to apply the patch Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/chromeos/touch_exploration_controller.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/gestures/gesture_provider_aura.h" 16 #include "ui/events/gestures/gesture_provider_aura.h"
17 #include "ui/events/test/events_test_utils.h"
17 #include "ui/gfx/geometry/point.h" 18 #include "ui/gfx/geometry/point.h"
18 #include "ui/gl/gl_implementation.h" 19 #include "ui/gl/gl_implementation.h"
19 #include "ui/gl/gl_surface.h" 20 #include "ui/gl/gl_surface.h"
20 21
21 namespace ui { 22 namespace ui {
22 23
23 namespace { 24 namespace {
24 // Records all mouse, touch, gesture, and key events. 25 // Records all mouse, touch, gesture, and key events.
25 class EventCapturer : public ui::EventHandler { 26 class EventCapturer : public ui::EventHandler {
26 public: 27 public:
(...skipping 28 matching lines...) Expand all
55 } 56 }
56 57
57 const ScopedVector<ui::Event>& captured_events() const { return events_; } 58 const ScopedVector<ui::Event>& captured_events() const { return events_; }
58 59
59 private: 60 private:
60 ScopedVector<ui::Event> events_; 61 ScopedVector<ui::Event> events_;
61 62
62 DISALLOW_COPY_AND_ASSIGN(EventCapturer); 63 DISALLOW_COPY_AND_ASSIGN(EventCapturer);
63 }; 64 };
64 65
66 int Factorial(int n) {
67 if (n <= 0)
68 return 0;
69 if (n == 1)
70 return 1;
71 return n * Factorial(n - 1);
72 }
73
65 } // namespace 74 } // namespace
66 75
67 class TouchExplorationTest : public aura::test::AuraTestBase { 76 class TouchExplorationTest : public aura::test::AuraTestBase {
68 public: 77 public:
69 TouchExplorationTest() : simulated_clock_(new base::SimpleTestTickClock()) { 78 TouchExplorationTest() : simulated_clock_(new base::SimpleTestTickClock()) {
70 // Tests fail if time is ever 0. 79 // Tests fail if time is ever 0.
71 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); 80 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
72 } 81 }
73 virtual ~TouchExplorationTest() {} 82 virtual ~TouchExplorationTest() {}
74 83
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 143
135 void ClearCapturedEvents() { 144 void ClearCapturedEvents() {
136 event_capturer_.Reset(); 145 event_capturer_.Reset();
137 } 146 }
138 147
139 void AdvanceSimulatedTimePastTapDelay() { 148 void AdvanceSimulatedTimePastTapDelay() {
140 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); 149 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
141 touch_exploration_controller_->CallTapTimerNowForTesting(); 150 touch_exploration_controller_->CallTapTimerNowForTesting();
142 } 151 }
143 152
153 void AdvanceSimulatedTimePastPotentialTapDelay() {
154 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
155 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting();
156 }
157
158 void SuppressVLOGs(bool suppress) {
159 touch_exploration_controller_->SuppressVLOGsForTesting(suppress);
160 }
161
144 void SwitchTouchExplorationMode(bool on) { 162 void SwitchTouchExplorationMode(bool on) {
145 if (!on && touch_exploration_controller_.get()) { 163 if (!on && touch_exploration_controller_.get()) {
146 touch_exploration_controller_.reset(); 164 touch_exploration_controller_.reset();
147 } else if (on && !touch_exploration_controller_.get()) { 165 } else if (on && !touch_exploration_controller_.get()) {
148 touch_exploration_controller_.reset( 166 touch_exploration_controller_.reset(
149 new ui::TouchExplorationController(root_window())); 167 new ui::TouchExplorationController(root_window()));
150 touch_exploration_controller_->SetEventHandlerForTesting( 168 touch_exploration_controller_->SetEventHandlerForTesting(
151 &event_capturer_); 169 &event_capturer_);
152 cursor_client()->ShowCursor(); 170 cursor_client()->ShowCursor();
153 cursor_client()->DisableMouseEvents(); 171 cursor_client()->DisableMouseEvents();
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 1150
1133 // The swipe registered and sent the appropriate key events. 1151 // The swipe registered and sent the appropriate key events.
1134 AssertDirectionalNavigationEvents(captured_events, direction); 1152 AssertDirectionalNavigationEvents(captured_events, direction);
1135 EXPECT_TRUE(IsInNoFingersDownState()); 1153 EXPECT_TRUE(IsInNoFingersDownState());
1136 EXPECT_FALSE(IsInTouchToMouseMode()); 1154 EXPECT_FALSE(IsInTouchToMouseMode());
1137 EXPECT_FALSE(IsInGestureInProgressState()); 1155 EXPECT_FALSE(IsInGestureInProgressState());
1138 ClearCapturedEvents(); 1156 ClearCapturedEvents();
1139 } 1157 }
1140 } 1158 }
1141 1159
1160 // Since there are so many permutations, this test is too slow in debug
1161 // mode, so it will only be run in release mode.
1162 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
1163 #define MAYBE_AllFingerPermutations AllFingerPermutations
1164 #else
1165 #define MAYBE_AllFingerPermutations DISABLED_AllFingerPermutations
1166 #endif
1167
1168 TEST_F(TouchExplorationTest, MAYBE_AllFingerPermutations) {
1169 SwitchTouchExplorationMode(true);
1170 SuppressVLOGs(true);
1171 // We will test all permutations of events from three different fingers
1172 // to ensure that we return to NO_FINGERS_DOWN when fingers have been
1173 // released.
1174 ScopedVector<ui::TouchEvent> all_events;
1175 for (int touch_id = 0; touch_id < 3; touch_id++){
1176 int x = 10*touch_id + 1;
1177 int y = 10*touch_id + 2;
1178 all_events.push_back(new TouchEvent(
1179 ui::ET_TOUCH_PRESSED, gfx::Point(x++, y++), touch_id, Now()));
1180 all_events.push_back(new TouchEvent(
1181 ui::ET_TOUCH_MOVED, gfx::Point(x++, y++), touch_id, Now()));
1182 all_events.push_back(new TouchEvent(
1183 ui::ET_TOUCH_RELEASED, gfx::Point(x, y), touch_id, Now()));
1184 }
1185
1186 // I'm going to explain this algorithm, and use an example in parentheses.
1187 // The example will be all permutations of a b c d.
1188 // There are four letters and 4! = 24 permutations.
1189 const int num_events = all_events.size();
1190 const int num_permutations = Factorial(num_events);
1191
1192 for (int p = 0; p < num_permutations; p++) {
1193 std::vector<ui::TouchEvent*> queued_events = all_events.get();
1194 std::vector<bool> fingers_pressed(3, false);
1195
1196 int current_num_permutations = num_permutations;
1197 for (int events_left = num_events; events_left > 0; events_left--) {
1198 // |p| indexes to each permutation when there are num_permutations
1199 // permutations. (e.g. 0 is abcd, 1 is abdc, 2 is acbd, 3 is acdb...)
1200 // But how do we find the index for the current number of permutations?
1201 // To find the permutation within the part of the sequence we're
1202 // currently looking at, we need a number between 0 and
1203 // |current_num_permutations| - 1.
1204 // (e.g. if we already chose the first letter, there are 3! = 6
1205 // options left, so we do p % 6. So |current_permutation| would go
1206 // from 0 to 5 and then reset to 0 again, for all combinations of
1207 // whichever three letters are remaining, as we loop through the
1208 // permutations)
1209 int current_permutation = p % current_num_permutations;
1210
1211 // Since this is is the total number of permutations starting with
1212 // this event and including future events, there could be multiple
1213 // values of current_permutation that will generate the same event
1214 // in this iteration.
1215 // (e.g. If we chose 'a' but have b c d to choose from, we choose b when
1216 // |current_permutation| = 0, 1 and c when |current_permutation| = 2, 3.
1217 // Note that each letter gets two numbers, which is the next
1218 // current_num_permutations, 2! for the two letters left.)
1219
1220 // Branching out from the first event, there are num_permutations
1221 // permutations, and each value of |p| is associated with one of these
1222 // permutations. However, once the first event is chosen, there
1223 // are now |num_events| - 1 events left, so the number of permutations
1224 // for the rest of the events changes, and will always be equal to
1225 // the factorial of the events_left.
1226 // (e.g. There are 3! = 6 permutations that start with 'a', so if we
1227 // start with 'a' there will be 6 ways to then choose from b c d.)
1228 // So we now set-up for the next iteration by setting
1229 // current_num_permutations to the factorial of the next number of
1230 // events left.
1231 current_num_permutations /= events_left;
1232
1233 // To figure out what current event we want to choose, we integer
1234 // divide the current permutation by the next current_num_permutations.
1235 // (e.g. If there are 4 letters a b c d and 24 permutations, we divide
1236 // by 24/4 = 6. Values 0 to 5 when divided by 6 equals 0, so the first
1237 // 6 permutations start with 'a', and the last 6 will start with 'd'.
1238 // Note that there are 6 that start with 'a' because there are 6
1239 // permutations for the next three letters that follow 'a'.)
1240 int index = current_permutation / current_num_permutations;
1241
1242 ui::TouchEvent* next_dispatch = queued_events[index];
1243 ASSERT_TRUE(next_dispatch != NULL);
1244
1245 // |next_dispatch| has to be put in this container so that its time
1246 // stamp can be changed to this point in the test, when it is being
1247 // dispatched..
1248 EventTestApi test_dispatch(next_dispatch);
1249 test_dispatch.set_time_stamp(Now());
1250 generator_->Dispatch(next_dispatch);
1251 queued_events.erase(queued_events.begin() + index);
1252
1253 // Keep track of what fingers have been pressed, to release
1254 // only those fingers at the end, so the check for being in
1255 // no fingers down can be accurate.
1256 if (next_dispatch->type() == ET_TOUCH_PRESSED) {
1257 fingers_pressed[next_dispatch->touch_id()] = true;
1258 } else if (next_dispatch->type() == ET_TOUCH_RELEASED) {
1259 fingers_pressed[next_dispatch->touch_id()] = false;
1260 }
1261 }
1262 ASSERT_EQ(queued_events.size(), 0u);
1263
1264 // Release fingers recorded as pressed.
1265 for(int j = 0; j < int(fingers_pressed.size()); j++){
1266 if (fingers_pressed[j] == true) {
1267 generator_->ReleaseTouchId(j);
1268 fingers_pressed[j] = false;
1269 }
1270 }
1271 AdvanceSimulatedTimePastPotentialTapDelay();
1272 EXPECT_TRUE(IsInNoFingersDownState());
1273 ClearCapturedEvents();
1274 }
1275 }
1276
1142 // With the simple swipe gestures, if additional fingers are added, then the 1277 // With the simple swipe gestures, if additional fingers are added, then the
1143 // state should change to passthrough. 1278 // state should change to passthrough.
1144 TEST_F(TouchExplorationTest, FromGestureToPassthrough) { 1279 TEST_F(TouchExplorationTest, FromGestureToPassthrough) {
1145 SwitchTouchExplorationMode(true); 1280 SwitchTouchExplorationMode(true);
1146 EXPECT_FALSE(IsInTouchToMouseMode()); 1281 EXPECT_FALSE(IsInTouchToMouseMode());
1147 EXPECT_FALSE(IsInGestureInProgressState()); 1282 EXPECT_FALSE(IsInGestureInProgressState());
1148 1283
1149 float distance = gesture_detector_config_.touch_slop + 1; 1284 float distance = gesture_detector_config_.touch_slop + 1;
1150 ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 1), 0, Now()); 1285 ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 1), 0, Now());
1151 generator_->Dispatch(&first_press); 1286 generator_->Dispatch(&first_press);
(...skipping 20 matching lines...) Expand all
1172 // The rest of the events should occur in passthrough. 1307 // The rest of the events should occur in passthrough.
1173 generator_->ReleaseTouchId(0); 1308 generator_->ReleaseTouchId(0);
1174 ASSERT_EQ(1U, captured_events.size()); 1309 ASSERT_EQ(1U, captured_events.size());
1175 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type()); 1310 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type());
1176 ClearCapturedEvents(); 1311 ClearCapturedEvents();
1177 generator_->ReleaseTouchId(1); 1312 generator_->ReleaseTouchId(1);
1178 ASSERT_EQ(0U, captured_events.size()); 1313 ASSERT_EQ(0U, captured_events.size());
1179 } 1314 }
1180 1315
1181 } // namespace ui 1316 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698