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

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: Removed extra comment 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 {
79 ++num_times_adjust_sound_played_;
80 }
81 virtual void SetOutputLevel(int volume) OVERRIDE { 78 virtual void SetOutputLevel(int volume) OVERRIDE {
82 volume_changes_.push_back(volume); 79 volume_changes_.push_back(volume);
83 } 80 }
84 virtual void SilenceSpokenFeedback() OVERRIDE { 81 virtual void SilenceSpokenFeedback() OVERRIDE {
85 } 82 }
83 virtual void PlayVolumeAdjustEarcon() OVERRIDE {
84 ++num_times_adjust_sound_played_;
85 }
86 virtual void PlayPassthroughEarcon() OVERRIDE {
87 ++num_times_passthrough_played_;
88 }
89 virtual void PlayExitScreenEarcon() OVERRIDE {
90 ++num_times_exit_screen_played_;
91 }
92 virtual void PlayEnterScreenEarcon() OVERRIDE {
93 ++num_times_enter_screen_played_;
94 }
86 95
87 const std::vector<float> VolumeChanges() { return volume_changes_; } 96 const std::vector<float> VolumeChanges() { return volume_changes_; }
88 const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; } 97 const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; }
98 const size_t NumPassthroughSounds() { return num_times_passthrough_played_; }
99 const size_t NumExitScreenSounds() { return num_times_exit_screen_played_; }
100 const size_t NumEnterScreenSounds() {
101 return num_times_enter_screen_played_;
102 }
103
104 void ResetCountersToZero() {
105 num_times_adjust_sound_played_ = 0;
106 num_times_passthrough_played_ = 0;
107 num_times_exit_screen_played_ = 0;
108 num_times_enter_screen_played_ = 0;
109 }
89 110
90 private: 111 private:
91 std::vector<float> volume_changes_; 112 std::vector<float> volume_changes_;
92 size_t num_times_adjust_sound_played_ = 0; 113 size_t num_times_adjust_sound_played_ = 0;
114 size_t num_times_passthrough_played_ = 0;
115 size_t num_times_exit_screen_played_ = 0;
116 size_t num_times_enter_screen_played_ = 0;
93 }; 117 };
94 118
95 } // namespace 119 } // namespace
96 120
97 class TouchExplorationControllerTestApi { 121 class TouchExplorationControllerTestApi {
98 public: 122 public:
99 TouchExplorationControllerTestApi( 123 TouchExplorationControllerTestApi(
100 TouchExplorationController* touch_exploration_controller) { 124 TouchExplorationController* touch_exploration_controller) {
101 touch_exploration_controller_.reset(touch_exploration_controller); 125 touch_exploration_controller_.reset(touch_exploration_controller);
102 } 126 }
103 127
104 void CallTapTimerNowForTesting() { 128 void CallTapTimerNowForTesting() {
105 DCHECK(touch_exploration_controller_->tap_timer_.IsRunning()); 129 DCHECK(touch_exploration_controller_->tap_timer_.IsRunning());
106 touch_exploration_controller_->tap_timer_.Stop(); 130 touch_exploration_controller_->tap_timer_.Stop();
107 touch_exploration_controller_->OnTapTimerFired(); 131 touch_exploration_controller_->OnTapTimerFired();
108 } 132 }
109 133
134 void CallPassthroughTimerNowForTesting() {
135 DCHECK(touch_exploration_controller_->passthrough_timer_.IsRunning());
136 touch_exploration_controller_->passthrough_timer_.Stop();
137 touch_exploration_controller_->OnPassthroughTimerFired();
138 }
139
110 void CallTapTimerNowIfRunningForTesting() { 140 void CallTapTimerNowIfRunningForTesting() {
111 if (touch_exploration_controller_->tap_timer_.IsRunning()) { 141 if (touch_exploration_controller_->tap_timer_.IsRunning()) {
112 touch_exploration_controller_->tap_timer_.Stop(); 142 touch_exploration_controller_->tap_timer_.Stop();
113 touch_exploration_controller_->OnTapTimerFired(); 143 touch_exploration_controller_->OnTapTimerFired();
114 } 144 }
115 } 145 }
116 146
117 bool IsInNoFingersDownStateForTesting() const { 147 bool IsInNoFingersDownStateForTesting() const {
118 return touch_exploration_controller_->state_ == 148 return touch_exploration_controller_->state_ ==
119 touch_exploration_controller_->NO_FINGERS_DOWN; 149 touch_exploration_controller_->NO_FINGERS_DOWN;
120 } 150 }
121 151
122 bool IsInGestureInProgressStateForTesting() const { 152 bool IsInGestureInProgressStateForTesting() const {
123 return touch_exploration_controller_->state_ == 153 return touch_exploration_controller_->state_ ==
124 touch_exploration_controller_->GESTURE_IN_PROGRESS; 154 touch_exploration_controller_->GESTURE_IN_PROGRESS;
125 } 155 }
126 156
127 bool IsInSlideGestureStateForTesting() const { 157 bool IsInSlideGestureStateForTesting() const {
128 return touch_exploration_controller_->state_ == 158 return touch_exploration_controller_->state_ ==
129 touch_exploration_controller_->SLIDE_GESTURE; 159 touch_exploration_controller_->SLIDE_GESTURE;
130 } 160 }
131 161
132 bool IsInTwoFingerTapStateForTesting() const { 162 bool IsInTwoFingerTapStateForTesting() const {
133 return touch_exploration_controller_->state_ == 163 return touch_exploration_controller_->state_ ==
134 touch_exploration_controller_->TWO_FINGER_TAP; 164 touch_exploration_controller_->TWO_FINGER_TAP;
135 } 165 }
166 bool IsInCornerPassthroughStateForTesting() const {
167 return touch_exploration_controller_->state_ ==
168 touch_exploration_controller_->CORNER_PASSTHROUGH;
169 }
136 170
137 gfx::Rect BoundsOfRootWindowInDIPForTesting() const { 171 gfx::Rect BoundsOfRootWindowInDIPForTesting() const {
138 return touch_exploration_controller_->root_window_->GetBoundsInScreen(); 172 return touch_exploration_controller_->root_window_->GetBoundsInScreen();
139 } 173 }
140 174
141 // 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,
142 // for example permutations of nine touch events. 176 // for example permutations of nine touch events.
143 void SuppressVLOGsForTesting(bool suppress) { 177 void SuppressVLOGsForTesting(bool suppress) {
144 touch_exploration_controller_->VLOG_on_ = !suppress; 178 touch_exploration_controller_->VLOG_on_ = !suppress;
145 } 179 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 void ClearCapturedEvents() { 267 void ClearCapturedEvents() {
234 event_capturer_.Reset(); 268 event_capturer_.Reset();
235 } 269 }
236 270
237 void AdvanceSimulatedTimePastTapDelay() { 271 void AdvanceSimulatedTimePastTapDelay() {
238 simulated_clock_->Advance(gesture_detector_config_.double_tap_timeout); 272 simulated_clock_->Advance(gesture_detector_config_.double_tap_timeout);
239 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1)); 273 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1));
240 touch_exploration_controller_->CallTapTimerNowForTesting(); 274 touch_exploration_controller_->CallTapTimerNowForTesting();
241 } 275 }
242 276
277 void AdvanceSimulatedTimePastPassthroughDelay() {
278 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
279 touch_exploration_controller_->CallPassthroughTimerNowForTesting();
280 }
281
243 void AdvanceSimulatedTimePastPotentialTapDelay() { 282 void AdvanceSimulatedTimePastPotentialTapDelay() {
244 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); 283 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
245 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); 284 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting();
246 } 285 }
247 286
248 void SuppressVLOGs(bool suppress) { 287 void SuppressVLOGs(bool suppress) {
249 touch_exploration_controller_->SuppressVLOGsForTesting(suppress); 288 touch_exploration_controller_->SuppressVLOGsForTesting(suppress);
250 } 289 }
251 290
252 void SetTickClock() { 291 void SetTickClock() {
(...skipping 13 matching lines...) Expand all
266 } 305 }
267 } 306 }
268 307
269 void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) { 308 void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) {
270 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now()); 309 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now());
271 generator_->Dispatch(&touch_press); 310 generator_->Dispatch(&touch_press);
272 AdvanceSimulatedTimePastTapDelay(); 311 AdvanceSimulatedTimePastTapDelay();
273 EXPECT_TRUE(IsInTouchToMouseMode()); 312 EXPECT_TRUE(IsInTouchToMouseMode());
274 } 313 }
275 314
315 // Checks that Corner Passthrough is working. Assumes that corner is the
316 // bottom left corner or the bottom right corner.
317 void AssertCornerPassthroughWorking(gfx::Point corner) {
318 ASSERT_EQ(0U, delegate_.NumPassthroughSounds());
319
320 ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, corner, 0, Now());
321 generator_->Dispatch(&first_press);
322
323 AdvanceSimulatedTimePastPassthroughDelay();
324 EXPECT_FALSE(IsInGestureInProgressState());
325 EXPECT_FALSE(IsInSlideGestureState());
326 EXPECT_FALSE(IsInTouchToMouseMode());
327 EXPECT_TRUE(IsInCornerPassthroughState());
328
329 gfx::Rect window = BoundsOfRootWindowInDIP();
330 // The following events should be passed through.
331 gfx::Point passthrough(window.right() / 2, window.bottom() / 2);
332 ui::TouchEvent passthrough_press(
333 ui::ET_TOUCH_PRESSED, passthrough, 1, Now());
334 ASSERT_EQ(1U, delegate_.NumPassthroughSounds());
335 generator_->Dispatch(&passthrough_press);
336 generator_->ReleaseTouchId(1);
337 generator_->PressTouchId(1);
338 EXPECT_FALSE(IsInGestureInProgressState());
339 EXPECT_FALSE(IsInSlideGestureState());
340 EXPECT_TRUE(IsInCornerPassthroughState());
341
342 std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
343 ASSERT_EQ(3U, captured_events.size());
344 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
345 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
346 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type());
347 generator_->ReleaseTouchId(1);
348 ClearCapturedEvents();
349
350 generator_->ReleaseTouchId(0);
351 captured_events = GetCapturedLocatedEvents();
352 ASSERT_EQ(0U, captured_events.size());
353 EXPECT_FALSE(IsInTouchToMouseMode());
354 EXPECT_FALSE(IsInCornerPassthroughState());
355 ClearCapturedEvents();
356 }
357
276 bool IsInTouchToMouseMode() { 358 bool IsInTouchToMouseMode() {
277 aura::client::CursorClient* cursor_client = 359 aura::client::CursorClient* cursor_client =
278 aura::client::GetCursorClient(root_window()); 360 aura::client::GetCursorClient(root_window());
279 return cursor_client && 361 return cursor_client &&
280 cursor_client->IsMouseEventsEnabled() && 362 cursor_client->IsMouseEventsEnabled() &&
281 !cursor_client->IsCursorVisible(); 363 !cursor_client->IsCursorVisible();
282 } 364 }
283 365
284 bool IsInNoFingersDownState() { 366 bool IsInNoFingersDownState() {
285 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); 367 return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
286 } 368 }
287 369
288 bool IsInGestureInProgressState() { 370 bool IsInGestureInProgressState() {
289 return touch_exploration_controller_ 371 return touch_exploration_controller_
290 ->IsInGestureInProgressStateForTesting(); 372 ->IsInGestureInProgressStateForTesting();
291 } 373 }
292 374
293 bool IsInSlideGestureState() { 375 bool IsInSlideGestureState() {
294 return touch_exploration_controller_->IsInSlideGestureStateForTesting(); 376 return touch_exploration_controller_->IsInSlideGestureStateForTesting();
295 } 377 }
296 378
297 bool IsInTwoFingerTapState() { 379 bool IsInTwoFingerTapState() {
298 return touch_exploration_controller_->IsInTwoFingerTapStateForTesting(); 380 return touch_exploration_controller_->IsInTwoFingerTapStateForTesting();
299 } 381 }
300 382
383 bool IsInCornerPassthroughState() {
384 return touch_exploration_controller_
385 ->IsInCornerPassthroughStateForTesting();
386 }
387
301 gfx::Rect BoundsOfRootWindowInDIP() { 388 gfx::Rect BoundsOfRootWindowInDIP() {
302 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); 389 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting();
303 } 390 }
304 391
305 float GetMaxDistanceFromEdge() const{ 392 float GetMaxDistanceFromEdge() const {
306 return touch_exploration_controller_->GetMaxDistanceFromEdge(); 393 return touch_exploration_controller_->GetMaxDistanceFromEdge();
307 } 394 }
308 395
309 float GetSlopDistanceFromEdge() const{ 396 float GetSlopDistanceFromEdge() const {
310 return touch_exploration_controller_->GetSlopDistanceFromEdge(); 397 return touch_exploration_controller_->GetSlopDistanceFromEdge();
311 } 398 }
312 399
313 base::TimeDelta Now() { 400 base::TimeDelta Now() {
314 // This is the same as what EventTimeForNow() does, but here we do it 401 // This is the same as what EventTimeForNow() does, but here we do it
315 // with our simulated clock. 402 // with our simulated clock.
316 return base::TimeDelta::FromInternalValue( 403 return base::TimeDelta::FromInternalValue(
317 simulated_clock_->NowTicks().ToInternalValue()); 404 simulated_clock_->NowTicks().ToInternalValue());
318 } 405 }
319 406
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 generator_->Dispatch(&first_press_id_2); 1776 generator_->Dispatch(&first_press_id_2);
1690 EXPECT_TRUE(IsInTwoFingerTapState()); 1777 EXPECT_TRUE(IsInTwoFingerTapState());
1691 1778
1692 const ScopedVector<ui::Event>& captured_events = GetCapturedEvents(); 1779 const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1693 ASSERT_EQ(0U, captured_events.size()); 1780 ASSERT_EQ(0U, captured_events.size());
1694 1781
1695 generator_->Dispatch(&out_slop_id_2); 1782 generator_->Dispatch(&out_slop_id_2);
1696 EXPECT_FALSE(IsInTwoFingerTapState()); 1783 EXPECT_FALSE(IsInTwoFingerTapState());
1697 } 1784 }
1698 1785
1786 // Corner passthrough should turn on if the user first holds down on either the
1787 // right or left corner past a delay and then places a finger anywhere else on
1788 // the screen.
1789 TEST_F(TouchExplorationTest, ActivateLeftCornerPassthrough) {
1790 SwitchTouchExplorationMode(true);
1791
1792 gfx::Rect window = BoundsOfRootWindowInDIP();
1793 gfx::Point left_corner(10, window.bottom() - GetMaxDistanceFromEdge() / 2);
1794 AssertCornerPassthroughWorking(left_corner);
1795 }
1796
1797 TEST_F(TouchExplorationTest, ActivateRightCornerPassthrough) {
1798 SwitchTouchExplorationMode(true);
1799
1800 gfx::Rect window = BoundsOfRootWindowInDIP();
1801 gfx::Point right_corner(window.right() - GetMaxDistanceFromEdge() / 2,
1802 window.bottom() - GetMaxDistanceFromEdge() / 2);
1803 AssertCornerPassthroughWorking(right_corner);
1804 }
1805
1806 // Earcons should play if the user slides off the screen or enters the screen
1807 // from the edge.
1808 TEST_F(TouchExplorationTest, EnterEarconPlays) {
1809 SwitchTouchExplorationMode(true);
1810
1811 gfx::Rect window = BoundsOfRootWindowInDIP();
1812
1813 gfx::Point upper_left_corner(0, 0);
1814 gfx::Point upper_right_corner(window.right(), 0);
1815 gfx::Point lower_left_corner(0, window.bottom());
1816 gfx::Point lower_right_corner(window.right(), window.bottom());
1817 gfx::Point left_edge(0, 30);
1818 gfx::Point right_edge(window.right(), 30);
1819 gfx::Point top_edge(30, 0);
1820 gfx::Point bottom_edge(30, window.bottom());
1821
1822 std::vector<gfx::Point> locations;
1823 locations.push_back(upper_left_corner);
1824 locations.push_back(upper_right_corner);
1825 locations.push_back(lower_left_corner);
1826 locations.push_back(lower_right_corner);
1827 locations.push_back(left_edge);
1828 locations.push_back(right_edge);
1829 locations.push_back(top_edge);
1830 locations.push_back(bottom_edge);
1831
1832 for (std::vector<gfx::Point>::const_iterator point = locations.begin();
1833 point != locations.end();
1834 ++point) {
1835 ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, *point, 1, Now());
1836
1837 generator_->Dispatch(&touch_event);
1838 ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1839 generator_->ReleaseTouchId(1);
1840 delegate_.ResetCountersToZero();
1841 }
1842 }
1843
1844 TEST_F(TouchExplorationTest, ExitEarconPlays) {
1845 SwitchTouchExplorationMode(true);
1846
1847 // On the device, it cannot actually tell if the finger has left the screen or
1848 // not. If the finger has left the screen, it reads it as a release that
1849 // occurred very close to the edge of the screen even if the finger is still
1850 // technically touching the moniter. To simulate this, a release that occurs
1851 // close to the edge is dispatched.
1852 gfx::Point initial_press(100, 200);
1853 gfx::Rect window = BoundsOfRootWindowInDIP();
1854
1855 gfx::Point upper_left_corner(0, 0);
1856 gfx::Point upper_right_corner(window.right(), 0);
1857 gfx::Point lower_left_corner(0, window.bottom());
1858 gfx::Point lower_right_corner(window.right(), window.bottom());
1859 gfx::Point left_edge(0, 30);
1860 gfx::Point right_edge(window.right(), 30);
1861 gfx::Point top_edge(30, 0);
1862 gfx::Point bottom_edge(30, window.bottom());
1863
1864 std::vector<gfx::Point> locations;
1865 locations.push_back(upper_left_corner);
1866 locations.push_back(upper_right_corner);
1867 locations.push_back(lower_left_corner);
1868 locations.push_back(lower_right_corner);
1869 locations.push_back(left_edge);
1870 locations.push_back(right_edge);
1871 locations.push_back(top_edge);
1872 locations.push_back(bottom_edge);
1873
1874 for (std::vector<gfx::Point>::const_iterator point = locations.begin();
1875 point != locations.end();
1876 ++point) {
1877 generator_->PressTouch();
1878 generator_->MoveTouch(initial_press);
1879 generator_->MoveTouch(*point);
1880 generator_->ReleaseTouch();
1881 ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1882 delegate_.ResetCountersToZero();
1883 }
1884 }
1885
1699 } // namespace ui 1886 } // 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