| 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 "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 Loading... |
| 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 } |
| 81 virtual void PlayVolumeAdjustEarcon() OVERRIDE { |
| 82 ++num_times_adjust_sound_played_; |
| 83 } |
| 84 virtual void PlayPassthroughEarcon() OVERRIDE {} |
| 85 virtual void PlayExitScreenEarcon() OVERRIDE {} |
| 86 virtual void PlayEnterScreenEarcon() OVERRIDE {} |
| 84 | 87 |
| 85 const std::vector<float> VolumeChanges() { return volume_changes_; } | 88 const std::vector<float> VolumeChanges() { return volume_changes_; } |
| 86 const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; } | 89 const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; } |
| 87 | 90 |
| 88 private: | 91 private: |
| 89 std::vector<float> volume_changes_; | 92 std::vector<float> volume_changes_; |
| 90 size_t num_times_adjust_sound_played_ = 0; | 93 size_t num_times_adjust_sound_played_ = 0; |
| 91 }; | 94 }; |
| 92 | 95 |
| 93 } // namespace | 96 } // namespace |
| 94 | 97 |
| 95 class TouchExplorationControllerTestApi { | 98 class TouchExplorationControllerTestApi { |
| 96 public: | 99 public: |
| 97 TouchExplorationControllerTestApi( | 100 TouchExplorationControllerTestApi( |
| 98 TouchExplorationController* touch_exploration_controller) { | 101 TouchExplorationController* touch_exploration_controller) { |
| 99 touch_exploration_controller_.reset(touch_exploration_controller); | 102 touch_exploration_controller_.reset(touch_exploration_controller); |
| 100 } | 103 } |
| 101 | 104 |
| 102 void CallTapTimerNowForTesting() { | 105 void CallTapTimerNowForTesting() { |
| 103 DCHECK(touch_exploration_controller_->tap_timer_.IsRunning()); | 106 DCHECK(touch_exploration_controller_->tap_timer_.IsRunning()); |
| 104 touch_exploration_controller_->tap_timer_.Stop(); | 107 touch_exploration_controller_->tap_timer_.Stop(); |
| 105 touch_exploration_controller_->OnTapTimerFired(); | 108 touch_exploration_controller_->OnTapTimerFired(); |
| 106 } | 109 } |
| 107 | 110 |
| 111 void CallLongPressTimerNowForTesting() { |
| 112 DCHECK(touch_exploration_controller_->long_press_timer_.IsRunning()); |
| 113 touch_exploration_controller_->long_press_timer_.Stop(); |
| 114 touch_exploration_controller_->OnLongPressTimerFired(); |
| 115 } |
| 116 |
| 108 void CallTapTimerNowIfRunningForTesting() { | 117 void CallTapTimerNowIfRunningForTesting() { |
| 109 if (touch_exploration_controller_->tap_timer_.IsRunning()) { | 118 if (touch_exploration_controller_->tap_timer_.IsRunning()) { |
| 110 touch_exploration_controller_->tap_timer_.Stop(); | 119 touch_exploration_controller_->tap_timer_.Stop(); |
| 111 touch_exploration_controller_->OnTapTimerFired(); | 120 touch_exploration_controller_->OnTapTimerFired(); |
| 112 } | 121 } |
| 113 } | 122 } |
| 114 | 123 |
| 115 void SetEventHandlerForTesting( | 124 void SetEventHandlerForTesting( |
| 116 ui::EventHandler* event_handler_for_testing) { | 125 ui::EventHandler* event_handler_for_testing) { |
| 117 touch_exploration_controller_->event_handler_for_testing_ = | 126 touch_exploration_controller_->event_handler_for_testing_ = |
| 118 event_handler_for_testing; | 127 event_handler_for_testing; |
| 119 } | 128 } |
| 120 | 129 |
| 121 bool IsInNoFingersDownStateForTesting() const { | 130 bool IsInNoFingersDownStateForTesting() const { |
| 122 return touch_exploration_controller_->state_ == | 131 return touch_exploration_controller_->state_ == |
| 123 touch_exploration_controller_->NO_FINGERS_DOWN; | 132 touch_exploration_controller_->NO_FINGERS_DOWN; |
| 124 } | 133 } |
| 125 | 134 |
| 126 bool IsInGestureInProgressStateForTesting() const { | 135 bool IsInGestureInProgressStateForTesting() const { |
| 127 return touch_exploration_controller_->state_ == | 136 return touch_exploration_controller_->state_ == |
| 128 touch_exploration_controller_->GESTURE_IN_PROGRESS; | 137 touch_exploration_controller_->GESTURE_IN_PROGRESS; |
| 129 } | 138 } |
| 130 | 139 |
| 131 bool IsInSlideGestureStateForTesting() const { | 140 bool IsInSlideGestureStateForTesting() const { |
| 132 return touch_exploration_controller_->state_ == | 141 return touch_exploration_controller_->state_ == |
| 133 touch_exploration_controller_->SLIDE_GESTURE; | 142 touch_exploration_controller_->SLIDE_GESTURE; |
| 134 } | 143 } |
| 135 | 144 |
| 145 bool IsInCornerPassthroughStateForTesting() const { |
| 146 return touch_exploration_controller_->state_ == |
| 147 touch_exploration_controller_->CORNER_PASSTHROUGH; |
| 148 } |
| 149 |
| 136 gfx::Rect BoundsOfRootWindowInDIPForTesting() const { | 150 gfx::Rect BoundsOfRootWindowInDIPForTesting() const { |
| 137 return touch_exploration_controller_->root_window_->GetBoundsInScreen(); | 151 return touch_exploration_controller_->root_window_->GetBoundsInScreen(); |
| 138 } | 152 } |
| 139 | 153 |
| 140 // VLOGs should be suppressed in tests that generate a lot of logs, | 154 // VLOGs should be suppressed in tests that generate a lot of logs, |
| 141 // for example permutations of nine touch events. | 155 // for example permutations of nine touch events. |
| 142 void SuppressVLOGsForTesting(bool suppress) { | 156 void SuppressVLOGsForTesting(bool suppress) { |
| 143 touch_exploration_controller_->VLOG_on_ = !suppress; | 157 touch_exploration_controller_->VLOG_on_ = !suppress; |
| 144 } | 158 } |
| 145 | 159 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 241 |
| 228 void ClearCapturedEvents() { | 242 void ClearCapturedEvents() { |
| 229 event_capturer_.Reset(); | 243 event_capturer_.Reset(); |
| 230 } | 244 } |
| 231 | 245 |
| 232 void AdvanceSimulatedTimePastTapDelay() { | 246 void AdvanceSimulatedTimePastTapDelay() { |
| 233 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); | 247 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); |
| 234 touch_exploration_controller_->CallTapTimerNowForTesting(); | 248 touch_exploration_controller_->CallTapTimerNowForTesting(); |
| 235 } | 249 } |
| 236 | 250 |
| 251 void AdvanceSimulatedTimePastLongPressDelay() { |
| 252 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); |
| 253 touch_exploration_controller_->CallLongPressTimerNowForTesting(); |
| 254 } |
| 255 |
| 237 void AdvanceSimulatedTimePastPotentialTapDelay() { | 256 void AdvanceSimulatedTimePastPotentialTapDelay() { |
| 238 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); | 257 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); |
| 239 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); | 258 touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); |
| 240 } | 259 } |
| 241 | 260 |
| 242 void SuppressVLOGs(bool suppress) { | 261 void SuppressVLOGs(bool suppress) { |
| 243 touch_exploration_controller_->SuppressVLOGsForTesting(suppress); | 262 touch_exploration_controller_->SuppressVLOGsForTesting(suppress); |
| 244 } | 263 } |
| 245 | 264 |
| 246 void SwitchTouchExplorationMode(bool on) { | 265 void SwitchTouchExplorationMode(bool on) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 268 gfx::Point second_touch_location) { | 287 gfx::Point second_touch_location) { |
| 269 SwitchTouchExplorationMode(true); | 288 SwitchTouchExplorationMode(true); |
| 270 ui::TouchEvent first_touch_press( | 289 ui::TouchEvent first_touch_press( |
| 271 ui::ET_TOUCH_PRESSED, first_touch_location, 0, Now()); | 290 ui::ET_TOUCH_PRESSED, first_touch_location, 0, Now()); |
| 272 generator_->Dispatch(&first_touch_press); | 291 generator_->Dispatch(&first_touch_press); |
| 273 ui::TouchEvent second_touch_press( | 292 ui::TouchEvent second_touch_press( |
| 274 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); | 293 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now()); |
| 275 generator_->Dispatch(&second_touch_press); | 294 generator_->Dispatch(&second_touch_press); |
| 276 } | 295 } |
| 277 | 296 |
| 297 // Checks that Corner Passthrough is working. Assumes that corner is the |
| 298 // bottom left corner or the bottom right corner. |
| 299 void AssertCornerPassthroughWorking(gfx::Point corner) { |
| 300 ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, corner, 0, Now()); |
| 301 generator_->Dispatch(&first_press); |
| 302 |
| 303 AdvanceSimulatedTimePastLongPressDelay(); |
| 304 EXPECT_FALSE(IsInGestureInProgressState()); |
| 305 EXPECT_FALSE(IsInSlideGestureState()); |
| 306 EXPECT_FALSE(IsInTouchToMouseMode()); |
| 307 EXPECT_TRUE(IsInCornerPassthroughState()); |
| 308 |
| 309 // The following events should be passed through. |
| 310 gfx::Point passthrough(window.right() / 2, window.bottom() / 2); |
| 311 ui::TouchEvent passthrough_press( |
| 312 ui::ET_TOUCH_PRESSED, passthrough, 1, Now()); |
| 313 generator_->Dispatch(&passthrough_press); |
| 314 generator_->ReleaseTouchId(1); |
| 315 generator_->PressTouchId(1); |
| 316 EXPECT_FALSE(IsInGestureInProgressState()); |
| 317 EXPECT_FALSE(IsInSlideGestureState()); |
| 318 EXPECT_TRUE(IsInCornerPassthroughState()); |
| 319 |
| 320 std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); |
| 321 ASSERT_EQ(3U, captured_events.size()); |
| 322 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); |
| 323 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); |
| 324 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type()); |
| 325 generator_->ReleaseTouchId(1); |
| 326 ClearCapturedEvents(); |
| 327 |
| 328 generator_->ReleaseTouchId(0); |
| 329 captured_events = GetCapturedLocatedEvents(); |
| 330 ASSERT_EQ(0U, captured_events.size()); |
| 331 EXPECT_FALSE(IsInTouchToMouseMode()); |
| 332 EXPECT_FALSE(IsInCornerPassthroughState()); |
| 333 ClearCapturedEvents(); |
| 334 } |
| 335 |
| 278 bool IsInTouchToMouseMode() { | 336 bool IsInTouchToMouseMode() { |
| 279 aura::client::CursorClient* cursor_client = | 337 aura::client::CursorClient* cursor_client = |
| 280 aura::client::GetCursorClient(root_window()); | 338 aura::client::GetCursorClient(root_window()); |
| 281 return cursor_client && | 339 return cursor_client && cursor_client->IsMouseEventsEnabled() && |
| 282 cursor_client->IsMouseEventsEnabled() && | |
| 283 !cursor_client->IsCursorVisible(); | 340 !cursor_client->IsCursorVisible(); |
| 284 } | 341 } |
| 285 | 342 |
| 286 bool IsInNoFingersDownState() { | 343 bool IsInNoFingersDownState() { |
| 287 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); | 344 return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); |
| 288 } | 345 } |
| 289 | 346 |
| 290 bool IsInGestureInProgressState() { | 347 bool IsInGestureInProgressState() { |
| 291 return touch_exploration_controller_ | 348 return touch_exploration_controller_ |
| 292 ->IsInGestureInProgressStateForTesting(); | 349 ->IsInGestureInProgressStateForTesting(); |
| 293 } | 350 } |
| 294 | 351 |
| 295 bool IsInSlideGestureState() { | 352 bool IsInSlideGestureState() { |
| 296 return touch_exploration_controller_->IsInSlideGestureStateForTesting(); | 353 return touch_exploration_controller_->IsInSlideGestureStateForTesting(); |
| 297 } | 354 } |
| 298 | 355 |
| 356 bool IsInCornerPassthroughState() { |
| 357 return touch_exploration_controller_ |
| 358 ->IsInCornerPassthroughStateForTesting(); |
| 359 } |
| 360 |
| 299 gfx::Rect BoundsOfRootWindowInDIP() { | 361 gfx::Rect BoundsOfRootWindowInDIP() { |
| 300 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); | 362 return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); |
| 301 } | 363 } |
| 302 | 364 |
| 303 float GetMaxDistanceFromEdge() const{ | 365 float GetMaxDistanceFromEdge() const { |
| 304 return touch_exploration_controller_->GetMaxDistanceFromEdge(); | 366 return touch_exploration_controller_->GetMaxDistanceFromEdge(); |
| 305 } | 367 } |
| 306 | 368 |
| 307 float GetSlopDistanceFromEdge() const{ | 369 float GetSlopDistanceFromEdge() const{ |
| 308 return touch_exploration_controller_->GetSlopDistanceFromEdge(); | 370 return touch_exploration_controller_->GetSlopDistanceFromEdge(); |
| 309 } | 371 } |
| 310 | 372 |
| 311 base::TimeDelta Now() { | 373 base::TimeDelta Now() { |
| 312 // This is the same as what EventTimeForNow() does, but here we do it | 374 // This is the same as what EventTimeForNow() does, but here we do it |
| 313 // with our simulated clock. | 375 // with our simulated clock. |
| (...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1633 EXPECT_FALSE(IsInGestureInProgressState()); | 1695 EXPECT_FALSE(IsInGestureInProgressState()); |
| 1634 EXPECT_FALSE(IsInSlideGestureState()); | 1696 EXPECT_FALSE(IsInSlideGestureState()); |
| 1635 EXPECT_FALSE(IsInTouchToMouseMode()); | 1697 EXPECT_FALSE(IsInTouchToMouseMode()); |
| 1636 | 1698 |
| 1637 AdvanceSimulatedTimePastTapDelay(); | 1699 AdvanceSimulatedTimePastTapDelay(); |
| 1638 EXPECT_FALSE(IsInGestureInProgressState()); | 1700 EXPECT_FALSE(IsInGestureInProgressState()); |
| 1639 EXPECT_FALSE(IsInSlideGestureState()); | 1701 EXPECT_FALSE(IsInSlideGestureState()); |
| 1640 EXPECT_TRUE(IsInTouchToMouseMode()); | 1702 EXPECT_TRUE(IsInTouchToMouseMode()); |
| 1641 } | 1703 } |
| 1642 | 1704 |
| 1705 // Corner passthrough should turn on if the user first holds down on either the |
| 1706 // right or left corner past a delay and then places a finger anywhere else on |
| 1707 // the screen. |
| 1708 TEST_F(TouchExplorationTest, ActivateLeftCornerPassthrough) { |
| 1709 SwitchTouchExplorationMode(true); |
| 1710 |
| 1711 gfx::Rect window = BoundsOfRootWindowInDIP(); |
| 1712 gfx::Point left_corner(10, window.bottom() - GetMaxDistanceFromEdge() / 2); |
| 1713 AssertCornerPassthroughWorking(left_corner); |
| 1714 } |
| 1715 |
| 1716 TEST_F(TouchExplorationTest, ActivateRightCornerPassthrough) { |
| 1717 SwitchTouchExplorationMode(true); |
| 1718 |
| 1719 gfx::Rect window = BoundsOfRootWindowInDIP(); |
| 1720 gfx::Point right_corner(window.right() - GetMaxDistanceFromEdge() / 2, |
| 1721 window.bottom() - GetMaxDistanceFromEdge() / 2); |
| 1722 AssertCornerPassthroughWorking(right_corner); |
| 1723 } |
| 1724 |
| 1643 } // namespace ui | 1725 } // namespace ui |
| OLD | NEW |