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 <math.h> |
7 #include <stddef.h> | 8 #include <stddef.h> |
8 | 9 |
9 #include "base/macros.h" | 10 #include "base/macros.h" |
10 #include "base/test/simple_test_tick_clock.h" | 11 #include "base/test/simple_test_tick_clock.h" |
11 #include "base/time/time.h" | 12 #include "base/time/time.h" |
12 #include "ui/aura/client/cursor_client.h" | 13 #include "ui/aura/client/cursor_client.h" |
13 #include "ui/aura/test/aura_test_base.h" | 14 #include "ui/aura/test/aura_test_base.h" |
14 #include "ui/aura/test/test_cursor_client.h" | 15 #include "ui/aura/test/test_cursor_client.h" |
15 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
16 #include "ui/events/event.h" | 17 #include "ui/events/event.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 : public ui::TouchExplorationControllerDelegate { | 72 : public ui::TouchExplorationControllerDelegate { |
72 public: | 73 public: |
73 void SetOutputLevel(int volume) override { | 74 void SetOutputLevel(int volume) override { |
74 volume_changes_.push_back(volume); | 75 volume_changes_.push_back(volume); |
75 } | 76 } |
76 void SilenceSpokenFeedback() override {} | 77 void SilenceSpokenFeedback() override {} |
77 void PlayVolumeAdjustEarcon() override { ++num_times_adjust_sound_played_; } | 78 void PlayVolumeAdjustEarcon() override { ++num_times_adjust_sound_played_; } |
78 void PlayPassthroughEarcon() override { ++num_times_passthrough_played_; } | 79 void PlayPassthroughEarcon() override { ++num_times_passthrough_played_; } |
79 void PlayExitScreenEarcon() override { ++num_times_exit_screen_played_; } | 80 void PlayExitScreenEarcon() override { ++num_times_exit_screen_played_; } |
80 void PlayEnterScreenEarcon() override { ++num_times_enter_screen_played_; } | 81 void PlayEnterScreenEarcon() override { ++num_times_enter_screen_played_; } |
| 82 void HandleAccessibilityGesture(ui::AXGesture gesture) override { |
| 83 last_gesture_ = gesture; |
| 84 } |
81 | 85 |
82 const std::vector<float> VolumeChanges() { return volume_changes_; } | 86 const std::vector<float> VolumeChanges() const { return volume_changes_; } |
83 size_t NumAdjustSounds() { return num_times_adjust_sound_played_; } | 87 size_t NumAdjustSounds() const { return num_times_adjust_sound_played_; } |
84 size_t NumPassthroughSounds() { return num_times_passthrough_played_; } | 88 size_t NumPassthroughSounds() const { return num_times_passthrough_played_; } |
85 size_t NumExitScreenSounds() { return num_times_exit_screen_played_; } | 89 size_t NumExitScreenSounds() const { return num_times_exit_screen_played_; } |
86 size_t NumEnterScreenSounds() { | 90 size_t NumEnterScreenSounds() const { return num_times_enter_screen_played_; } |
87 return num_times_enter_screen_played_; | 91 ui::AXGesture GetLastGesture() const { return last_gesture_; } |
88 } | |
89 | 92 |
90 void ResetCountersToZero() { | 93 void ResetCountersToZero() { |
91 num_times_adjust_sound_played_ = 0; | 94 num_times_adjust_sound_played_ = 0; |
92 num_times_passthrough_played_ = 0; | 95 num_times_passthrough_played_ = 0; |
93 num_times_exit_screen_played_ = 0; | 96 num_times_exit_screen_played_ = 0; |
94 num_times_enter_screen_played_ = 0; | 97 num_times_enter_screen_played_ = 0; |
95 } | 98 } |
96 | 99 |
97 private: | 100 private: |
98 std::vector<float> volume_changes_; | 101 std::vector<float> volume_changes_; |
99 size_t num_times_adjust_sound_played_ = 0; | 102 size_t num_times_adjust_sound_played_ = 0; |
100 size_t num_times_passthrough_played_ = 0; | 103 size_t num_times_passthrough_played_ = 0; |
101 size_t num_times_exit_screen_played_ = 0; | 104 size_t num_times_exit_screen_played_ = 0; |
102 size_t num_times_enter_screen_played_ = 0; | 105 size_t num_times_enter_screen_played_ = 0; |
| 106 ui::AXGesture last_gesture_ = ui::AX_GESTURE_NONE; |
103 }; | 107 }; |
104 | 108 |
105 } // namespace | 109 } // namespace |
106 | 110 |
107 class TouchExplorationControllerTestApi { | 111 class TouchExplorationControllerTestApi { |
108 public: | 112 public: |
109 TouchExplorationControllerTestApi( | 113 TouchExplorationControllerTestApi( |
110 TouchExplorationController* touch_exploration_controller) { | 114 TouchExplorationController* touch_exploration_controller) { |
111 touch_exploration_controller_.reset(touch_exploration_controller); | 115 touch_exploration_controller_.reset(touch_exploration_controller); |
112 } | 116 } |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \ | 456 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \ |
453 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2)) | 457 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2)) |
454 | 458 |
455 #define CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(e1, e2) \ | 459 #define CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(e1, e2) \ |
456 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreKeyAndEqual(e1, e2)) | 460 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreKeyAndEqual(e1, e2)) |
457 | 461 |
458 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit | 462 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit |
459 // events when running these tests as part of ui_base_unittests. We do get them | 463 // events when running these tests as part of ui_base_unittests. We do get them |
460 // when the tests are run as part of ash unit tests. | 464 // when the tests are run as part of ash unit tests. |
461 | 465 |
462 // If a swipe has been successfully completed, then six key events will be | |
463 // dispatched that correspond to shift+search+direction | |
464 void AssertDirectionalNavigationEvents(const ScopedVector<ui::Event>& events, | |
465 ui::KeyboardCode direction) { | |
466 ASSERT_EQ(6U, events.size()); | |
467 ui::KeyEvent shift_pressed( | |
468 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); | |
469 ui::KeyEvent search_pressed( | |
470 ui::ET_KEY_PRESSED, ui::VKEY_LWIN, ui::EF_SHIFT_DOWN); | |
471 ui::KeyEvent direction_pressed( | |
472 ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN); | |
473 ui::KeyEvent direction_released( | |
474 ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); | |
475 ui::KeyEvent search_released( | |
476 ui::ET_KEY_RELEASED, VKEY_LWIN, ui::EF_SHIFT_DOWN); | |
477 ui::KeyEvent shift_released( | |
478 ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); | |
479 CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&shift_pressed, events[0]); | |
480 CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&search_pressed, events[1]); | |
481 CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&direction_pressed, events[2]); | |
482 CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&direction_released, events[3]); | |
483 CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&search_released, events[4]); | |
484 CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&shift_released, events[5]); | |
485 } | |
486 | |
487 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) { | 466 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) { |
488 SwitchTouchExplorationMode(true); | 467 SwitchTouchExplorationMode(true); |
489 EXPECT_FALSE(IsInTouchToMouseMode()); | 468 EXPECT_FALSE(IsInTouchToMouseMode()); |
490 generator_->PressTouch(); | 469 generator_->PressTouch(); |
491 AdvanceSimulatedTimePastTapDelay(); | 470 AdvanceSimulatedTimePastTapDelay(); |
492 EXPECT_TRUE(IsInTouchToMouseMode()); | 471 EXPECT_TRUE(IsInTouchToMouseMode()); |
493 } | 472 } |
494 | 473 |
495 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) { | 474 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) { |
496 int slop = gesture_detector_config_.touch_slop; | 475 int slop = gesture_detector_config_.touch_slop; |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); | 1264 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); |
1286 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); | 1265 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); |
1287 EXPECT_TRUE(IsInTouchToMouseMode()); | 1266 EXPECT_TRUE(IsInTouchToMouseMode()); |
1288 EXPECT_FALSE(IsInGestureInProgressState()); | 1267 EXPECT_FALSE(IsInGestureInProgressState()); |
1289 } | 1268 } |
1290 | 1269 |
1291 // A swipe+direction gesture should trigger a Shift+Search+Direction | 1270 // A swipe+direction gesture should trigger a Shift+Search+Direction |
1292 // keyboard event. | 1271 // keyboard event. |
1293 TEST_F(TouchExplorationTest, GestureSwipe) { | 1272 TEST_F(TouchExplorationTest, GestureSwipe) { |
1294 SwitchTouchExplorationMode(true); | 1273 SwitchTouchExplorationMode(true); |
1295 std::vector<ui::KeyboardCode> directions; | 1274 |
1296 directions.push_back(ui::VKEY_RIGHT); | 1275 // Test all four swipe directions with 1 to 4 fingers. |
1297 directions.push_back(ui::VKEY_LEFT); | 1276 struct GestureInfo { |
1298 directions.push_back(ui::VKEY_UP); | 1277 int move_x; |
1299 directions.push_back(ui::VKEY_DOWN); | 1278 int move_y; |
| 1279 int num_fingers; |
| 1280 ui::AXGesture expected_gesture; |
| 1281 } gestures_to_test[] = { |
| 1282 {-1, 0, 1, ui::AX_GESTURE_SWIPE_LEFT_1}, |
| 1283 {0, -1, 1, ui::AX_GESTURE_SWIPE_UP_1}, |
| 1284 {1, 0, 1, ui::AX_GESTURE_SWIPE_RIGHT_1}, |
| 1285 {0, 1, 1, ui::AX_GESTURE_SWIPE_DOWN_1}, |
| 1286 {-1, 0, 2, ui::AX_GESTURE_SWIPE_LEFT_2}, |
| 1287 {0, -1, 2, ui::AX_GESTURE_SWIPE_UP_2}, |
| 1288 {1, 0, 2, ui::AX_GESTURE_SWIPE_RIGHT_2}, |
| 1289 {0, 1, 2, ui::AX_GESTURE_SWIPE_DOWN_2}, |
| 1290 {-1, 0, 3, ui::AX_GESTURE_SWIPE_LEFT_3}, |
| 1291 {0, -1, 3, ui::AX_GESTURE_SWIPE_UP_3}, |
| 1292 {1, 0, 3, ui::AX_GESTURE_SWIPE_RIGHT_3}, |
| 1293 {0, 1, 3, ui::AX_GESTURE_SWIPE_DOWN_3}, |
| 1294 {-1, 0, 4, ui::AX_GESTURE_SWIPE_LEFT_4}, |
| 1295 {0, -1, 4, ui::AX_GESTURE_SWIPE_UP_4}, |
| 1296 {1, 0, 4, ui::AX_GESTURE_SWIPE_RIGHT_4}, |
| 1297 {0, 1, 4, ui::AX_GESTURE_SWIPE_DOWN_4}, |
| 1298 }; |
1300 | 1299 |
1301 // This value was taken from gesture_recognizer_unittest.cc in a swipe | 1300 // This value was taken from gesture_recognizer_unittest.cc in a swipe |
1302 // detector test, since it seems to be about the right amount to get a swipe. | 1301 // detector test, since it seems to be about the right amount to get a swipe. |
1303 const int kSteps = 15; | 1302 const int kSteps = 15; |
1304 | 1303 |
1305 // There are gestures supported with up to four fingers. | 1304 for (size_t i = 0; i < arraysize(gestures_to_test); ++i) { |
1306 for (int num_fingers = 1; num_fingers <= 4; num_fingers++) { | 1305 const float distance = 2 * gesture_detector_config_.touch_slop + 1; |
| 1306 int move_x = gestures_to_test[i].move_x * distance; |
| 1307 int move_y = gestures_to_test[i].move_y * distance; |
| 1308 int num_fingers = gestures_to_test[i].num_fingers; |
| 1309 ui::AXGesture expected_gesture = gestures_to_test[i].expected_gesture; |
| 1310 |
1307 std::vector<gfx::Point> start_points; | 1311 std::vector<gfx::Point> start_points; |
1308 for (int j = 0; j < num_fingers; j++) { | 1312 for (int j = 0; j < num_fingers; j++) { |
1309 start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 200)); | 1313 start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 200)); |
1310 } | 1314 } |
1311 gfx::Point* start_points_array = &start_points[0]; | 1315 gfx::Point* start_points_array = &start_points[0]; |
1312 const float distance = gesture_detector_config_.touch_slop + 1; | |
1313 // Iterate through each swipe direction for this number of fingers. | |
1314 for (std::vector<ui::KeyboardCode>::const_iterator it = directions.begin(); | |
1315 it != directions.end(); | |
1316 ++it) { | |
1317 int move_x = 0; | |
1318 int move_y = 0; | |
1319 ui::KeyboardCode direction = *it; | |
1320 switch (direction) { | |
1321 case ui::VKEY_RIGHT: | |
1322 move_x = distance; | |
1323 break; | |
1324 case ui::VKEY_LEFT: | |
1325 move_x = 0 - distance; | |
1326 break; | |
1327 case ui::VKEY_UP: | |
1328 move_y = 0 - distance; | |
1329 break; | |
1330 case ui::VKEY_DOWN: | |
1331 move_y = distance; | |
1332 break; | |
1333 default: | |
1334 return; | |
1335 } | |
1336 | 1316 |
1337 // A swipe is made when a fling starts | 1317 // A swipe is made when a fling starts |
1338 float delta_time = | 1318 float delta_time = |
1339 distance / gesture_detector_config_.maximum_fling_velocity; | 1319 distance / gesture_detector_config_.maximum_fling_velocity; |
1340 // delta_time is in seconds, so we convert to ms. | 1320 // delta_time is in seconds, so we convert to ms. |
1341 int delta_time_ms = floor(delta_time * 1000); | 1321 int delta_time_ms = floor(delta_time * 1000); |
1342 generator_->GestureMultiFingerScroll(num_fingers, | 1322 generator_->GestureMultiFingerScroll(num_fingers, start_points_array, |
1343 start_points_array, | 1323 delta_time_ms, kSteps, move_x, move_y); |
1344 delta_time_ms, | 1324 EXPECT_EQ(expected_gesture, delegate_.GetLastGesture()); |
1345 kSteps, | 1325 EXPECT_TRUE(IsInNoFingersDownState()); |
1346 move_x * 2, | 1326 EXPECT_FALSE(IsInTouchToMouseMode()); |
1347 move_y * 2); | 1327 EXPECT_FALSE(IsInGestureInProgressState()); |
1348 | 1328 ClearCapturedEvents(); |
1349 // The swipe registered and sent the appropriate key events. | |
1350 const ScopedVector<ui::Event>& captured_events = GetCapturedEvents(); | |
1351 if (num_fingers == 1) | |
1352 AssertDirectionalNavigationEvents(captured_events, direction); | |
1353 else { | |
1354 // Most of the time this is 2 right now, but two of the two finger | |
1355 // swipes are mapped to chromevox commands which dispatch 6 key events, | |
1356 // and these will probably be remapped a lot as we're developing. | |
1357 ASSERT_GE(captured_events.size(), 2U); | |
1358 std::vector<ui::Event>::size_type i; | |
1359 for (i = 0; i != captured_events.size(); i++) { | |
1360 EXPECT_TRUE(captured_events[i]->IsKeyEvent()); | |
1361 } | |
1362 } | |
1363 EXPECT_TRUE(IsInNoFingersDownState()); | |
1364 EXPECT_FALSE(IsInTouchToMouseMode()); | |
1365 EXPECT_FALSE(IsInGestureInProgressState()); | |
1366 ClearCapturedEvents(); | |
1367 } | |
1368 } | 1329 } |
1369 } | 1330 } |
1370 | 1331 |
1371 // Since there are so many permutations, this test is fairly slow. Therefore, it | 1332 // Since there are so many permutations, this test is fairly slow. Therefore, it |
1372 // is disabled and will be turned on to check during development. | 1333 // is disabled and will be turned on to check during development. |
1373 | 1334 |
1374 TEST_F(TouchExplorationTest, DISABLED_AllFingerPermutations) { | 1335 TEST_F(TouchExplorationTest, DISABLED_AllFingerPermutations) { |
1375 SwitchTouchExplorationMode(true); | 1336 SwitchTouchExplorationMode(true); |
1376 SuppressVLOGs(true); | 1337 SuppressVLOGs(true); |
1377 // We will test all permutations of events from three different fingers | 1338 // We will test all permutations of events from three different fingers |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 generator_->PressTouch(); | 1890 generator_->PressTouch(); |
1930 generator_->MoveTouch(initial_press); | 1891 generator_->MoveTouch(initial_press); |
1931 generator_->MoveTouch(*point); | 1892 generator_->MoveTouch(*point); |
1932 generator_->ReleaseTouch(); | 1893 generator_->ReleaseTouch(); |
1933 ASSERT_EQ(1U, delegate_.NumExitScreenSounds()); | 1894 ASSERT_EQ(1U, delegate_.NumExitScreenSounds()); |
1934 delegate_.ResetCountersToZero(); | 1895 delegate_.ResetCountersToZero(); |
1935 } | 1896 } |
1936 } | 1897 } |
1937 | 1898 |
1938 } // namespace ui | 1899 } // namespace ui |
OLD | NEW |