blob: 689900073c1ae72dc3ff8f59d0d64b4db08aca75 [file] [log] [blame]
dmazzoni16d2dec2016-12-19 23:27:571// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/chromeos/touch_accessibility_enabler.h"
6
7#include "base/macros.h"
8#include "base/test/simple_test_tick_clock.h"
9#include "base/time/time.h"
10#include "ui/aura/test/aura_test_base.h"
11#include "ui/aura/window.h"
12#include "ui/events/event.h"
13#include "ui/events/event_utils.h"
14#include "ui/events/gestures/gesture_provider_aura.h"
15#include "ui/events/test/event_generator.h"
16#include "ui/events/test/events_test_utils.h"
17#include "ui/gfx/geometry/point.h"
18
19namespace ui {
20
21namespace {
22
23class MockTouchAccessibilityEnablerDelegate
24 : public ui::TouchAccessibilityEnablerDelegate {
25 public:
26 MockTouchAccessibilityEnablerDelegate() {}
27 ~MockTouchAccessibilityEnablerDelegate() override {}
28
dmazzonidf9a1e922017-04-13 05:10:4429 void OnTwoFingerTouchStart() override { started_ = true; }
30
31 void OnTwoFingerTouchStop() override { stopped_ = true; }
32
dmazzoni16d2dec2016-12-19 23:27:5733 void PlaySpokenFeedbackToggleCountdown(int tick_count) override {
34 ++feedback_progress_sound_count_;
35 }
36 void ToggleSpokenFeedback() override { toggle_spoken_feedback_ = true; }
37
dmazzonidf9a1e922017-04-13 05:10:4438 bool started() { return started_; }
39 bool stopped() { return stopped_; }
dmazzoni16d2dec2016-12-19 23:27:5740 size_t feedback_progress_sound_count() const {
41 return feedback_progress_sound_count_;
42 }
43 bool toggle_spoken_feedback() const { return toggle_spoken_feedback_; }
44
45 private:
dmazzonidf9a1e922017-04-13 05:10:4446 bool started_ = false;
47 bool stopped_ = false;
dmazzoni16d2dec2016-12-19 23:27:5748 size_t feedback_progress_sound_count_ = 0;
49 bool toggle_spoken_feedback_ = false;
50
51 DISALLOW_COPY_AND_ASSIGN(MockTouchAccessibilityEnablerDelegate);
52};
53
54class TouchAccessibilityEnablerTest : public aura::test::AuraTestBase {
55 public:
56 TouchAccessibilityEnablerTest() {}
57 ~TouchAccessibilityEnablerTest() override {}
58
59 void SetUp() override {
60 aura::test::AuraTestBase::SetUp();
61
62 generator_.reset(new test::EventGenerator(root_window()));
63
64 simulated_clock_ = new base::SimpleTestTickClock();
65 // Tests fail if time is ever 0.
66 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
67 // ui takes ownership of the tick clock.
68 ui::SetEventTickClockForTesting(
69 std::unique_ptr<base::TickClock>(simulated_clock_));
70
71 enabler_.reset(new TouchAccessibilityEnabler(root_window(), &delegate_));
72 }
73
74 void TearDown() override {
75 enabler_.reset(nullptr);
76 ui::SetEventTickClockForTesting(nullptr);
77 aura::test::AuraTestBase::TearDown();
78 }
79
80 protected:
81 base::TimeTicks Now() {
82 // This is the same as what EventTimeForNow() does, but here we do it
83 // with our simulated clock.
84 return simulated_clock_->NowTicks();
85 }
86
87 std::unique_ptr<test::EventGenerator> generator_;
88 // Owned by |ui|.
89 base::SimpleTestTickClock* simulated_clock_ = nullptr;
90 MockTouchAccessibilityEnablerDelegate delegate_;
91 std::unique_ptr<TouchAccessibilityEnabler> enabler_;
92 ui::GestureDetector::Config gesture_detector_config_;
93
94 DISALLOW_COPY_AND_ASSIGN(TouchAccessibilityEnablerTest);
95};
96
97} // namespace
98
99TEST_F(TouchAccessibilityEnablerTest, EntersOneFingerDownMode) {
100 EXPECT_TRUE(enabler_->IsInNoFingersDownForTesting());
101 EXPECT_FALSE(enabler_->IsInOneFingerDownForTesting());
102 generator_->set_current_location(gfx::Point(11, 12));
103 generator_->PressTouch();
104
105 EXPECT_FALSE(enabler_->IsInNoFingersDownForTesting());
106 EXPECT_TRUE(enabler_->IsInOneFingerDownForTesting());
107}
108
109TEST_F(TouchAccessibilityEnablerTest, EntersTwoFingersDownMode) {
110 EXPECT_TRUE(enabler_->IsInNoFingersDownForTesting());
111 generator_->set_current_location(gfx::Point(11, 12));
112 generator_->PressTouchId(1);
113
114 generator_->set_current_location(gfx::Point(22, 34));
115 generator_->PressTouchId(2);
116
117 EXPECT_TRUE(enabler_->IsInTwoFingersDownForTesting());
118}
119
120TEST_F(TouchAccessibilityEnablerTest, PlaysProgressSound) {
121 EXPECT_TRUE(enabler_->IsInNoFingersDownForTesting());
122 generator_->set_current_location(gfx::Point(11, 12));
123 generator_->PressTouchId(1);
124
125 generator_->set_current_location(gfx::Point(22, 34));
126 generator_->PressTouchId(2);
127
128 EXPECT_TRUE(enabler_->IsInTwoFingersDownForTesting());
129 EXPECT_EQ(0U, delegate_.feedback_progress_sound_count());
130
131 enabler_->TriggerOnTimerForTesting();
132 EXPECT_EQ(0U, delegate_.feedback_progress_sound_count());
133
134 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(3000));
135 enabler_->TriggerOnTimerForTesting();
136 EXPECT_EQ(1U, delegate_.feedback_progress_sound_count());
137}
138
139TEST_F(TouchAccessibilityEnablerTest, TogglesSpokenFeedback) {
140 EXPECT_TRUE(enabler_->IsInNoFingersDownForTesting());
141 generator_->set_current_location(gfx::Point(11, 12));
142 generator_->PressTouchId(1);
143
144 generator_->set_current_location(gfx::Point(22, 34));
145 generator_->PressTouchId(2);
146
147 EXPECT_TRUE(enabler_->IsInTwoFingersDownForTesting());
148 EXPECT_FALSE(delegate_.toggle_spoken_feedback());
dmazzonidf9a1e922017-04-13 05:10:44149 EXPECT_TRUE(delegate_.started());
150 EXPECT_FALSE(delegate_.stopped());
dmazzoni16d2dec2016-12-19 23:27:57151
152 enabler_->TriggerOnTimerForTesting();
153 EXPECT_FALSE(delegate_.toggle_spoken_feedback());
154
155 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(5000));
156 enabler_->TriggerOnTimerForTesting();
157 EXPECT_TRUE(delegate_.toggle_spoken_feedback());
dmazzonidf9a1e922017-04-13 05:10:44158 EXPECT_TRUE(delegate_.started());
159 EXPECT_FALSE(delegate_.stopped());
dmazzoni16d2dec2016-12-19 23:27:57160}
161
162TEST_F(TouchAccessibilityEnablerTest, ThreeFingersCancelsDetection) {
163 EXPECT_TRUE(enabler_->IsInNoFingersDownForTesting());
164 generator_->set_current_location(gfx::Point(11, 12));
165 generator_->PressTouchId(1);
166
167 generator_->set_current_location(gfx::Point(22, 34));
168 generator_->PressTouchId(2);
169
170 EXPECT_TRUE(enabler_->IsInTwoFingersDownForTesting());
dmazzonidf9a1e922017-04-13 05:10:44171 EXPECT_TRUE(delegate_.started());
172 EXPECT_FALSE(delegate_.stopped());
dmazzoni16d2dec2016-12-19 23:27:57173
174 generator_->set_current_location(gfx::Point(33, 56));
175 generator_->PressTouchId(3);
176
177 EXPECT_TRUE(enabler_->IsInWaitForNoFingersForTesting());
dmazzonidf9a1e922017-04-13 05:10:44178 EXPECT_TRUE(delegate_.started());
179 EXPECT_TRUE(delegate_.stopped());
dmazzoni16d2dec2016-12-19 23:27:57180}
181
182TEST_F(TouchAccessibilityEnablerTest, MovingFingerPastSlopCancelsDetection) {
183 EXPECT_TRUE(enabler_->IsInNoFingersDownForTesting());
184 generator_->set_current_location(gfx::Point(11, 12));
185 generator_->PressTouch();
186
187 int slop = gesture_detector_config_.double_tap_slop;
188 int half_slop = slop / 2;
189
190 generator_->MoveTouch(gfx::Point(11 + half_slop, 12));
191 EXPECT_TRUE(enabler_->IsInOneFingerDownForTesting());
192
193 generator_->MoveTouch(gfx::Point(11 + slop + 1, 12));
194 EXPECT_TRUE(enabler_->IsInWaitForNoFingersForTesting());
195}
196
197} // namespace ui