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

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: Added Exit and Enter Screen tests 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
« 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"
(...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 void SetEventHandlerForTesting( 145 void SetEventHandlerForTesting(
116 ui::EventHandler* event_handler_for_testing) { 146 ui::EventHandler* event_handler_for_testing) {
117 touch_exploration_controller_->event_handler_for_testing_ = 147 touch_exploration_controller_->event_handler_for_testing_ =
118 event_handler_for_testing; 148 event_handler_for_testing;
119 } 149 }
120 150
121 bool IsInNoFingersDownStateForTesting() const { 151 bool IsInNoFingersDownStateForTesting() const {
122 return touch_exploration_controller_->state_ == 152 return touch_exploration_controller_->state_ ==
123 touch_exploration_controller_->NO_FINGERS_DOWN; 153 touch_exploration_controller_->NO_FINGERS_DOWN;
124 } 154 }
125 155
126 bool IsInGestureInProgressStateForTesting() const { 156 bool IsInGestureInProgressStateForTesting() const {
127 return touch_exploration_controller_->state_ == 157 return touch_exploration_controller_->state_ ==
128 touch_exploration_controller_->GESTURE_IN_PROGRESS; 158 touch_exploration_controller_->GESTURE_IN_PROGRESS;
129 } 159 }
130 160
131 bool IsInSlideGestureStateForTesting() const { 161 bool IsInSlideGestureStateForTesting() const {
132 return touch_exploration_controller_->state_ == 162 return touch_exploration_controller_->state_ ==
133 touch_exploration_controller_->SLIDE_GESTURE; 163 touch_exploration_controller_->SLIDE_GESTURE;
134 } 164 }
135 165
166 bool IsInCornerPassthroughStateForTesting() const {
167 return touch_exploration_controller_->state_ ==
168 touch_exploration_controller_->CORNER_PASSTHROUGH;
169 }
170
136 gfx::Rect BoundsOfRootWindowInDIPForTesting() const { 171 gfx::Rect BoundsOfRootWindowInDIPForTesting() const {
137 return touch_exploration_controller_->root_window_->GetBoundsInScreen(); 172 return touch_exploration_controller_->root_window_->GetBoundsInScreen();
138 } 173 }
139 174
140 // VLOGs should be suppressed in tests that generate a lot of logs, 175 // VLOGs should be suppressed in tests that generate a lot of logs,
141 // for example permutations of nine touch events. 176 // for example permutations of nine touch events.
142 void SuppressVLOGsForTesting(bool suppress) { 177 void SuppressVLOGsForTesting(bool suppress) {
143 touch_exploration_controller_->VLOG_on_ = !suppress; 178 touch_exploration_controller_->VLOG_on_ = !suppress;
144 } 179 }
145 180
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 262
228 void ClearCapturedEvents() { 263 void ClearCapturedEvents() {
229 event_capturer_.Reset(); 264 event_capturer_.Reset();
230 } 265 }
231 266
232 void AdvanceSimulatedTimePastTapDelay() { 267 void AdvanceSimulatedTimePastTapDelay() {
233 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); 268 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
234 touch_exploration_controller_->CallTapTimerNowForTesting(); 269 touch_exploration_controller_->CallTapTimerNowForTesting();
235 } 270 }
236 271
272 void AdvanceSimulatedTimePastLongPressDelay() {
273 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
274 touch_exploration_controller_->CallLongPressTimerNowForTesting();
275 }
276
237 void AdvanceSimulatedTimePastPotentialTapDelay() { 277 void AdvanceSimulatedTimePastPotentialTapDelay() {
238 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); 278 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
239 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); 279 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting();
240 } 280 }
241 281
242 void SuppressVLOGs(bool suppress) { 282 void SuppressVLOGs(bool suppress) {
243 touch_exploration_controller_->SuppressVLOGsForTesting(suppress); 283 touch_exploration_controller_->SuppressVLOGsForTesting(suppress);
244 } 284 }
245 285
246 void SwitchTouchExplorationMode(bool on) { 286 void SwitchTouchExplorationMode(bool on) {
(...skipping 21 matching lines...) Expand all
268 gfx::Point second_touch_location) { 308 gfx::Point second_touch_location) {
269 SwitchTouchExplorationMode(true); 309 SwitchTouchExplorationMode(true);
270 ui::TouchEvent first_touch_press( 310 ui::TouchEvent first_touch_press(
271 ui::ET_TOUCH_PRESSED, first_touch_location, 0, Now()); 311 ui::ET_TOUCH_PRESSED, first_touch_location, 0, Now());
272 generator_->Dispatch(&first_touch_press); 312 generator_->Dispatch(&first_touch_press);
273 ui::TouchEvent second_touch_press( 313 ui::TouchEvent second_touch_press(
274 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); 314 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
275 generator_->Dispatch(&second_touch_press); 315 generator_->Dispatch(&second_touch_press);
276 } 316 }
277 317
318 // Checks that Corner Passthrough is working. Assumes that corner is the
319 // bottom left corner or the bottom right corner.
320 void AssertCornerPassthroughWorking(gfx::Point corner) {
321 ASSERT_EQ(0U, delegate_.NumPassthroughSounds());
322
323 ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, corner, 0, Now());
324 generator_->Dispatch(&first_press);
325
326 AdvanceSimulatedTimePastLongPressDelay();
327 EXPECT_FALSE(IsInGestureInProgressState());
328 EXPECT_FALSE(IsInSlideGestureState());
329 EXPECT_FALSE(IsInTouchToMouseMode());
330 EXPECT_TRUE(IsInCornerPassthroughState());
331
332 gfx::Rect window = BoundsOfRootWindowInDIP();
333 // The following events should be passed through.
334 gfx::Point passthrough(window.right() / 2, window.bottom() / 2);
335 ui::TouchEvent passthrough_press(
336 ui::ET_TOUCH_PRESSED, passthrough, 1, Now());
337 ASSERT_EQ(1U, delegate_.NumPassthroughSounds());
338 generator_->Dispatch(&passthrough_press);
339 generator_->ReleaseTouchId(1);
340 generator_->PressTouchId(1);
341 EXPECT_FALSE(IsInGestureInProgressState());
342 EXPECT_FALSE(IsInSlideGestureState());
343 EXPECT_TRUE(IsInCornerPassthroughState());
344
345 std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
346 ASSERT_EQ(3U, captured_events.size());
347 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
348 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
349 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type());
350 generator_->ReleaseTouchId(1);
351 ClearCapturedEvents();
352
353 generator_->ReleaseTouchId(0);
354 captured_events = GetCapturedLocatedEvents();
355 ASSERT_EQ(0U, captured_events.size());
356 EXPECT_FALSE(IsInTouchToMouseMode());
357 EXPECT_FALSE(IsInCornerPassthroughState());
358 ClearCapturedEvents();
359 }
360
278 bool IsInTouchToMouseMode() { 361 bool IsInTouchToMouseMode() {
279 aura::client::CursorClient* cursor_client = 362 aura::client::CursorClient* cursor_client =
280 aura::client::GetCursorClient(root_window()); 363 aura::client::GetCursorClient(root_window());
281 return cursor_client && 364 return cursor_client && cursor_client->IsMouseEventsEnabled() &&
282 cursor_client->IsMouseEventsEnabled() &&
283 !cursor_client->IsCursorVisible(); 365 !cursor_client->IsCursorVisible();
284 } 366 }
285 367
286 bool IsInNoFingersDownState() { 368 bool IsInNoFingersDownState() {
287 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); 369 return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
288 } 370 }
289 371
290 bool IsInGestureInProgressState() { 372 bool IsInGestureInProgressState() {
291 return touch_exploration_controller_ 373 return touch_exploration_controller_
292 ->IsInGestureInProgressStateForTesting(); 374 ->IsInGestureInProgressStateForTesting();
293 } 375 }
294 376
295 bool IsInSlideGestureState() { 377 bool IsInSlideGestureState() {
296 return touch_exploration_controller_->IsInSlideGestureStateForTesting(); 378 return touch_exploration_controller_->IsInSlideGestureStateForTesting();
297 } 379 }
298 380
381 bool IsInCornerPassthroughState() {
382 return touch_exploration_controller_
383 ->IsInCornerPassthroughStateForTesting();
384 }
385
299 gfx::Rect BoundsOfRootWindowInDIP() { 386 gfx::Rect BoundsOfRootWindowInDIP() {
300 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); 387 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting();
301 } 388 }
302 389
303 float GetMaxDistanceFromEdge() const{ 390 float GetMaxDistanceFromEdge() const {
304 return touch_exploration_controller_->GetMaxDistanceFromEdge(); 391 return touch_exploration_controller_->GetMaxDistanceFromEdge();
305 } 392 }
306 393
307 float GetSlopDistanceFromEdge() const{ 394 float GetSlopDistanceFromEdge() const{
308 return touch_exploration_controller_->GetSlopDistanceFromEdge(); 395 return touch_exploration_controller_->GetSlopDistanceFromEdge();
309 } 396 }
310 397
311 base::TimeDelta Now() { 398 base::TimeDelta Now() {
312 // This is the same as what EventTimeForNow() does, but here we do it 399 // This is the same as what EventTimeForNow() does, but here we do it
313 // with our simulated clock. 400 // with our simulated clock.
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 EXPECT_FALSE(IsInGestureInProgressState()); 1720 EXPECT_FALSE(IsInGestureInProgressState());
1634 EXPECT_FALSE(IsInSlideGestureState()); 1721 EXPECT_FALSE(IsInSlideGestureState());
1635 EXPECT_FALSE(IsInTouchToMouseMode()); 1722 EXPECT_FALSE(IsInTouchToMouseMode());
1636 1723
1637 AdvanceSimulatedTimePastTapDelay(); 1724 AdvanceSimulatedTimePastTapDelay();
1638 EXPECT_FALSE(IsInGestureInProgressState()); 1725 EXPECT_FALSE(IsInGestureInProgressState());
1639 EXPECT_FALSE(IsInSlideGestureState()); 1726 EXPECT_FALSE(IsInSlideGestureState());
1640 EXPECT_TRUE(IsInTouchToMouseMode()); 1727 EXPECT_TRUE(IsInTouchToMouseMode());
1641 } 1728 }
1642 1729
1730 // Corner passthrough should turn on if the user first holds down on either the
1731 // right or left corner past a delay and then places a finger anywhere else on
1732 // the screen.
1733 TEST_F(TouchExplorationTest, ActivateLeftCornerPassthrough) {
1734 SwitchTouchExplorationMode(true);
1735
1736 gfx::Rect window = BoundsOfRootWindowInDIP();
1737 gfx::Point left_corner(10, window.bottom() - GetMaxDistanceFromEdge() / 2);
1738 AssertCornerPassthroughWorking(left_corner);
1739 }
1740
1741 TEST_F(TouchExplorationTest, ActivateRightCornerPassthrough) {
1742 SwitchTouchExplorationMode(true);
1743
1744 gfx::Rect window = BoundsOfRootWindowInDIP();
1745 gfx::Point right_corner(window.right() - GetMaxDistanceFromEdge() / 2,
1746 window.bottom() - GetMaxDistanceFromEdge() / 2);
1747 AssertCornerPassthroughWorking(right_corner);
1748 }
1749
1750 // Earcons should play if the user slides off the screen or enters the screen
1751 // from the edge.
1752 TEST_F(TouchExplorationTest, EnterEarconPlays) {
1753 SwitchTouchExplorationMode(true);
1754
1755 gfx::Rect window = BoundsOfRootWindowInDIP();
1756 ui::TouchEvent upper_left_corner(
aboxhall 2014/07/28 22:41:44 Suggestion (similarly for ExitEarconPlays test): p
1757 ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 1, Now());
1758 ui::TouchEvent upper_right_corner(
1759 ui::ET_TOUCH_PRESSED, gfx::Point(window.right(), 0), 1, Now());
1760 ui::TouchEvent lower_left_corner(
1761 ui::ET_TOUCH_PRESSED, gfx::Point(0, window.bottom()), 1, Now());
1762 ui::TouchEvent lower_right_corner(ui::ET_TOUCH_PRESSED,
1763 gfx::Point(window.right(), window.bottom()),
1764 1,
1765 Now());
1766
1767 generator_->Dispatch(&upper_left_corner);
1768 ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1769 generator_->ReleaseTouchId(1);
1770 delegate_.ResetCountersToZero();
1771
1772 generator_->Dispatch(&upper_right_corner);
1773 ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1774 generator_->ReleaseTouchId(1);
1775 delegate_.ResetCountersToZero();
1776
1777 generator_->Dispatch(&lower_left_corner);
1778 ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1779 generator_->ReleaseTouchId(1);
1780 delegate_.ResetCountersToZero();
1781
1782 generator_->Dispatch(&lower_right_corner);
1783 ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1784 generator_->ReleaseTouchId(1);
1785 delegate_.ResetCountersToZero();
1786 }
1787
1788 TEST_F(TouchExplorationTest, ExitEarconPlays) {
1789 SwitchTouchExplorationMode(true);
1790
1791 // On the device, it cannot actually tell if the finger has left the screen or
1792 // not. If the finger has left the screen, it reads it as a release that
1793 // occurred very close to the edge of the screen even if the finger is still
1794 // technically touching the moniter. To simulate this, a release that occurs
1795 // close to the edge is dispatched.
1796 gfx::Point initial_press(100, 200);
1797 gfx::Rect window = BoundsOfRootWindowInDIP();
1798 gfx::Point upper_left_corner(0, 0);
1799 gfx::Point upper_right_corner(window.right(), 0);
1800 gfx::Point lower_left_corner(0, window.bottom());
1801 gfx::Point lower_right_corner(window.right(), window.bottom());
1802
1803 generator_->PressTouch();
1804 generator_->MoveTouch(initial_press);
1805 generator_->MoveTouch(upper_left_corner);
1806 generator_->ReleaseTouch();
1807 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1808 delegate_.ResetCountersToZero();
1809
1810 generator_->PressTouch();
1811 generator_->MoveTouch(initial_press);
1812 generator_->MoveTouch(upper_left_corner);
1813 generator_->ReleaseTouch();
1814 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1815 delegate_.ResetCountersToZero();
1816
1817 generator_->PressTouch();
1818 generator_->MoveTouch(initial_press);
1819 generator_->MoveTouch(upper_right_corner);
1820 generator_->ReleaseTouch();
1821 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1822 delegate_.ResetCountersToZero();
1823
1824 generator_->PressTouch();
1825 generator_->MoveTouch(initial_press);
1826 generator_->MoveTouch(lower_left_corner);
1827 generator_->ReleaseTouch();
1828 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1829 delegate_.ResetCountersToZero();
1830
1831 generator_->PressTouch();
1832 generator_->MoveTouch(initial_press);
1833 generator_->MoveTouch(lower_right_corner);
1834 generator_->ReleaseTouch();
1835 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1836 delegate_.ResetCountersToZero();
1837 }
1838
1643 } // namespace ui 1839 } // 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