| 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 6b1f3dea84621539f4b272c9c94ed4bd714e37d3..11e9b443b6b91078b7237c15c8865edbcfdb6df1 100644
|
| --- a/ui/chromeos/touch_exploration_controller_unittest.cc
|
| +++ b/ui/chromeos/touch_exploration_controller_unittest.cc
|
| @@ -71,6 +71,24 @@ int Factorial(int n) {
|
| return n * Factorial(n - 1);
|
| }
|
|
|
| +class MockTouchExplorationControllerDelegate
|
| + : public ui::TouchExplorationControllerDelegate {
|
| + public:
|
| + virtual void const PlayVolumeAdjustSound() OVERRIDE {
|
| + ++num_times_adjust_sound_played_;
|
| + }
|
| + virtual void AdjustSound(float volume) OVERRIDE {
|
| + volume_changes_.push_back(volume);
|
| + }
|
| +
|
| + const std::vector<float> VolumeChanges() { return volume_changes_; }
|
| + const int NumAdjustSounds() { return num_times_adjust_sound_played_; }
|
| +
|
| + private:
|
| + std::vector<float> volume_changes_;
|
| + int num_times_adjust_sound_played_ = 0;
|
| +};
|
| +
|
| } // namespace
|
|
|
| class TouchExplorationTest : public aura::test::AuraTestBase {
|
| @@ -85,6 +103,7 @@ class TouchExplorationTest : public aura::test::AuraTestBase {
|
| if (gfx::GetGLImplementation() == gfx::kGLImplementationNone)
|
| gfx::GLSurface::InitializeOneOffForTests();
|
| aura::test::AuraTestBase::SetUp();
|
| + delegate_ = new MockTouchExplorationControllerDelegate();
|
| cursor_client_.reset(new aura::test::TestCursorClient(root_window()));
|
| root_window()->AddPreTargetHandler(&event_capturer_);
|
| generator_.reset(new aura::test::EventGenerator(root_window()));
|
| @@ -164,7 +183,7 @@ class TouchExplorationTest : public aura::test::AuraTestBase {
|
| touch_exploration_controller_.reset();
|
| } else if (on && !touch_exploration_controller_.get()) {
|
| touch_exploration_controller_.reset(
|
| - new ui::TouchExplorationController(root_window()));
|
| + new ui::TouchExplorationController(root_window(), delegate_));
|
| touch_exploration_controller_->SetEventHandlerForTesting(
|
| &event_capturer_);
|
| cursor_client()->ShowCursor();
|
| @@ -207,6 +226,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.
|
| @@ -218,6 +245,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_;
|
| @@ -460,6 +488,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));
|
| generator_->PressTouchId(1);
|
| simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
|
| generator_->PressTouchId(2);
|
| @@ -1307,10 +1336,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());
|
| @@ -1338,4 +1368,207 @@ 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
|
| + // changes (one for each movement).
|
| + int num_adjust_sounds = delegate_->NumAdjustSounds();
|
| + EXPECT_EQ(num_adjust_sounds, 2U);
|
| + EXPECT_EQ(delegate_->VolumeChanges().size(), 2U);
|
| +
|
| + // 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
|
| + 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);
|
| +
|
| + // DO SOMETHING TO MAKE THESE CONSTANTS ACCESSIBLE FROM ORIGINAL FILE
|
| + 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));
|
| +
|
| + int num_adjust_sounds = delegate_->NumAdjustSounds();
|
| + EXPECT_EQ(num_adjust_sounds, 2U);
|
| + EXPECT_EQ(delegate_->VolumeChanges().size(), 2U);
|
| +
|
| + // 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();
|
| + EXPECT_EQ(num_adjust_sounds, 2U);
|
| + EXPECT_EQ(delegate_->VolumeChanges().size(), 2U);
|
| +
|
| + // 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();
|
| + EXPECT_EQ(num_adjust_sounds, 3U);
|
| + EXPECT_EQ(delegate_->VolumeChanges().size(), 3U);
|
| +
|
| + 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);
|
| +
|
| + // DO SOMETHING TO MAKE THESE CONSTANTS ACCESSIBLE FROM ORIGINAL FILE
|
| + 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
|
|
|