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

Side by Side Diff: ui/chromeos/touch_exploration_controller_unittest.cc

Issue 296403011: Support double-tap to click in touch accessibility controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update browser test for touch exploration too Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « ui/chromeos/touch_exploration_controller.cc ('k') | ui/ui_unittests.gyp » ('j') | 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/time/time.h" 8 #include "base/time/time.h"
8 #include "ui/aura/client/cursor_client.h" 9 #include "ui/aura/client/cursor_client.h"
9 #include "ui/aura/test/aura_test_base.h" 10 #include "ui/aura/test/aura_test_base.h"
10 #include "ui/aura/test/event_generator.h" 11 #include "ui/aura/test/event_generator.h"
11 #include "ui/aura/test/test_cursor_client.h" 12 #include "ui/aura/test/test_cursor_client.h"
12 #include "ui/aura/window.h" 13 #include "ui/aura/window.h"
13 #include "ui/events/event.h" 14 #include "ui/events/event.h"
14 #include "ui/events/event_utils.h" 15 #include "ui/events/event_utils.h"
15 #include "ui/gfx/geometry/point.h" 16 #include "ui/gfx/geometry/point.h"
16 #include "ui/gl/gl_implementation.h" 17 #include "ui/gl/gl_implementation.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 private: 54 private:
54 ScopedVector<ui::LocatedEvent> events_; 55 ScopedVector<ui::LocatedEvent> events_;
55 56
56 DISALLOW_COPY_AND_ASSIGN(EventCapturer); 57 DISALLOW_COPY_AND_ASSIGN(EventCapturer);
57 }; 58 };
58 59
59 } // namespace 60 } // namespace
60 61
61 class TouchExplorationTest : public aura::test::AuraTestBase { 62 class TouchExplorationTest : public aura::test::AuraTestBase {
62 public: 63 public:
63 TouchExplorationTest() {} 64 TouchExplorationTest()
65 : simulated_clock_(new base::SimpleTestTickClock()) {}
64 virtual ~TouchExplorationTest() {} 66 virtual ~TouchExplorationTest() {}
65 67
66 virtual void SetUp() OVERRIDE { 68 virtual void SetUp() OVERRIDE {
67 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) 69 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone)
68 gfx::GLSurface::InitializeOneOffForTests(); 70 gfx::GLSurface::InitializeOneOffForTests();
69 aura::test::AuraTestBase::SetUp(); 71 aura::test::AuraTestBase::SetUp();
70 cursor_client_.reset(new aura::test::TestCursorClient(root_window())); 72 cursor_client_.reset(new aura::test::TestCursorClient(root_window()));
71 root_window()->AddPreTargetHandler(&event_capturer_); 73 root_window()->AddPreTargetHandler(&event_capturer_);
74 generator_.reset(new aura::test::EventGenerator(root_window()));
75 // The generator takes ownership of the clock.
76 generator_->SetTickClock(scoped_ptr<base::TickClock>(simulated_clock_));
77 cursor_client()->ShowCursor();
78 cursor_client()->DisableMouseEvents();
72 } 79 }
73 80
74 virtual void TearDown() OVERRIDE { 81 virtual void TearDown() OVERRIDE {
75 root_window()->RemovePreTargetHandler(&event_capturer_); 82 root_window()->RemovePreTargetHandler(&event_capturer_);
76 SwitchTouchExplorationMode(false); 83 SwitchTouchExplorationMode(false);
77 cursor_client_.reset(); 84 cursor_client_.reset();
78 aura::test::AuraTestBase::TearDown(); 85 aura::test::AuraTestBase::TearDown();
79 } 86 }
80 87
88 protected:
89 aura::client::CursorClient* cursor_client() { return cursor_client_.get(); }
90
81 const ScopedVector<ui::LocatedEvent>& GetCapturedEvents() { 91 const ScopedVector<ui::LocatedEvent>& GetCapturedEvents() {
82 return event_capturer_.captured_events(); 92 return event_capturer_.captured_events();
83 } 93 }
84 94
95 std::vector<ui::LocatedEvent*> GetCapturedEventsOfType(int type) {
96 const ScopedVector<ui::LocatedEvent>& all_events = GetCapturedEvents();
97 std::vector<ui::LocatedEvent*> events;
98 for (size_t i = 0; i < all_events.size(); ++i) {
99 if (type == all_events[i]->type())
100 events.push_back(all_events[i]);
101 }
102 return events;
103 }
104
85 void ClearCapturedEvents() { 105 void ClearCapturedEvents() {
86 event_capturer_.Reset(); 106 event_capturer_.Reset();
87 } 107 }
88 108
89 protected: 109 void AdvanceSimulatedTimePastTapDelay() {
90 aura::client::CursorClient* cursor_client() { return cursor_client_.get(); } 110 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
111 touch_exploration_controller_->CallTapTimerNowForTesting();
112 }
91 113
92 void SwitchTouchExplorationMode(bool on) { 114 void SwitchTouchExplorationMode(bool on) {
93 if (!on && touch_exploration_controller_.get()) 115 if (!on && touch_exploration_controller_.get()) {
94 touch_exploration_controller_.reset(); 116 touch_exploration_controller_.reset();
95 else if (on && !touch_exploration_controller_.get()) 117 } else if (on && !touch_exploration_controller_.get()) {
96 touch_exploration_controller_.reset( 118 touch_exploration_controller_.reset(
97 new ui::TouchExplorationController(root_window())); 119 new ui::TouchExplorationController(root_window()));
120 touch_exploration_controller_->SetEventHandlerForTesting(
121 &event_capturer_);
122 cursor_client()->ShowCursor();
123 cursor_client()->DisableMouseEvents();
124 }
98 } 125 }
99 126
100 bool IsInTouchToMouseMode() { 127 bool IsInTouchToMouseMode() {
101 aura::client::CursorClient* cursor_client = 128 aura::client::CursorClient* cursor_client =
102 aura::client::GetCursorClient(root_window()); 129 aura::client::GetCursorClient(root_window());
103 return cursor_client && 130 return cursor_client &&
104 cursor_client->IsMouseEventsEnabled() && 131 cursor_client->IsMouseEventsEnabled() &&
105 !cursor_client->IsCursorVisible(); 132 !cursor_client->IsCursorVisible();
106 } 133 }
107 134
135 bool IsInNoFingersDownState() {
136 return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
137 }
138
139 base::TimeDelta Now() {
140 // This is the same as what EventTimeForNow() does, but here we do it
141 // with our simulated clock.
142 return base::TimeDelta::FromInternalValue(
143 simulated_clock_->NowTicks().ToInternalValue());
144 }
145
146 scoped_ptr<aura::test::EventGenerator> generator_;
147 ui::GestureDetector::Config gesture_detector_config_;
148 // Owned by |generator_|.
149 base::SimpleTestTickClock* simulated_clock_;
150
108 private: 151 private:
109 EventCapturer event_capturer_; 152 EventCapturer event_capturer_;
110 scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_; 153 scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_;
111 scoped_ptr<aura::test::TestCursorClient> cursor_client_; 154 scoped_ptr<aura::test::TestCursorClient> cursor_client_;
112 155
113 DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest); 156 DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
114 }; 157 };
115 158
116 // Executes a number of assertions to confirm that |e1| and |e2| are touch 159 // Executes a number of assertions to confirm that |e1| and |e2| are touch
117 // events and are equal to each other. 160 // events and are equal to each other.
(...skipping 25 matching lines...) Expand all
143 #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \ 186 #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \
144 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2)) 187 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2))
145 188
146 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \ 189 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \
147 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2)) 190 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2))
148 191
149 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit 192 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit
150 // events when running these tests as part of ui_unittests. We do get them when 193 // events when running these tests as part of ui_unittests. We do get them when
151 // the tests are run as part of ash unit tests. 194 // the tests are run as part of ash unit tests.
152 195
153 // Simple test to confirm one-finger touches are transformed into mouse moves. 196 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) {
154 TEST_F(TouchExplorationTest, OneFingerTouch) {
155 SwitchTouchExplorationMode(true); 197 SwitchTouchExplorationMode(true);
156 cursor_client()->ShowCursor(); 198 EXPECT_FALSE(IsInTouchToMouseMode());
157 cursor_client()->DisableMouseEvents(); 199 generator_->PressTouch();
158 aura::test::EventGenerator generator(root_window()); 200 AdvanceSimulatedTimePastTapDelay();
159 gfx::Point location_start = generator.current_location();
160 gfx::Point location_end(11, 12);
161 generator.PressTouch();
162 EXPECT_TRUE(IsInTouchToMouseMode()); 201 EXPECT_TRUE(IsInTouchToMouseMode());
163 generator.MoveTouch(location_end); 202 }
164 // Confirm the actual mouse moves are unaffected. 203
204 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) {
205 int slop = gesture_detector_config_.touch_slop;
206 int half_slop = slop / 2;
207
208 SwitchTouchExplorationMode(true);
209 EXPECT_FALSE(IsInTouchToMouseMode());
210 generator_->set_current_location(gfx::Point(11, 12));
211 generator_->PressTouch();
212 generator_->MoveTouch(gfx::Point(11 + half_slop, 12));
213 EXPECT_FALSE(IsInTouchToMouseMode());
214 generator_->MoveTouch(gfx::Point(11, 12 + half_slop));
215 EXPECT_FALSE(IsInTouchToMouseMode());
216 generator_->MoveTouch(gfx::Point(11 + slop + 1, 12));
217 EXPECT_TRUE(IsInTouchToMouseMode());
218 }
219
220 TEST_F(TouchExplorationTest, OneFingerTap) {
221 SwitchTouchExplorationMode(true);
222 gfx::Point location(11, 12);
223 generator_->set_current_location(location);
224 generator_->PressTouch();
225 generator_->ReleaseTouch();
226 AdvanceSimulatedTimePastTapDelay();
227
228 std::vector<ui::LocatedEvent*> events =
229 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
230 ASSERT_EQ(1U, events.size());
231
232 EXPECT_EQ(location, events[0]->location());
233 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
234 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
235 EXPECT_TRUE(IsInNoFingersDownState());
236 }
237
238 TEST_F(TouchExplorationTest, ActualMouseMovesUnaffected) {
239 SwitchTouchExplorationMode(true);
240
241 gfx::Point location_start(11, 12);
242 gfx::Point location_end(13, 14);
243 generator_->set_current_location(location_start);
244 generator_->PressTouch();
245 AdvanceSimulatedTimePastTapDelay();
246 generator_->MoveTouch(location_end);
247
248 gfx::Point location_real_mouse_move(15, 16);
165 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, 249 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
166 gfx::Point(13, 14), 250 location_real_mouse_move,
167 gfx::Point(13, 14), 251 location_real_mouse_move,
168 0, 252 0,
169 0); 253 0);
170 generator.Dispatch(&mouse_move); 254 generator_->Dispatch(&mouse_move);
171 generator.ReleaseTouch(); 255 generator_->ReleaseTouch();
172 256
173 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 257 std::vector<ui::LocatedEvent*> events =
174 ScopedVector<ui::LocatedEvent>::const_iterator it; 258 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
175 // TODO(mfomitchev): mouse enter/exit events 259 ASSERT_EQ(4U, events.size());
176 int num_mouse_moves = 0; 260
177 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 261 EXPECT_EQ(location_start, events[0]->location());
178 int type = (*it)->type(); 262 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
179 // Ignore enter and exit mouse events synthesized when the mouse cursor is 263 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
180 // shown or hidden. 264
181 if (type == ui::ET_MOUSE_ENTERED || type == ui::ET_MOUSE_EXITED) 265 EXPECT_EQ(location_end, events[1]->location());
182 continue; 266 EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
183 EXPECT_EQ(ui::ET_MOUSE_MOVED, (*it)->type()); 267 EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
184 if (num_mouse_moves == 0) 268
185 EXPECT_EQ(location_start, (*it)->location()); 269 // The real mouse move goes through.
186 if (num_mouse_moves == 1 || num_mouse_moves == 3) 270 EXPECT_EQ(location_real_mouse_move, events[2]->location());
187 EXPECT_EQ(location_end, (*it)->location()); 271 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(events[2], &mouse_move);
188 if (num_mouse_moves == 2) 272 EXPECT_FALSE(events[2]->flags() & ui::EF_IS_SYNTHESIZED);
189 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move); 273 EXPECT_FALSE(events[2]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
190 if (num_mouse_moves != 2) { 274
191 EXPECT_TRUE((*it)->flags() & ui::EF_IS_SYNTHESIZED); 275 // The touch release gets written as a mouse move.
192 EXPECT_TRUE((*it)->flags() & ui::EF_TOUCH_ACCESSIBILITY); 276 EXPECT_EQ(location_end, events[3]->location());
193 } 277 EXPECT_TRUE(events[3]->flags() & ui::EF_IS_SYNTHESIZED);
194 num_mouse_moves++; 278 EXPECT_TRUE(events[3]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
195 } 279 EXPECT_TRUE(IsInNoFingersDownState());
196 EXPECT_EQ(4, num_mouse_moves);
197 } 280 }
198 281
199 // Turn the touch exploration mode on in the middle of the touch gesture. 282 // Turn the touch exploration mode on in the middle of the touch gesture.
200 // Confirm that events from the finger which was touching when the mode was 283 // Confirm that events from the finger which was touching when the mode was
201 // turned on don't get rewritten. 284 // turned on don't get rewritten.
202 TEST_F(TouchExplorationTest, TurnOnMidTouch) { 285 TEST_F(TouchExplorationTest, TurnOnMidTouch) {
203 SwitchTouchExplorationMode(false); 286 SwitchTouchExplorationMode(false);
204 cursor_client()->ShowCursor(); 287 generator_->PressTouchId(1);
205 cursor_client()->DisableMouseEvents();
206 aura::test::EventGenerator generator(root_window());
207 generator.PressTouchId(1);
208 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 288 EXPECT_TRUE(cursor_client()->IsCursorVisible());
209 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
210 ClearCapturedEvents(); 289 ClearCapturedEvents();
211 290
212 // Enable touch exploration mode while the first finger is touching the 291 // Enable touch exploration mode while the first finger is touching the
213 // screen. Ensure that subsequent events from that first finger are not 292 // screen. Ensure that subsequent events from that first finger are not
214 // affected by the touch exploration mode, while the touch events from another 293 // affected by the touch exploration mode, while the touch events from another
215 // finger get rewritten. 294 // finger get rewritten.
216 SwitchTouchExplorationMode(true); 295 SwitchTouchExplorationMode(true);
217 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED, 296 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED,
218 gfx::Point(11, 12), 297 gfx::Point(11, 12),
219 1, 298 1,
220 ui::EventTimeForNow()); 299 Now());
221 generator.Dispatch(&touch_move); 300 generator_->Dispatch(&touch_move);
222 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 301 EXPECT_TRUE(cursor_client()->IsCursorVisible());
223 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); 302 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
224 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 303 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
225 ASSERT_EQ(1u, captured_events.size()); 304 ASSERT_EQ(1u, captured_events.size());
226 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move); 305 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
227 ClearCapturedEvents(); 306 ClearCapturedEvents();
228 307
229 // The press from the second finger should get rewritten. 308 // The press from the second finger should get rewritten.
230 generator.PressTouchId(2); 309 generator_->PressTouchId(2);
310 AdvanceSimulatedTimePastTapDelay();
231 EXPECT_TRUE(IsInTouchToMouseMode()); 311 EXPECT_TRUE(IsInTouchToMouseMode());
232 // TODO(mfomitchev): mouse enter/exit events
233 ScopedVector<ui::LocatedEvent>::const_iterator it; 312 ScopedVector<ui::LocatedEvent>::const_iterator it;
234 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 313 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
235 if ((*it)->type() == ui::ET_MOUSE_MOVED) 314 if ((*it)->type() == ui::ET_MOUSE_MOVED)
236 break; 315 break;
237 } 316 }
238 EXPECT_NE(captured_events.end(), it); 317 EXPECT_NE(captured_events.end(), it);
239 ClearCapturedEvents(); 318 ClearCapturedEvents();
240 319
241 // The release of the first finger shouldn't be affected. 320 // The release of the first finger shouldn't be affected.
242 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, 321 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED,
243 gfx::Point(11, 12), 322 gfx::Point(11, 12),
244 1, 323 1,
245 ui::EventTimeForNow()); 324 Now());
246 generator.Dispatch(&touch_release); 325 generator_->Dispatch(&touch_release);
247 ASSERT_EQ(1u, captured_events.size()); 326 ASSERT_EQ(1u, captured_events.size());
248 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release); 327 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
249 ClearCapturedEvents(); 328 ClearCapturedEvents();
250 329
251 // The move and release from the second finger should get rewritten. 330 // The move and release from the second finger should get rewritten.
252 generator.MoveTouchId(gfx::Point(13, 14), 2); 331 generator_->MoveTouchId(gfx::Point(13, 14), 2);
253 generator.ReleaseTouchId(2); 332 generator_->ReleaseTouchId(2);
254 ASSERT_EQ(2u, captured_events.size()); 333 ASSERT_EQ(2u, captured_events.size());
255 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); 334 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
256 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); 335 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
336 EXPECT_TRUE(IsInNoFingersDownState());
257 } 337 }
258 338
259 TEST_F(TouchExplorationTest, TwoFingerTouch) { 339 TEST_F(TouchExplorationTest, TwoFingerTouch) {
260 SwitchTouchExplorationMode(true); 340 SwitchTouchExplorationMode(true);
261 aura::test::EventGenerator generator(root_window()); 341 generator_->PressTouchId(1);
262 generator.PressTouchId(1);
263 ClearCapturedEvents(); 342 ClearCapturedEvents();
264 343
265 // Confirm events from the second finger go through as is. 344 // Confirm events from the second finger go through as is.
266 cursor_client()->ShowCursor(); 345 ui::TouchEvent touch_press(
267 cursor_client()->DisableMouseEvents(); 346 ui::ET_TOUCH_PRESSED,
268 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, 347 gfx::Point(10, 11),
269 gfx::Point(10, 11), 348 2,
270 2, 349 Now());
271 ui::EventTimeForNow()); 350 generator_->Dispatch(&touch_press);
272 generator.Dispatch(&touch_press);
273 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 351 EXPECT_TRUE(cursor_client()->IsCursorVisible());
274 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); 352 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
275 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 353 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
276 // TODO(mfomitchev): mouse enter/exit events 354 // TODO(mfomitchev): mouse enter/exit events
277 // There will be a ET_MOUSE_EXITED event synthesized when the mouse cursor is 355 // There will be a ET_MOUSE_EXITED event synthesized when the mouse cursor is
278 // hidden - ignore it. 356 // hidden - ignore it.
279 ScopedVector<ui::LocatedEvent>::const_iterator it; 357 ScopedVector<ui::LocatedEvent>::const_iterator it;
280 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 358 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
281 if ((*it)->type() == ui::ET_TOUCH_PRESSED) { 359 if ((*it)->type() == ui::ET_TOUCH_PRESSED) {
282 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(*it, &touch_press); 360 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(*it, &touch_press);
283 break; 361 break;
284 } 362 }
285 } 363 }
286 EXPECT_NE(captured_events.end(), it); 364 EXPECT_NE(captured_events.end(), it);
287 ClearCapturedEvents(); 365 ClearCapturedEvents();
288 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED, 366 ui::TouchEvent touch_move(
289 gfx::Point(20, 21), 367 ui::ET_TOUCH_MOVED,
290 2, 368 gfx::Point(20, 21),
291 ui::EventTimeForNow()); 369 2,
292 generator.Dispatch(&touch_move); 370 Now());
371 generator_->Dispatch(&touch_move);
293 ASSERT_EQ(1u, captured_events.size()); 372 ASSERT_EQ(1u, captured_events.size());
294 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move); 373 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
295 ClearCapturedEvents(); 374 ClearCapturedEvents();
296 375
297 // Confirm mouse moves go through unaffected. 376 // Confirm mouse moves go through unaffected.
298 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, 377 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
299 gfx::Point(13, 14), 378 gfx::Point(13, 14),
300 gfx::Point(13, 14), 379 gfx::Point(13, 14),
301 0, 380 0,
302 0); 381 0);
303 generator.Dispatch(&mouse_move); 382 generator_->Dispatch(&mouse_move);
304 // TODO(mfomitchev): mouse enter/exit events 383 // TODO(mfomitchev): mouse enter/exit events
305 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED 384 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED
306 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 385 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
307 if ((*it)->type() == ui::ET_MOUSE_MOVED) { 386 if ((*it)->type() == ui::ET_MOUSE_MOVED) {
308 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move); 387 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move);
309 break; 388 break;
310 } 389 }
311 } 390 }
312 EXPECT_NE(captured_events.end(), it); 391 EXPECT_NE(captured_events.end(), it);
313 ClearCapturedEvents(); 392 ClearCapturedEvents();
314 393
315 // Have some other fingers touch/move/release
316 generator.PressTouchId(3);
317 generator.PressTouchId(4);
318 generator.MoveTouchId(gfx::Point(30, 31), 3);
319 generator.ReleaseTouchId(3);
320 generator.ReleaseTouchId(4);
321 ClearCapturedEvents();
322
323 // Events from the first finger should not go through while the second finger 394 // Events from the first finger should not go through while the second finger
324 // is touching. 395 // is touching.
325 gfx::Point touch1_location = gfx::Point(15, 16); 396 gfx::Point touch1_location = gfx::Point(15, 16);
326 generator.MoveTouchId(touch1_location, 1); 397 generator_->MoveTouchId(touch1_location, 1);
327 EXPECT_EQ(0u, GetCapturedEvents().size()); 398 EXPECT_EQ(0u, GetCapturedEvents().size());
328 399
329 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 400 EXPECT_TRUE(cursor_client()->IsCursorVisible());
330 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); 401 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
331 402
332 // A release of the second finger should go through, plus there should be a 403 // A release of the second finger should be rewritten as a mouse move
333 // mouse move at |touch1_location| generated. 404 // of that finger to the |touch1_location| and we stay in passthrough
334 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, 405 // mode.
335 gfx::Point(25, 26), 406 ui::TouchEvent touch_release(
336 2, 407 ui::ET_TOUCH_RELEASED,
337 ui::EventTimeForNow()); 408 gfx::Point(25, 26),
338 generator.Dispatch(&touch_release); 409 2,
339 EXPECT_TRUE(IsInTouchToMouseMode()); 410 Now());
340 ASSERT_GE(captured_events.size(), 2u); 411 generator_->Dispatch(&touch_release);
341 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release); 412 EXPECT_FALSE(IsInTouchToMouseMode());
342 // TODO(mfomitchev): mouse enter/exit events 413 ASSERT_EQ(captured_events.size(), 1u);
343 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED 414 EXPECT_EQ(touch1_location, captured_events[0]->location());
344 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
345 if ((*it)->type() == ui::ET_MOUSE_MOVED) {
346 EXPECT_EQ(touch1_location, (*it)->location());
347 break;
348 }
349 }
350 EXPECT_NE(captured_events.end(), it);
351 } 415 }
352 416
353 TEST_F(TouchExplorationTest, MultiFingerTouch) { 417 TEST_F(TouchExplorationTest, MultiFingerTouch) {
354 SwitchTouchExplorationMode(true); 418 SwitchTouchExplorationMode(true);
355 aura::test::EventGenerator generator(root_window()); 419 generator_->PressTouchId(1);
356 generator.PressTouchId(1); 420 generator_->PressTouchId(2);
357 generator.PressTouchId(2);
358 ClearCapturedEvents(); 421 ClearCapturedEvents();
359 422
360 // Confirm events from other fingers go through as is. 423 // Confirm events from other fingers go through as is.
361 ui::TouchEvent touch3_press(ui::ET_TOUCH_PRESSED, 424 ui::TouchEvent touch3_press(ui::ET_TOUCH_PRESSED,
362 gfx::Point(10, 11), 425 gfx::Point(10, 11),
363 3, 426 3,
364 ui::EventTimeForNow()); 427 Now());
365 ui::TouchEvent touch3_move1(ui::ET_TOUCH_MOVED, 428 ui::TouchEvent touch3_move1(ui::ET_TOUCH_MOVED,
366 gfx::Point(12, 13), 429 gfx::Point(12, 13),
367 3, 430 3,
368 ui::EventTimeForNow()); 431 Now());
369 ui::TouchEvent touch4_press(ui::ET_TOUCH_PRESSED, 432 ui::TouchEvent touch4_press(ui::ET_TOUCH_PRESSED,
370 gfx::Point(20, 21), 433 gfx::Point(20, 21),
371 4, 434 4,
372 ui::EventTimeForNow()); 435 Now());
373 ui::TouchEvent touch3_move2(ui::ET_TOUCH_MOVED, 436 ui::TouchEvent touch3_move2(ui::ET_TOUCH_MOVED,
374 gfx::Point(14, 15), 437 gfx::Point(14, 15),
375 3, 438 3,
376 ui::EventTimeForNow()); 439 Now());
377 ui::TouchEvent touch4_move(ui::ET_TOUCH_MOVED, 440 ui::TouchEvent touch4_move(ui::ET_TOUCH_MOVED,
378 gfx::Point(22, 23), 441 gfx::Point(22, 23),
379 4, 442 4,
380 ui::EventTimeForNow()); 443 Now());
381 ui::TouchEvent touch3_release(ui::ET_TOUCH_RELEASED, 444 ui::TouchEvent touch3_release(ui::ET_TOUCH_RELEASED,
382 gfx::Point(14, 15), 445 gfx::Point(14, 15),
383 3, 446 3,
384 ui::EventTimeForNow()); 447 Now());
385 ui::TouchEvent touch4_release(ui::ET_TOUCH_RELEASED, 448 ui::TouchEvent touch4_release(ui::ET_TOUCH_RELEASED,
386 gfx::Point(22, 23), 449 gfx::Point(22, 23),
387 4, 450 4,
388 ui::EventTimeForNow()); 451 Now());
389 generator.Dispatch(&touch3_press); 452 generator_->Dispatch(&touch3_press);
390 generator.Dispatch(&touch3_move1); 453 generator_->Dispatch(&touch3_move1);
391 generator.Dispatch(&touch4_press); 454 generator_->Dispatch(&touch4_press);
392 generator.Dispatch(&touch3_move2); 455 generator_->Dispatch(&touch3_move2);
393 generator.Dispatch(&touch4_move); 456 generator_->Dispatch(&touch4_move);
394 generator.Dispatch(&touch3_release); 457 generator_->Dispatch(&touch3_release);
395 generator.Dispatch(&touch4_release); 458 generator_->Dispatch(&touch4_release);
396 459
397 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 460 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
398 ASSERT_EQ(7u, captured_events.size()); 461 ASSERT_EQ(7u, captured_events.size());
399 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch3_press); 462 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch3_press);
400 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[1], &touch3_move1); 463 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[1], &touch3_move1);
401 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[2], &touch4_press); 464 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[2], &touch4_press);
402 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[3], &touch3_move2); 465 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[3], &touch3_move2);
403 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[4], &touch4_move); 466 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[4], &touch4_move);
404 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[5], &touch3_release); 467
468 // The release of finger 3 is rewritten as a move to the former location
469 // of finger 1.
470 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[5]->type());
405 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[6], &touch4_release); 471 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[6], &touch4_release);
406 } 472 }
407 473
408 // Test the case when there are multiple fingers on the screen and the first 474 // Test the case when there are multiple fingers on the screen and the first
409 // finger is released. This should be rewritten as a release of the second 475 // finger is released. This should be ignored, but then the second finger
410 // finger. Additionally, if the second finger is the only finger left touching, 476 // release should be passed through.
411 // we should enter a mouse move mode, and a mouse move event should be
412 // dispatched.
413 TEST_F(TouchExplorationTest, FirstFingerLifted) { 477 TEST_F(TouchExplorationTest, FirstFingerLifted) {
414 SwitchTouchExplorationMode(true); 478 SwitchTouchExplorationMode(true);
415 aura::test::EventGenerator generator(root_window()); 479 generator_->PressTouchId(1);
416 generator.PressTouchId(1); 480 generator_->PressTouchId(2);
417 generator.PressTouchId(2);
418 gfx::Point touch2_location(10, 11); 481 gfx::Point touch2_location(10, 11);
419 generator.MoveTouchId(touch2_location, 2); 482 generator_->MoveTouchId(touch2_location, 2);
420 generator.PressTouchId(3); 483 generator_->PressTouchId(3);
421 gfx::Point touch3_location(20, 21); 484 gfx::Point touch3_location(20, 21);
422 generator.MoveTouchId(touch3_location, 3); 485 generator_->MoveTouchId(touch3_location, 3);
423 ClearCapturedEvents(); 486 ClearCapturedEvents();
424 487
425 // Release of finger 1 should be rewritten as a release of finger 2. 488 // Release of finger 1 should be ignored.
426 generator.ReleaseTouchId(1); 489 generator_->ReleaseTouchId(1);
490 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
491 ASSERT_EQ(0u, captured_events.size());
492
493 // Move of finger 2 should be passed through.
494 gfx::Point touch2_new_location(20, 11);
495 generator_->MoveTouchId(touch2_new_location, 2);
496 ASSERT_EQ(1u, captured_events.size());
497 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
498 EXPECT_EQ(touch2_new_location, captured_events[0]->location());
499 ClearCapturedEvents();
500
501 // Release of finger 2 should be passed through.
502 ui::TouchEvent touch2_release(
503 ui::ET_TOUCH_RELEASED,
504 gfx::Point(14, 15),
505 2,
506 Now());
507 generator_->Dispatch(&touch2_release);
508 ASSERT_EQ(1u, captured_events.size());
509 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch2_release);
510 }
511
512 // Test the case when there are multiple fingers on the screen and the
513 // second finger is released. This should be rewritten as a move to the
514 // location of the first finger.
515 TEST_F(TouchExplorationTest, SecondFingerLifted) {
516 SwitchTouchExplorationMode(true);
517 gfx::Point touch1_location(0, 11);
518 generator_->set_current_location(touch1_location);
519 generator_->PressTouchId(1);
520 generator_->PressTouchId(2);
521 gfx::Point touch2_location(10, 11);
522 generator_->MoveTouchId(touch2_location, 2);
523 generator_->PressTouchId(3);
524 gfx::Point touch3_location(20, 21);
525 generator_->MoveTouchId(touch3_location, 3);
526 ClearCapturedEvents();
527
528 // Release of finger 2 should be rewritten as a move to the location
529 // of the first finger.
530 generator_->ReleaseTouchId(2);
427 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 531 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
428 ASSERT_EQ(1u, captured_events.size()); 532 ASSERT_EQ(1u, captured_events.size());
429 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type()); 533 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
430 ui::TouchEvent* touch_event = 534 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
431 static_cast<ui::TouchEvent*>(captured_events[0]); 535 EXPECT_EQ(touch1_location, captured_events[0]->location());
432 EXPECT_EQ(2, touch_event->touch_id());
433 EXPECT_EQ(touch2_location, touch_event->location());
434 ClearCapturedEvents(); 536 ClearCapturedEvents();
435 537
436 // Release of finger 2 should be rewritten as a release of finger 3, plus 538 // Move of finger 1 should be rewritten as a move of finger 2.
437 // we should enter the mouse move mode and a mouse move event should be 539 gfx::Point touch1_new_location(0, 41);
438 // dispatched. 540 generator_->MoveTouchId(touch1_new_location, 1);
439 cursor_client()->ShowCursor(); 541 ASSERT_EQ(1u, captured_events.size());
440 cursor_client()->DisableMouseEvents(); 542 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
441 generator.ReleaseTouchId(2); 543 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
442 EXPECT_TRUE(IsInTouchToMouseMode()); 544 EXPECT_EQ(touch1_new_location, captured_events[0]->location());
443 ASSERT_GE(2u, captured_events.size()); 545 ClearCapturedEvents();
546
547 // Release of finger 1 should be rewritten as release of finger 2.
548 gfx::Point touch1_final_location(0, 41);
549 ui::TouchEvent touch1_release(
550 ui::ET_TOUCH_RELEASED,
551 touch1_final_location,
552 1,
553 Now());
554 generator_->Dispatch(&touch1_release);
555 ASSERT_EQ(1u, captured_events.size());
444 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type()); 556 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type());
445 touch_event = static_cast<ui::TouchEvent*>(captured_events[0]); 557 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
446 EXPECT_EQ(3, touch_event->touch_id()); 558 EXPECT_EQ(touch1_final_location, captured_events[0]->location());
447 EXPECT_EQ(touch3_location, touch_event->location()); 559 }
448 // TODO(mfomitchev): mouse enter/exit events 560
449 ScopedVector<ui::LocatedEvent>::const_iterator it; 561 // If an event is received after the double-tap timeout has elapsed, but
450 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 562 // before the timer has fired, a mouse move should still be generated.
451 if ((*it)->type() == ui::ET_MOUSE_MOVED) { 563 TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) {
452 EXPECT_EQ(touch3_location, (*it)->location()); 564 SwitchTouchExplorationMode(true);
453 break; 565
454 } 566 // Send a press, then add another finger after the double-tap timeout.
455 } 567 generator_->PressTouchId(1);
456 EXPECT_NE(captured_events.end(), it); 568 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
569 generator_->PressTouchId(2);
570 std::vector<ui::LocatedEvent*> events =
571 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
572 ASSERT_EQ(1U, events.size());
573 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
574 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
575
576 generator_->ReleaseTouchId(2);
577 generator_->ReleaseTouchId(1);
578 EXPECT_TRUE(IsInNoFingersDownState());
579 }
580
581 // If a new tap is received after the double-tap timeout has elapsed from
582 // a previous tap, but before the timer has fired, a mouse move should
583 // still be generated from the old tap.
584 TEST_F(TouchExplorationTest, TimerFiresLateAfterTap) {
585 SwitchTouchExplorationMode(true);
586
587 // Send a tap at location1.
588 gfx::Point location0(11, 12);
589 generator_->set_current_location(location0);
590 generator_->PressTouch();
591 generator_->ReleaseTouch();
592
593 // Send a tap at location2, after the double-tap timeout, but before the
594 // timer fires.
595 gfx::Point location1(33, 34);
596 generator_->set_current_location(location1);
597 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(301));
598 generator_->PressTouch();
599 generator_->ReleaseTouch();
600 AdvanceSimulatedTimePastTapDelay();
601
602 std::vector<ui::LocatedEvent*> events =
603 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
604 ASSERT_EQ(2U, events.size());
605 EXPECT_EQ(location0, events[0]->location());
606 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
607 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
608 EXPECT_EQ(location1, events[1]->location());
609 EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
610 EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
611 EXPECT_TRUE(IsInNoFingersDownState());
612 }
613
614 // Double-tapping should send a touch press and release through to the location
615 // of the last successful touch exploration.
616 TEST_F(TouchExplorationTest, DoubleTap) {
617 SwitchTouchExplorationMode(true);
618
619 // Tap at one location, and get a mouse move event.
620 gfx::Point tap_location(11, 12);
621 generator_->set_current_location(tap_location);
622 generator_->PressTouch();
623 generator_->ReleaseTouch();
624 AdvanceSimulatedTimePastTapDelay();
625
626 std::vector<ui::LocatedEvent*> events =
627 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
628 ASSERT_EQ(1U, events.size());
629
630 EXPECT_EQ(tap_location, events[0]->location());
631 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
632 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
633 ClearCapturedEvents();
634
635 // Now double-tap at a different location. This should result in
636 // a single touch press and release at the location of the tap,
637 // not at the location of the double-tap.
638 gfx::Point double_tap_location(33, 34);
639 generator_->set_current_location(double_tap_location);
640 generator_->PressTouch();
641 generator_->ReleaseTouch();
642 generator_->PressTouch();
643 generator_->ReleaseTouch();
644
645 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
646 ASSERT_EQ(2U, captured_events.size());
647 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
648 EXPECT_EQ(tap_location, captured_events[0]->location());
649 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
650 EXPECT_EQ(tap_location, captured_events[1]->location());
651 EXPECT_TRUE(IsInNoFingersDownState());
457 } 652 }
458 653
459 } // namespace ui 654 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.cc ('k') | ui/ui_unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698