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

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

Issue 410783002: Corner Passthrough for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@side-gestures
Patch Set: Rebase off Master Created 6 years, 4 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
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"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 if (n <= 0) 68 if (n <= 0)
69 return 0; 69 return 0;
70 if (n == 1) 70 if (n == 1)
71 return 1; 71 return 1;
72 return n * Factorial(n - 1); 72 return n * Factorial(n - 1);
73 } 73 }
74 74
75 class MockTouchExplorationControllerDelegate 75 class MockTouchExplorationControllerDelegate
76 : public ui::TouchExplorationControllerDelegate { 76 : public ui::TouchExplorationControllerDelegate {
77 public: 77 public:
78 virtual void PlayVolumeAdjustSound() OVERRIDE { 78 virtual void SetOutputLevel(int volume) OVERRIDE {
79 volume_changes_.push_back(volume);
80 }
81 virtual void PlayVolumeAdjustEarcon() OVERRIDE {
79 ++num_times_adjust_sound_played_; 82 ++num_times_adjust_sound_played_;
80 } 83 }
81 virtual void SetOutputLevel(int volume) OVERRIDE { 84 virtual void PlayPassthroughEarcon() OVERRIDE {
82 volume_changes_.push_back(volume); 85 ++num_times_passthrough_played_;
86 }
87 virtual void PlayExitScreenEarcon() OVERRIDE {
88 ++num_times_exit_screen_played_;
89 }
90 virtual void PlayEnterScreenEarcon() OVERRIDE {
91 ++num_times_enter_screen_played_;
83 } 92 }
84 93
85 const std::vector<float> VolumeChanges() { return volume_changes_; } 94 const std::vector<float> VolumeChanges() { return volume_changes_; }
86 const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; } 95 const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; }
96 const size_t NumPassthroughSounds() { return num_times_passthrough_played_; }
97 const size_t NumExitScreenSounds() { return num_times_exit_screen_played_; }
98 const size_t NumEnterScreenSounds() {
99 return num_times_enter_screen_played_;
100 }
101
102 void ResetCountersToZero() {
103 num_times_adjust_sound_played_ = 0;
104 num_times_passthrough_played_ = 0;
105 num_times_exit_screen_played_ = 0;
106 num_times_enter_screen_played_ = 0;
107 }
87 108
88 private: 109 private:
89 std::vector<float> volume_changes_; 110 std::vector<float> volume_changes_;
90 size_t num_times_adjust_sound_played_ = 0; 111 size_t num_times_adjust_sound_played_ = 0;
112 size_t num_times_passthrough_played_ = 0;
113 size_t num_times_exit_screen_played_ = 0;
114 size_t num_times_enter_screen_played_ = 0;
91 }; 115 };
92 116
93 } // namespace 117 } // namespace
94 118
95 class TouchExplorationControllerTestApi { 119 class TouchExplorationControllerTestApi {
96 public: 120 public:
97 TouchExplorationControllerTestApi( 121 TouchExplorationControllerTestApi(
98 TouchExplorationController* touch_exploration_controller) { 122 TouchExplorationController* touch_exploration_controller) {
99 touch_exploration_controller_.reset(touch_exploration_controller); 123 touch_exploration_controller_.reset(touch_exploration_controller);
100 } 124 }
101 125
102 void CallTapTimerNowForTesting() { 126 void CallTapTimerNowForTesting() {
103 DCHECK(touch_exploration_controller_->tap_timer_.IsRunning()); 127 DCHECK(touch_exploration_controller_->tap_timer_.IsRunning());
104 touch_exploration_controller_->tap_timer_.Stop(); 128 touch_exploration_controller_->tap_timer_.Stop();
105 touch_exploration_controller_->OnTapTimerFired(); 129 touch_exploration_controller_->OnTapTimerFired();
106 } 130 }
107 131
132 void CallLongPressTimerNowForTesting() {
133 DCHECK(touch_exploration_controller_->long_press_timer_.IsRunning());
134 touch_exploration_controller_->long_press_timer_.Stop();
135 touch_exploration_controller_->OnLongPressTimerFired();
136 }
137
108 void CallTapTimerNowIfRunningForTesting() { 138 void CallTapTimerNowIfRunningForTesting() {
109 if (touch_exploration_controller_->tap_timer_.IsRunning()) { 139 if (touch_exploration_controller_->tap_timer_.IsRunning()) {
110 touch_exploration_controller_->tap_timer_.Stop(); 140 touch_exploration_controller_->tap_timer_.Stop();
111 touch_exploration_controller_->OnTapTimerFired(); 141 touch_exploration_controller_->OnTapTimerFired();
112 } 142 }
113 } 143 }
114 144
115 bool IsInNoFingersDownStateForTesting() const { 145 bool IsInNoFingersDownStateForTesting() const {
116 return touch_exploration_controller_->state_ == 146 return touch_exploration_controller_->state_ ==
117 touch_exploration_controller_->NO_FINGERS_DOWN; 147 touch_exploration_controller_->NO_FINGERS_DOWN;
118 } 148 }
119 149
120 bool IsInGestureInProgressStateForTesting() const { 150 bool IsInGestureInProgressStateForTesting() const {
121 return touch_exploration_controller_->state_ == 151 return touch_exploration_controller_->state_ ==
122 touch_exploration_controller_->GESTURE_IN_PROGRESS; 152 touch_exploration_controller_->GESTURE_IN_PROGRESS;
123 } 153 }
124 154
125 bool IsInSlideGestureStateForTesting() const { 155 bool IsInSlideGestureStateForTesting() const {
126 return touch_exploration_controller_->state_ == 156 return touch_exploration_controller_->state_ ==
127 touch_exploration_controller_->SLIDE_GESTURE; 157 touch_exploration_controller_->SLIDE_GESTURE;
128 } 158 }
129 159
160 bool IsInCornerPassthroughStateForTesting() const {
161 return touch_exploration_controller_->state_ ==
162 touch_exploration_controller_->CORNER_PASSTHROUGH;
163 }
164
130 gfx::Rect BoundsOfRootWindowInDIPForTesting() const { 165 gfx::Rect BoundsOfRootWindowInDIPForTesting() const {
131 return touch_exploration_controller_->root_window_->GetBoundsInScreen(); 166 return touch_exploration_controller_->root_window_->GetBoundsInScreen();
132 } 167 }
133 168
134 // VLOGs should be suppressed in tests that generate a lot of logs, 169 // VLOGs should be suppressed in tests that generate a lot of logs,
135 // for example permutations of nine touch events. 170 // for example permutations of nine touch events.
136 void SuppressVLOGsForTesting(bool suppress) { 171 void SuppressVLOGsForTesting(bool suppress) {
137 touch_exploration_controller_->VLOG_on_ = !suppress; 172 touch_exploration_controller_->VLOG_on_ = !suppress;
138 } 173 }
139 174
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 void ClearCapturedEvents() { 261 void ClearCapturedEvents() {
227 event_capturer_.Reset(); 262 event_capturer_.Reset();
228 } 263 }
229 264
230 void AdvanceSimulatedTimePastTapDelay() { 265 void AdvanceSimulatedTimePastTapDelay() {
231 simulated_clock_->Advance(gesture_detector_config_.double_tap_timeout); 266 simulated_clock_->Advance(gesture_detector_config_.double_tap_timeout);
232 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1)); 267 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1));
233 touch_exploration_controller_->CallTapTimerNowForTesting(); 268 touch_exploration_controller_->CallTapTimerNowForTesting();
234 } 269 }
235 270
271 void AdvanceSimulatedTimePastLongPressDelay() {
272 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
273 touch_exploration_controller_->CallLongPressTimerNowForTesting();
274 }
275
236 void AdvanceSimulatedTimePastPotentialTapDelay() { 276 void AdvanceSimulatedTimePastPotentialTapDelay() {
237 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); 277 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
238 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); 278 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting();
239 } 279 }
240 280
241 void SuppressVLOGs(bool suppress) { 281 void SuppressVLOGs(bool suppress) {
242 touch_exploration_controller_->SuppressVLOGsForTesting(suppress); 282 touch_exploration_controller_->SuppressVLOGsForTesting(suppress);
243 } 283 }
244 284
245 void SetTickClock() { 285 void SetTickClock() {
(...skipping 13 matching lines...) Expand all
259 } 299 }
260 } 300 }
261 301
262 void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) { 302 void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) {
263 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now()); 303 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now());
264 generator_->Dispatch(&touch_press); 304 generator_->Dispatch(&touch_press);
265 AdvanceSimulatedTimePastTapDelay(); 305 AdvanceSimulatedTimePastTapDelay();
266 EXPECT_TRUE(IsInTouchToMouseMode()); 306 EXPECT_TRUE(IsInTouchToMouseMode());
267 } 307 }
268 308
309 // Checks that Corner Passthrough is working. Assumes that corner is the
310 // bottom left corner or the bottom right corner.
311 void AssertCornerPassthroughWorking(gfx::Point corner) {
312 ASSERT_EQ(0U, delegate_.NumPassthroughSounds());
313
314 ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, corner, 0, Now());
315 generator_->Dispatch(&first_press);
316
317 AdvanceSimulatedTimePastLongPressDelay();
318 EXPECT_FALSE(IsInGestureInProgressState());
319 EXPECT_FALSE(IsInSlideGestureState());
320 EXPECT_FALSE(IsInTouchToMouseMode());
321 EXPECT_TRUE(IsInCornerPassthroughState());
322
323 gfx::Rect window = BoundsOfRootWindowInDIP();
324 // The following events should be passed through.
325 gfx::Point passthrough(window.right() / 2, window.bottom() / 2);
326 ui::TouchEvent passthrough_press(
327 ui::ET_TOUCH_PRESSED, passthrough, 1, Now());
328 ASSERT_EQ(1U, delegate_.NumPassthroughSounds());
329 generator_->Dispatch(&passthrough_press);
330 generator_->ReleaseTouchId(1);
331 generator_->PressTouchId(1);
332 EXPECT_FALSE(IsInGestureInProgressState());
333 EXPECT_FALSE(IsInSlideGestureState());
334 EXPECT_TRUE(IsInCornerPassthroughState());
335
336 std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
337 ASSERT_EQ(3U, captured_events.size());
338 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
339 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
340 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type());
341 generator_->ReleaseTouchId(1);
342 ClearCapturedEvents();
343
344 generator_->ReleaseTouchId(0);
345 captured_events = GetCapturedLocatedEvents();
346 ASSERT_EQ(0U, captured_events.size());
347 EXPECT_FALSE(IsInTouchToMouseMode());
348 EXPECT_FALSE(IsInCornerPassthroughState());
349 ClearCapturedEvents();
350 }
351
269 bool IsInTouchToMouseMode() { 352 bool IsInTouchToMouseMode() {
270 aura::client::CursorClient* cursor_client = 353 aura::client::CursorClient* cursor_client =
271 aura::client::GetCursorClient(root_window()); 354 aura::client::GetCursorClient(root_window());
272 return cursor_client && 355 return cursor_client && cursor_client->IsMouseEventsEnabled() &&
273 cursor_client->IsMouseEventsEnabled() &&
274 !cursor_client->IsCursorVisible(); 356 !cursor_client->IsCursorVisible();
275 } 357 }
276 358
277 bool IsInNoFingersDownState() { 359 bool IsInNoFingersDownState() {
278 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); 360 return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
279 } 361 }
280 362
281 bool IsInGestureInProgressState() { 363 bool IsInGestureInProgressState() {
282 return touch_exploration_controller_ 364 return touch_exploration_controller_
283 ->IsInGestureInProgressStateForTesting(); 365 ->IsInGestureInProgressStateForTesting();
284 } 366 }
285 367
286 bool IsInSlideGestureState() { 368 bool IsInSlideGestureState() {
287 return touch_exploration_controller_->IsInSlideGestureStateForTesting(); 369 return touch_exploration_controller_->IsInSlideGestureStateForTesting();
288 } 370 }
289 371
372 bool IsInCornerPassthroughState() {
373 return touch_exploration_controller_
374 ->IsInCornerPassthroughStateForTesting();
375 }
376
290 gfx::Rect BoundsOfRootWindowInDIP() { 377 gfx::Rect BoundsOfRootWindowInDIP() {
291 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); 378 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting();
292 } 379 }
293 380
294 float GetMaxDistanceFromEdge() const{ 381 float GetMaxDistanceFromEdge() const {
295 return touch_exploration_controller_->GetMaxDistanceFromEdge(); 382 return touch_exploration_controller_->GetMaxDistanceFromEdge();
296 } 383 }
297 384
298 float GetSlopDistanceFromEdge() const{ 385 float GetSlopDistanceFromEdge() const{
299 return touch_exploration_controller_->GetSlopDistanceFromEdge(); 386 return touch_exploration_controller_->GetSlopDistanceFromEdge();
300 } 387 }
301 388
302 base::TimeDelta Now() { 389 base::TimeDelta Now() {
303 // This is the same as what EventTimeForNow() does, but here we do it 390 // This is the same as what EventTimeForNow() does, but here we do it
304 // with our simulated clock. 391 // with our simulated clock.
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 EXPECT_FALSE(IsInGestureInProgressState()); 1607 EXPECT_FALSE(IsInGestureInProgressState());
1521 EXPECT_FALSE(IsInSlideGestureState()); 1608 EXPECT_FALSE(IsInSlideGestureState());
1522 EXPECT_FALSE(IsInTouchToMouseMode()); 1609 EXPECT_FALSE(IsInTouchToMouseMode());
1523 1610
1524 AdvanceSimulatedTimePastTapDelay(); 1611 AdvanceSimulatedTimePastTapDelay();
1525 EXPECT_FALSE(IsInGestureInProgressState()); 1612 EXPECT_FALSE(IsInGestureInProgressState());
1526 EXPECT_FALSE(IsInSlideGestureState()); 1613 EXPECT_FALSE(IsInSlideGestureState());
1527 EXPECT_TRUE(IsInTouchToMouseMode()); 1614 EXPECT_TRUE(IsInTouchToMouseMode());
1528 } 1615 }
1529 1616
1617 // Corner passthrough should turn on if the user first holds down on either the
1618 // right or left corner past a delay and then places a finger anywhere else on
1619 // the screen.
1620 TEST_F(TouchExplorationTest, ActivateLeftCornerPassthrough) {
1621 SwitchTouchExplorationMode(true);
1622
1623 gfx::Rect window = BoundsOfRootWindowInDIP();
1624 gfx::Point left_corner(10, window.bottom() - GetMaxDistanceFromEdge() / 2);
1625 AssertCornerPassthroughWorking(left_corner);
1626 }
1627
1628 TEST_F(TouchExplorationTest, ActivateRightCornerPassthrough) {
1629 SwitchTouchExplorationMode(true);
1630
1631 gfx::Rect window = BoundsOfRootWindowInDIP();
1632 gfx::Point right_corner(window.right() - GetMaxDistanceFromEdge() / 2,
1633 window.bottom() - GetMaxDistanceFromEdge() / 2);
1634 AssertCornerPassthroughWorking(right_corner);
1635 }
1636
1637 // Earcons should play if the user slides off the screen or enters the screen
1638 // from the edge.
1639 TEST_F(TouchExplorationTest, EnterEarconPlays) {
1640 SwitchTouchExplorationMode(true);
1641
1642 gfx::Rect window = BoundsOfRootWindowInDIP();
1643
1644 gfx::Point upper_left_corner(0, 0);
1645 gfx::Point upper_right_corner(window.right(), 0);
1646 gfx::Point lower_left_corner(0, window.bottom());
1647 gfx::Point lower_right_corner(window.right(), window.bottom());
1648 gfx::Point left_edge(0, 30);
1649 gfx::Point right_edge(window.right(), 30);
1650 gfx::Point top_edge(30, 0);
1651 gfx::Point bottom_edge(30, window.bottom());
1652
1653 std::vector<gfx::Point> locations;
1654 locations.push_back(upper_left_corner);
1655 locations.push_back(upper_right_corner);
1656 locations.push_back(lower_left_corner);
1657 locations.push_back(lower_right_corner);
1658 locations.push_back(left_edge);
1659 locations.push_back(right_edge);
1660 locations.push_back(top_edge);
1661 locations.push_back(bottom_edge);
1662
1663 for (std::vector<gfx::Point>::const_iterator point = locations.begin();
1664 point != locations.end();
1665 ++point) {
1666 ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, *point, 1, Now());
1667
1668 generator_->Dispatch(&touch_event);
1669 ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1670 generator_->ReleaseTouchId(1);
1671 delegate_.ResetCountersToZero();
1672 }
1673 }
1674
1675 TEST_F(TouchExplorationTest, ExitEarconPlays) {
1676 SwitchTouchExplorationMode(true);
1677
1678 // On the device, it cannot actually tell if the finger has left the screen or
1679 // not. If the finger has left the screen, it reads it as a release that
1680 // occurred very close to the edge of the screen even if the finger is still
1681 // technically touching the moniter. To simulate this, a release that occurs
1682 // close to the edge is dispatched.
1683 gfx::Point initial_press(100, 200);
1684 gfx::Rect window = BoundsOfRootWindowInDIP();
1685
1686 gfx::Point upper_left_corner(0, 0);
1687 gfx::Point upper_right_corner(window.right(), 0);
1688 gfx::Point lower_left_corner(0, window.bottom());
1689 gfx::Point lower_right_corner(window.right(), window.bottom());
1690 gfx::Point left_edge(0, 30);
1691 gfx::Point right_edge(window.right(), 30);
1692 gfx::Point top_edge(30, 0);
1693 gfx::Point bottom_edge(30, window.bottom());
1694
1695 std::vector<gfx::Point> locations;
1696 locations.push_back(upper_left_corner);
1697 locations.push_back(upper_right_corner);
1698 locations.push_back(lower_left_corner);
1699 locations.push_back(lower_right_corner);
1700 locations.push_back(left_edge);
1701 locations.push_back(right_edge);
1702 locations.push_back(top_edge);
1703 locations.push_back(bottom_edge);
1704
1705 for (std::vector<gfx::Point>::const_iterator point = locations.begin();
1706 point != locations.end();
1707 ++point) {
1708 generator_->PressTouch();
1709 generator_->MoveTouch(initial_press);
1710 generator_->MoveTouch(*point);
1711 generator_->ReleaseTouch();
1712 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1713 delegate_.ResetCountersToZero();
1714 }
1715 }
1716
1530 } // namespace ui 1717 } // namespace ui
OLDNEW
« ui/chromeos/touch_exploration_controller.cc ('K') | « ui/chromeos/touch_exploration_controller.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698