Chromium Code Reviews| Index: ui/chromeos/touch_exploration_controller_unittest.cc |
| diff --git a/ui/chromeos/touch_exploration_controller_unittest.cc b/ui/chromeos/touch_exploration_controller_unittest.cc |
| index 70bac63e756ee6fb2fd0954e6db0c243400f5534..e557a1976b9c781ea415fada95e9330cface685a 100644 |
| --- a/ui/chromeos/touch_exploration_controller_unittest.cc |
| +++ b/ui/chromeos/touch_exploration_controller_unittest.cc |
| @@ -72,6 +72,24 @@ int Factorial(int n) { |
| return n * Factorial(n - 1); |
| } |
| +class MockTouchExplorationControllerDelegate |
| + : public ui::TouchExplorationControllerDelegate { |
| + public: |
| + virtual void PlayVolumeAdjustSound() OVERRIDE { |
| + ++num_times_adjust_sound_played_; |
| + } |
| + virtual void SetOutputLevel(int volume) OVERRIDE { |
| + volume_changes_.push_back(volume); |
| + } |
| + |
| + const std::vector<float> VolumeChanges() { return volume_changes_; } |
| + const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; } |
| + |
| + private: |
| + std::vector<float> volume_changes_; |
| + size_t num_times_adjust_sound_played_ = 0; |
| +}; |
| + |
| } // namespace |
| class TouchExplorationControllerTestApi { |
| @@ -110,6 +128,15 @@ class TouchExplorationControllerTestApi { |
| touch_exploration_controller_->GESTURE_IN_PROGRESS; |
| } |
| + bool IsInSlideGestureStateForTesting() const { |
| + return touch_exploration_controller_->state_ == |
| + touch_exploration_controller_->SLIDE_GESTURE; |
| + } |
| + |
| + gfx::Rect BoundsOfRootWindowInDIPForTesting() const { |
| + return touch_exploration_controller_->root_window_->GetBoundsInScreen(); |
| + } |
| + |
| // VLOGs should be suppressed in tests that generate a lot of logs, |
| // for example permutations of nine touch events. |
| void SuppressVLOGsForTesting(bool suppress) { |
| @@ -212,8 +239,9 @@ class TouchExplorationTest : public aura::test::AuraTestBase { |
| if (!on && touch_exploration_controller_.get()) { |
| touch_exploration_controller_.reset(); |
| } else if (on && !touch_exploration_controller_.get()) { |
| - touch_exploration_controller_.reset(new TouchExplorationControllerTestApi( |
| - new ui::TouchExplorationController(root_window()))); |
| + touch_exploration_controller_.reset( |
| + new ui::TouchExplorationControllerTestApi( |
| + new TouchExplorationController(root_window(), &delegate_))); |
| touch_exploration_controller_->SetEventHandlerForTesting( |
| &event_capturer_); |
| cursor_client()->ShowCursor(); |
| @@ -256,6 +284,14 @@ class TouchExplorationTest : public aura::test::AuraTestBase { |
| ->IsInGestureInProgressStateForTesting(); |
| } |
| + bool IsInSlideGestureState() { |
| + return touch_exploration_controller_->IsInSlideGestureStateForTesting(); |
| + } |
| + |
| + gfx::Rect BoundsOfRootWindowInDIP() { |
| + return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); |
| + } |
| + |
| base::TimeDelta Now() { |
| // This is the same as what EventTimeForNow() does, but here we do it |
| // with our simulated clock. |
| @@ -267,6 +303,7 @@ class TouchExplorationTest : public aura::test::AuraTestBase { |
| ui::GestureDetector::Config gesture_detector_config_; |
| // Owned by |generator_|. |
| base::SimpleTestTickClock* simulated_clock_; |
| + MockTouchExplorationControllerDelegate delegate_; |
| private: |
| EventCapturer event_capturer_; |
| @@ -510,6 +547,7 @@ TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) { |
| SwitchTouchExplorationMode(true); |
| // Send a press, then add another finger after the double-tap timeout. |
| + generator_->MoveTouch(gfx::Point(100, 200)); |
|
aboxhall
2014/07/22 17:20:42
Perhaps move this above the preceding comment and
lisayin
2014/07/22 18:06:26
Done.
|
| generator_->PressTouchId(1); |
| simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000)); |
| generator_->PressTouchId(2); |
| @@ -1357,10 +1395,11 @@ TEST_F(TouchExplorationTest, FromGestureToPassthrough) { |
| EXPECT_FALSE(IsInGestureInProgressState()); |
| float distance = gesture_detector_config_.touch_slop + 1; |
| - ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 1), 0, Now()); |
| + ui::TouchEvent first_press( |
| + ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), 0, Now()); |
| generator_->Dispatch(&first_press); |
| simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| - gfx::Point second_location(distance, 1); |
| + gfx::Point second_location(100 + distance, 200); |
| generator_->MoveTouch(second_location); |
| EXPECT_TRUE(IsInGestureInProgressState()); |
| EXPECT_FALSE(IsInTouchToMouseMode()); |
| @@ -1388,4 +1427,205 @@ TEST_F(TouchExplorationTest, FromGestureToPassthrough) { |
| ASSERT_EQ(0U, captured_events.size()); |
| } |
| +TEST_F(TouchExplorationTest, EnterSlideGestureState) { |
| + SwitchTouchExplorationMode(true); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + |
| + gfx::Rect window = BoundsOfRootWindowInDIP(); |
| + float distance = gesture_detector_config_.touch_slop + 1; |
| + ui::TouchEvent first_press( |
| + ui::ET_TOUCH_PRESSED, gfx::Point(window.right(), 1), 0, Now()); |
| + gfx::Point second_location(window.right(), 1 + distance / 2); |
| + gfx::Point third_location(window.right(), 1 + distance); |
| + |
| + generator_->Dispatch(&first_press); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| + |
| + // Since we haven't moved past slop yet, we should not be in slide gesture. |
| + generator_->MoveTouch(second_location); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| + |
| + // Once we are out of slop, we should be in slide gesture since we are along |
| + // the edge of the screen. |
| + generator_->MoveTouch(third_location); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_TRUE(IsInSlideGestureState()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + const ScopedVector<ui::Event>& captured_events = GetCapturedEvents(); |
| + ASSERT_EQ(0U, captured_events.size()); |
| + |
| + // Since we are at the right edge of the screen, but the sound timer has not |
| + // elapsed, there should have two sounds that fired and two volume |
|
aboxhall
2014/07/22 17:20:42
So the move within the slop region generates a vol
lisayin
2014/07/22 18:06:26
The slop region is an additional grace area so tha
|
| + // changes (one for each movement). |
| + size_t num_adjust_sounds = delegate_.NumAdjustSounds(); |
| + ASSERT_EQ(2U, num_adjust_sounds); |
| + ASSERT_EQ(2U, delegate_.VolumeChanges().size()); |
| + |
| + // Exit out of slide gesture once touch is lifted, but not before even if the |
| + // grace period is over. |
| + |
| + AdvanceSimulatedTimePastPotentialTapDelay(); |
| + ASSERT_EQ(0U, captured_events.size()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_TRUE(IsInSlideGestureState()); |
| + |
| + generator_->ReleaseTouch(); |
| + ASSERT_EQ(0U, captured_events.size()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| +} |
| + |
| +// If a press + move occurred outside the boundaries, but within the slop |
| +// boundaries and then moved into the boundaries of an edge, there still should |
| +// not be a slide gesture. |
| +TEST_F(TouchExplorationTest, AvoidEnteringSlideGesture) { |
| + SwitchTouchExplorationMode(true); |
| + |
| + // DO SOMETHING TO MAKE THESE CONSTANTS ACCESSIBLE FROM ORIGINAL FILE |
|
dmazzoni
2014/07/22 17:14:55
Define the constants you need in the TouchExplorat
lisayin
2014/07/22 18:06:26
Done.
|
| + const float kMaxDistanceFromEdge = 75; |
| + const float kSlopDistanceFromEdge = kMaxDistanceFromEdge + 40; |
| + |
| + gfx::Rect window = BoundsOfRootWindowInDIP(); |
| + float distance = gesture_detector_config_.touch_slop + 1; |
| + ui::TouchEvent first_press( |
| + ui::ET_TOUCH_PRESSED, |
| + gfx::Point(window.right() - kSlopDistanceFromEdge, 1), |
| + 0, |
| + Now()); |
| + gfx::Point out_of_slop(window.right() - kSlopDistanceFromEdge + distance, 1); |
| + gfx::Point into_boundaries(window.right() - kMaxDistanceFromEdge / 2, 1); |
| + |
| + generator_->Dispatch(&first_press); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| + |
| + generator_->MoveTouch(out_of_slop); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + EXPECT_TRUE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| + |
| + // Since we did not start moving while in the boundaries, we should not be in |
| + // slide gestures. |
| + generator_->MoveTouch(into_boundaries); |
| + EXPECT_TRUE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + const ScopedVector<ui::Event>& captured_events = GetCapturedEvents(); |
| + ASSERT_EQ(0U, captured_events.size()); |
| + |
| + generator_->ReleaseTouch(); |
| +} |
| + |
| +// If the slide gesture begins within the boundaries and then moves |
| +// SlopDistanceFromEdge there should still be a sound change. If the finger |
| +// moves into the center screen, there should no longer be a sound change but it |
| +// should still be in slide gesture. If the finger moves back into the edges |
| +// without lifting, it should start changing sound again. |
| +TEST_F(TouchExplorationTest, TestingBoundaries) { |
| + SwitchTouchExplorationMode(true); |
| + |
| + const float kMaxDistanceFromEdge = 75; |
| + const float kSlopDistanceFromEdge = kMaxDistanceFromEdge + 40; |
| + |
| + gfx::Rect window = BoundsOfRootWindowInDIP(); |
| + gfx::Point initial_press(window.right() - kMaxDistanceFromEdge / 2, 1); |
| + ui::TouchEvent first_press( |
| + ui::ET_TOUCH_PRESSED, |
| + initial_press, |
| + 0, |
| + Now()); |
| + gfx::Point touch_move(initial_press.x() + gesture_detector_config_.touch_slop, |
| + 1); |
| + gfx::Point into_slop_boundaries(window.right() - kSlopDistanceFromEdge / 2, |
| + 1); |
| + gfx::Point center_screen(window.right() / 2, window.bottom() / 2); |
| + |
| + generator_->Dispatch(&first_press); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| + |
| + generator_->MoveTouch(touch_move); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| + |
| + // Move the touch into slop boundaries. It should stil be in slide gestures |
| + // and adjust the volume. |
| + generator_->MoveTouch(into_slop_boundaries); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_TRUE(IsInSlideGestureState()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + |
| + // The sound is rate limiting so it only activates every 150ms. |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(200)); |
| + |
| + size_t num_adjust_sounds = delegate_.NumAdjustSounds(); |
| + ASSERT_EQ(2U, num_adjust_sounds); |
| + ASSERT_EQ(2U, delegate_.VolumeChanges().size()); |
| + |
| + // Move the touch into the center of the window. It should still be in slide |
| + // gestures, but there should not be anymore volume adjustments. |
| + generator_->MoveTouch(center_screen); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_TRUE(IsInSlideGestureState()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(200)); |
| + num_adjust_sounds = delegate_.NumAdjustSounds(); |
| + ASSERT_EQ(2U, num_adjust_sounds); |
| + ASSERT_EQ(2U, delegate_.VolumeChanges().size()); |
| + |
| + // Move the touch back into slop edge distance and volume should be changing |
| + // again. |
| + generator_->MoveTouch(into_slop_boundaries); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_TRUE(IsInSlideGestureState()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + |
| + generator_->MoveTouch( |
| + gfx::Point(into_slop_boundaries.x() + gesture_detector_config_.touch_slop, |
| + into_slop_boundaries.y())); |
| + simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(200)); |
| + |
| + num_adjust_sounds = delegate_.NumAdjustSounds(); |
| + ASSERT_EQ(3U, num_adjust_sounds); |
| + ASSERT_EQ(3U, delegate_.VolumeChanges().size()); |
| + |
| + const ScopedVector<ui::Event>& captured_events = GetCapturedEvents(); |
| + ASSERT_EQ(0U, captured_events.size()); |
| + |
| + generator_->ReleaseTouch(); |
| +} |
| + |
| +// Even if the gesture starts within bounds, if it has not moved past slop |
| +// within the grace period, it should go to touch exploration. |
| +TEST_F(TouchExplorationTest, InBoundariesTouchExploration) { |
| + SwitchTouchExplorationMode(true); |
| + |
| + const float kMaxDistanceFromEdge = 75; |
| + |
| + gfx::Rect window = BoundsOfRootWindowInDIP(); |
| + gfx::Point initial_press(window.right() - kMaxDistanceFromEdge / 2, 1); |
| + ui::TouchEvent first_press( |
| + ui::ET_TOUCH_PRESSED, |
| + initial_press, |
| + 0, |
| + Now()); |
| + generator_->Dispatch(&first_press); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| + EXPECT_FALSE(IsInTouchToMouseMode()); |
| + |
| + AdvanceSimulatedTimePastTapDelay(); |
| + EXPECT_FALSE(IsInGestureInProgressState()); |
| + EXPECT_FALSE(IsInSlideGestureState()); |
| + EXPECT_TRUE(IsInTouchToMouseMode()); |
| +} |
| + |
| } // namespace ui |