Support for unpacked ARM packed relocations.
[chromium-blink-merge.git] / ui / chromeos / touch_exploration_controller_unittest.cc
blob86582f0ff06b5bc06698b094700dc7c677d3e52e
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
3 // found in the LICENSE file.
5 #include "ui/chromeos/touch_exploration_controller.h"
7 #include "base/test/simple_test_tick_clock.h"
8 #include "base/time/time.h"
9 #include "ui/aura/client/cursor_client.h"
10 #include "ui/aura/test/aura_test_base.h"
11 #include "ui/aura/test/event_generator.h"
12 #include "ui/aura/test/test_cursor_client.h"
13 #include "ui/aura/window.h"
14 #include "ui/events/event.h"
15 #include "ui/events/event_utils.h"
16 #include "ui/gfx/geometry/point.h"
17 #include "ui/gl/gl_implementation.h"
18 #include "ui/gl/gl_surface.h"
20 namespace ui {
22 namespace {
23 // Records all mouse and touch events.
24 class EventCapturer : public ui::EventHandler {
25 public:
26 EventCapturer() {}
27 virtual ~EventCapturer() {}
29 void Reset() {
30 events_.clear();
33 virtual void OnEvent(ui::Event* event) OVERRIDE {
34 if (event->IsMouseEvent()) {
35 events_.push_back(
36 new ui::MouseEvent(static_cast<ui::MouseEvent&>(*event)));
37 } else if (event->IsTouchEvent()) {
38 events_.push_back(
39 new ui::TouchEvent(static_cast<ui::TouchEvent&>(*event)));
40 } else {
41 return;
43 // Stop event propagation so we don't click on random stuff that
44 // might break test assumptions.
45 event->StopPropagation();
46 // If there is a possibility that we're in an infinite loop, we should
47 // exit early with a sensible error rather than letting the test time out.
48 ASSERT_LT(events_.size(), 100u);
50 const ScopedVector<ui::LocatedEvent>& captured_events() const {
51 return events_;
54 private:
55 ScopedVector<ui::LocatedEvent> events_;
57 DISALLOW_COPY_AND_ASSIGN(EventCapturer);
60 } // namespace
62 class TouchExplorationTest : public aura::test::AuraTestBase {
63 public:
64 TouchExplorationTest()
65 : simulated_clock_(new base::SimpleTestTickClock()) {}
66 virtual ~TouchExplorationTest() {}
68 virtual void SetUp() OVERRIDE {
69 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone)
70 gfx::GLSurface::InitializeOneOffForTests();
71 aura::test::AuraTestBase::SetUp();
72 cursor_client_.reset(new aura::test::TestCursorClient(root_window()));
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();
81 virtual void TearDown() OVERRIDE {
82 root_window()->RemovePreTargetHandler(&event_capturer_);
83 SwitchTouchExplorationMode(false);
84 cursor_client_.reset();
85 aura::test::AuraTestBase::TearDown();
88 protected:
89 aura::client::CursorClient* cursor_client() { return cursor_client_.get(); }
91 const ScopedVector<ui::LocatedEvent>& GetCapturedEvents() {
92 return event_capturer_.captured_events();
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]);
102 return events;
105 void ClearCapturedEvents() {
106 event_capturer_.Reset();
109 void AdvanceSimulatedTimePastTapDelay() {
110 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
111 touch_exploration_controller_->CallTapTimerNowForTesting();
114 void SwitchTouchExplorationMode(bool on) {
115 if (!on && touch_exploration_controller_.get()) {
116 touch_exploration_controller_.reset();
117 } else if (on && !touch_exploration_controller_.get()) {
118 touch_exploration_controller_.reset(
119 new ui::TouchExplorationController(root_window()));
120 touch_exploration_controller_->SetEventHandlerForTesting(
121 &event_capturer_);
122 cursor_client()->ShowCursor();
123 cursor_client()->DisableMouseEvents();
127 void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) {
128 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now());
129 generator_->Dispatch(&touch_press);
130 AdvanceSimulatedTimePastTapDelay();
131 EXPECT_TRUE(IsInTouchToMouseMode());
134 bool IsInTouchToMouseMode() {
135 aura::client::CursorClient* cursor_client =
136 aura::client::GetCursorClient(root_window());
137 return cursor_client &&
138 cursor_client->IsMouseEventsEnabled() &&
139 !cursor_client->IsCursorVisible();
142 bool IsInNoFingersDownState() {
143 return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
146 base::TimeDelta Now() {
147 // This is the same as what EventTimeForNow() does, but here we do it
148 // with our simulated clock.
149 return base::TimeDelta::FromInternalValue(
150 simulated_clock_->NowTicks().ToInternalValue());
153 scoped_ptr<aura::test::EventGenerator> generator_;
154 ui::GestureDetector::Config gesture_detector_config_;
155 // Owned by |generator_|.
156 base::SimpleTestTickClock* simulated_clock_;
158 private:
159 EventCapturer event_capturer_;
160 scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_;
161 scoped_ptr<aura::test::TestCursorClient> cursor_client_;
163 DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
166 // Executes a number of assertions to confirm that |e1| and |e2| are touch
167 // events and are equal to each other.
168 void ConfirmEventsAreTouchAndEqual(ui::Event* e1, ui::Event* e2) {
169 ASSERT_TRUE(e1->IsTouchEvent());
170 ASSERT_TRUE(e2->IsTouchEvent());
171 ui::TouchEvent* touch_event1 = static_cast<ui::TouchEvent*>(e1);
172 ui::TouchEvent* touch_event2 = static_cast<ui::TouchEvent*>(e2);
173 EXPECT_EQ(touch_event1->type(), touch_event2->type());
174 EXPECT_EQ(touch_event1->location(), touch_event2->location());
175 EXPECT_EQ(touch_event1->touch_id(), touch_event2->touch_id());
176 EXPECT_EQ(touch_event1->flags(), touch_event2->flags());
177 EXPECT_EQ(touch_event1->time_stamp(), touch_event2->time_stamp());
180 // Executes a number of assertions to confirm that |e1| and |e2| are mouse
181 // events and are equal to each other.
182 void ConfirmEventsAreMouseAndEqual(ui::Event* e1, ui::Event* e2) {
183 ASSERT_TRUE(e1->IsMouseEvent());
184 ASSERT_TRUE(e2->IsMouseEvent());
185 ui::MouseEvent* mouse_event1 = static_cast<ui::MouseEvent*>(e1);
186 ui::MouseEvent* mouse_event2 = static_cast<ui::MouseEvent*>(e2);
187 EXPECT_EQ(mouse_event1->type(), mouse_event2->type());
188 EXPECT_EQ(mouse_event1->location(), mouse_event2->location());
189 EXPECT_EQ(mouse_event1->root_location(), mouse_event2->root_location());
190 EXPECT_EQ(mouse_event1->flags(), mouse_event2->flags());
193 #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \
194 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2))
196 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \
197 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2))
199 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit
200 // events when running these tests as part of ui_unittests. We do get them when
201 // the tests are run as part of ash unit tests.
203 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) {
204 SwitchTouchExplorationMode(true);
205 EXPECT_FALSE(IsInTouchToMouseMode());
206 generator_->PressTouch();
207 AdvanceSimulatedTimePastTapDelay();
208 EXPECT_TRUE(IsInTouchToMouseMode());
211 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) {
212 int slop = gesture_detector_config_.touch_slop;
213 int half_slop = slop / 2;
215 SwitchTouchExplorationMode(true);
216 EXPECT_FALSE(IsInTouchToMouseMode());
217 generator_->set_current_location(gfx::Point(11, 12));
218 generator_->PressTouch();
219 generator_->MoveTouch(gfx::Point(11 + half_slop, 12));
220 EXPECT_FALSE(IsInTouchToMouseMode());
221 generator_->MoveTouch(gfx::Point(11, 12 + half_slop));
222 EXPECT_FALSE(IsInTouchToMouseMode());
223 generator_->MoveTouch(gfx::Point(11 + slop + 1, 12));
224 EXPECT_TRUE(IsInTouchToMouseMode());
227 TEST_F(TouchExplorationTest, OneFingerTap) {
228 SwitchTouchExplorationMode(true);
229 gfx::Point location(11, 12);
230 generator_->set_current_location(location);
231 generator_->PressTouch();
232 generator_->ReleaseTouch();
233 AdvanceSimulatedTimePastTapDelay();
235 std::vector<ui::LocatedEvent*> events =
236 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
237 ASSERT_EQ(1U, events.size());
239 EXPECT_EQ(location, events[0]->location());
240 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
241 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
242 EXPECT_TRUE(IsInNoFingersDownState());
245 TEST_F(TouchExplorationTest, ActualMouseMovesUnaffected) {
246 SwitchTouchExplorationMode(true);
248 gfx::Point location_start(11, 12);
249 gfx::Point location_end(13, 14);
250 generator_->set_current_location(location_start);
251 generator_->PressTouch();
252 AdvanceSimulatedTimePastTapDelay();
253 generator_->MoveTouch(location_end);
255 gfx::Point location_real_mouse_move(15, 16);
256 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
257 location_real_mouse_move,
258 location_real_mouse_move,
261 generator_->Dispatch(&mouse_move);
262 generator_->ReleaseTouch();
263 AdvanceSimulatedTimePastTapDelay();
265 std::vector<ui::LocatedEvent*> events =
266 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
267 ASSERT_EQ(4U, events.size());
269 EXPECT_EQ(location_start, events[0]->location());
270 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
271 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
273 EXPECT_EQ(location_end, events[1]->location());
274 EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
275 EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
277 // The real mouse move goes through.
278 EXPECT_EQ(location_real_mouse_move, events[2]->location());
279 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(events[2], &mouse_move);
280 EXPECT_FALSE(events[2]->flags() & ui::EF_IS_SYNTHESIZED);
281 EXPECT_FALSE(events[2]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
283 // The touch release gets written as a mouse move.
284 EXPECT_EQ(location_end, events[3]->location());
285 EXPECT_TRUE(events[3]->flags() & ui::EF_IS_SYNTHESIZED);
286 EXPECT_TRUE(events[3]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
287 EXPECT_TRUE(IsInNoFingersDownState());
290 // Turn the touch exploration mode on in the middle of the touch gesture.
291 // Confirm that events from the finger which was touching when the mode was
292 // turned on don't get rewritten.
293 TEST_F(TouchExplorationTest, TurnOnMidTouch) {
294 SwitchTouchExplorationMode(false);
295 generator_->PressTouchId(1);
296 EXPECT_TRUE(cursor_client()->IsCursorVisible());
297 ClearCapturedEvents();
299 // Enable touch exploration mode while the first finger is touching the
300 // screen. Ensure that subsequent events from that first finger are not
301 // affected by the touch exploration mode, while the touch events from another
302 // finger get rewritten.
303 SwitchTouchExplorationMode(true);
304 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED,
305 gfx::Point(11, 12),
307 Now());
308 generator_->Dispatch(&touch_move);
309 EXPECT_TRUE(cursor_client()->IsCursorVisible());
310 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
311 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
312 ASSERT_EQ(1u, captured_events.size());
313 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
314 ClearCapturedEvents();
316 // The press from the second finger should get rewritten.
317 generator_->PressTouchId(2);
318 AdvanceSimulatedTimePastTapDelay();
319 EXPECT_TRUE(IsInTouchToMouseMode());
320 ScopedVector<ui::LocatedEvent>::const_iterator it;
321 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
322 if ((*it)->type() == ui::ET_MOUSE_MOVED)
323 break;
325 EXPECT_NE(captured_events.end(), it);
326 ClearCapturedEvents();
328 // The release of the first finger shouldn't be affected.
329 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED,
330 gfx::Point(11, 12),
332 Now());
333 generator_->Dispatch(&touch_release);
334 ASSERT_EQ(1u, captured_events.size());
335 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
336 ClearCapturedEvents();
338 // The move and release from the second finger should get rewritten.
339 generator_->MoveTouchId(gfx::Point(13, 14), 2);
340 generator_->ReleaseTouchId(2);
341 AdvanceSimulatedTimePastTapDelay();
343 ASSERT_EQ(2u, captured_events.size());
344 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
345 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
346 EXPECT_TRUE(IsInNoFingersDownState());
349 TEST_F(TouchExplorationTest, TwoFingerTouch) {
350 SwitchTouchExplorationMode(true);
351 generator_->PressTouchId(1);
352 ClearCapturedEvents();
354 // Confirm events from the second finger go through as is.
355 ui::TouchEvent touch_press(
356 ui::ET_TOUCH_PRESSED,
357 gfx::Point(10, 11),
359 Now());
360 generator_->Dispatch(&touch_press);
361 EXPECT_TRUE(cursor_client()->IsCursorVisible());
362 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
363 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
364 // TODO(mfomitchev): mouse enter/exit events
365 // There will be a ET_MOUSE_EXITED event synthesized when the mouse cursor is
366 // hidden - ignore it.
367 ScopedVector<ui::LocatedEvent>::const_iterator it;
368 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
369 if ((*it)->type() == ui::ET_TOUCH_PRESSED) {
370 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(*it, &touch_press);
371 break;
374 EXPECT_NE(captured_events.end(), it);
375 ClearCapturedEvents();
376 ui::TouchEvent touch_move(
377 ui::ET_TOUCH_MOVED,
378 gfx::Point(20, 21),
380 Now());
381 generator_->Dispatch(&touch_move);
382 ASSERT_EQ(1u, captured_events.size());
383 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
384 ClearCapturedEvents();
386 // Confirm mouse moves go through unaffected.
387 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
388 gfx::Point(13, 14),
389 gfx::Point(13, 14),
392 generator_->Dispatch(&mouse_move);
393 // TODO(mfomitchev): mouse enter/exit events
394 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED
395 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
396 if ((*it)->type() == ui::ET_MOUSE_MOVED) {
397 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move);
398 break;
401 EXPECT_NE(captured_events.end(), it);
402 ClearCapturedEvents();
404 // Events from the first finger should not go through while the second finger
405 // is touching.
406 gfx::Point touch1_location = gfx::Point(15, 16);
407 generator_->MoveTouchId(touch1_location, 1);
408 EXPECT_EQ(0u, GetCapturedEvents().size());
410 EXPECT_TRUE(cursor_client()->IsCursorVisible());
411 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
413 // A release of the second finger should be rewritten as a mouse move
414 // of that finger to the |touch1_location| and we stay in passthrough
415 // mode.
416 ui::TouchEvent touch_release(
417 ui::ET_TOUCH_RELEASED,
418 gfx::Point(25, 26),
420 Now());
421 generator_->Dispatch(&touch_release);
422 EXPECT_FALSE(IsInTouchToMouseMode());
423 ASSERT_EQ(captured_events.size(), 1u);
424 EXPECT_EQ(touch1_location, captured_events[0]->location());
427 TEST_F(TouchExplorationTest, MultiFingerTouch) {
428 SwitchTouchExplorationMode(true);
429 generator_->PressTouchId(1);
430 generator_->PressTouchId(2);
431 ClearCapturedEvents();
433 // Confirm events from other fingers go through as is.
434 ui::TouchEvent touch3_press(ui::ET_TOUCH_PRESSED,
435 gfx::Point(10, 11),
437 Now());
438 ui::TouchEvent touch3_move1(ui::ET_TOUCH_MOVED,
439 gfx::Point(12, 13),
441 Now());
442 ui::TouchEvent touch4_press(ui::ET_TOUCH_PRESSED,
443 gfx::Point(20, 21),
445 Now());
446 ui::TouchEvent touch3_move2(ui::ET_TOUCH_MOVED,
447 gfx::Point(14, 15),
449 Now());
450 ui::TouchEvent touch4_move(ui::ET_TOUCH_MOVED,
451 gfx::Point(22, 23),
453 Now());
454 ui::TouchEvent touch3_release(ui::ET_TOUCH_RELEASED,
455 gfx::Point(14, 15),
457 Now());
458 ui::TouchEvent touch4_release(ui::ET_TOUCH_RELEASED,
459 gfx::Point(22, 23),
461 Now());
462 generator_->Dispatch(&touch3_press);
463 generator_->Dispatch(&touch3_move1);
464 generator_->Dispatch(&touch4_press);
465 generator_->Dispatch(&touch3_move2);
466 generator_->Dispatch(&touch4_move);
467 generator_->Dispatch(&touch3_release);
468 generator_->Dispatch(&touch4_release);
470 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
471 ASSERT_EQ(7u, captured_events.size());
472 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch3_press);
473 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[1], &touch3_move1);
474 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[2], &touch4_press);
475 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[3], &touch3_move2);
476 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[4], &touch4_move);
478 // The release of finger 3 is rewritten as a move to the former location
479 // of finger 1.
480 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[5]->type());
481 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[6], &touch4_release);
484 // Test the case when there are multiple fingers on the screen and the first
485 // finger is released. This should be ignored, but then the second finger
486 // release should be passed through.
487 TEST_F(TouchExplorationTest, FirstFingerLifted) {
488 SwitchTouchExplorationMode(true);
489 generator_->PressTouchId(1);
490 generator_->PressTouchId(2);
491 gfx::Point touch2_location(10, 11);
492 generator_->MoveTouchId(touch2_location, 2);
493 generator_->PressTouchId(3);
494 gfx::Point touch3_location(20, 21);
495 generator_->MoveTouchId(touch3_location, 3);
496 ClearCapturedEvents();
498 // Release of finger 1 should be ignored.
499 generator_->ReleaseTouchId(1);
500 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
501 ASSERT_EQ(0u, captured_events.size());
503 // Move of finger 2 should be passed through.
504 gfx::Point touch2_new_location(20, 11);
505 generator_->MoveTouchId(touch2_new_location, 2);
506 ASSERT_EQ(1u, captured_events.size());
507 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
508 EXPECT_EQ(touch2_new_location, captured_events[0]->location());
509 ClearCapturedEvents();
511 // Release of finger 2 should be passed through.
512 ui::TouchEvent touch2_release(
513 ui::ET_TOUCH_RELEASED,
514 gfx::Point(14, 15),
516 Now());
517 generator_->Dispatch(&touch2_release);
518 ASSERT_EQ(1u, captured_events.size());
519 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch2_release);
522 // Test the case when there are multiple fingers on the screen and the
523 // second finger is released. This should be rewritten as a move to the
524 // location of the first finger.
525 TEST_F(TouchExplorationTest, SecondFingerLifted) {
526 SwitchTouchExplorationMode(true);
527 gfx::Point touch1_location(0, 11);
528 generator_->set_current_location(touch1_location);
529 generator_->PressTouchId(1);
530 generator_->PressTouchId(2);
531 gfx::Point touch2_location(10, 11);
532 generator_->MoveTouchId(touch2_location, 2);
533 generator_->PressTouchId(3);
534 gfx::Point touch3_location(20, 21);
535 generator_->MoveTouchId(touch3_location, 3);
536 ClearCapturedEvents();
538 // Release of finger 2 should be rewritten as a move to the location
539 // of the first finger.
540 generator_->ReleaseTouchId(2);
541 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
542 ASSERT_EQ(1u, captured_events.size());
543 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
544 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
545 EXPECT_EQ(touch1_location, captured_events[0]->location());
546 ClearCapturedEvents();
548 // Move of finger 1 should be rewritten as a move of finger 2.
549 gfx::Point touch1_new_location(0, 41);
550 generator_->MoveTouchId(touch1_new_location, 1);
551 ASSERT_EQ(1u, captured_events.size());
552 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
553 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
554 EXPECT_EQ(touch1_new_location, captured_events[0]->location());
555 ClearCapturedEvents();
557 // Release of finger 1 should be rewritten as release of finger 2.
558 gfx::Point touch1_final_location(0, 41);
559 ui::TouchEvent touch1_release(
560 ui::ET_TOUCH_RELEASED,
561 touch1_final_location,
563 Now());
564 generator_->Dispatch(&touch1_release);
565 ASSERT_EQ(1u, captured_events.size());
566 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type());
567 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
568 EXPECT_EQ(touch1_final_location, captured_events[0]->location());
571 // If an event is received after the double-tap timeout has elapsed, but
572 // before the timer has fired, a mouse move should still be generated.
573 TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) {
574 SwitchTouchExplorationMode(true);
576 // Send a press, then add another finger after the double-tap timeout.
577 generator_->PressTouchId(1);
578 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
579 generator_->PressTouchId(2);
580 std::vector<ui::LocatedEvent*> events =
581 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
582 ASSERT_EQ(1U, events.size());
583 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
584 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
586 generator_->ReleaseTouchId(2);
587 generator_->ReleaseTouchId(1);
588 AdvanceSimulatedTimePastTapDelay();
589 EXPECT_TRUE(IsInNoFingersDownState());
592 // If a new tap is received after the double-tap timeout has elapsed from
593 // a previous tap, but before the timer has fired, a mouse move should
594 // still be generated from the old tap.
595 TEST_F(TouchExplorationTest, TimerFiresLateAfterTap) {
596 SwitchTouchExplorationMode(true);
598 // Send a tap at location1.
599 gfx::Point location0(11, 12);
600 generator_->set_current_location(location0);
601 generator_->PressTouch();
602 generator_->ReleaseTouch();
604 // Send a tap at location2, after the double-tap timeout, but before the
605 // timer fires.
606 gfx::Point location1(33, 34);
607 generator_->set_current_location(location1);
608 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(301));
609 generator_->PressTouch();
610 generator_->ReleaseTouch();
611 AdvanceSimulatedTimePastTapDelay();
613 std::vector<ui::LocatedEvent*> events =
614 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
615 ASSERT_EQ(2U, events.size());
616 EXPECT_EQ(location0, events[0]->location());
617 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
618 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
619 EXPECT_EQ(location1, events[1]->location());
620 EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
621 EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
622 EXPECT_TRUE(IsInNoFingersDownState());
625 // Double-tapping should send a touch press and release through to the location
626 // of the last successful touch exploration.
627 TEST_F(TouchExplorationTest, DoubleTap) {
628 SwitchTouchExplorationMode(true);
630 // Tap at one location, and get a mouse move event.
631 gfx::Point tap_location(11, 12);
632 generator_->set_current_location(tap_location);
633 generator_->PressTouch();
634 generator_->ReleaseTouch();
635 AdvanceSimulatedTimePastTapDelay();
637 std::vector<ui::LocatedEvent*> events =
638 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
639 ASSERT_EQ(1U, events.size());
641 EXPECT_EQ(tap_location, events[0]->location());
642 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
643 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
644 ClearCapturedEvents();
646 // Now double-tap at a different location. This should result in
647 // a single touch press and release at the location of the tap,
648 // not at the location of the double-tap.
649 gfx::Point double_tap_location(33, 34);
650 generator_->set_current_location(double_tap_location);
651 generator_->PressTouch();
652 generator_->ReleaseTouch();
653 generator_->PressTouch();
654 generator_->ReleaseTouch();
656 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
657 ASSERT_EQ(2U, captured_events.size());
658 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
659 EXPECT_EQ(tap_location, captured_events[0]->location());
660 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
661 EXPECT_EQ(tap_location, captured_events[1]->location());
662 EXPECT_TRUE(IsInNoFingersDownState());
665 // Double-tapping where the user holds their finger down for the second time
666 // for a longer press should send a touch press and released (right click)
667 // to the location of the last successful touch exploration.
668 TEST_F(TouchExplorationTest, DoubleTapLongPress) {
669 SwitchTouchExplorationMode(true);
671 // Tap at one location, and get a mouse move event.
672 gfx::Point tap_location(11, 12);
673 generator_->set_current_location(tap_location);
674 generator_->PressTouch();
675 generator_->ReleaseTouch();
676 AdvanceSimulatedTimePastTapDelay();
678 std::vector<ui::LocatedEvent*> events =
679 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
680 ASSERT_EQ(1U, events.size());
682 EXPECT_EQ(tap_location, events[0]->location());
683 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
684 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
685 ClearCapturedEvents();
687 // Now double-tap and hold at a different location.
688 // This should result in a single touch long press and release
689 // at the location of the tap, not at the location of the double-tap.
690 // There should be a time delay between the touch press and release.
691 gfx::Point first_tap_location(33, 34);
692 generator_->set_current_location(first_tap_location);
693 generator_->PressTouch();
694 generator_->ReleaseTouch();
695 gfx::Point second_tap_location(23, 24);
696 generator_->set_current_location(second_tap_location);
697 generator_->PressTouch();
698 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
699 generator_->ReleaseTouch();
701 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
702 ASSERT_EQ(2U, captured_events.size());
703 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
704 EXPECT_EQ(tap_location, captured_events[0]->location());
705 base::TimeDelta pressed_time = captured_events[0]->time_stamp();
706 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
707 EXPECT_EQ(tap_location, captured_events[1]->location());
708 base::TimeDelta released_time = captured_events[1]->time_stamp();
709 EXPECT_EQ(gesture_detector_config_.longpress_timeout,
710 released_time - pressed_time);
713 // Single-tapping should send a touch press and release through to the location
714 // of the last successful touch exploration if the grace period has not
715 // elapsed.
716 TEST_F(TouchExplorationTest, SingleTap) {
717 SwitchTouchExplorationMode(true);
719 // Tap once to simulate a mouse moved event.
720 gfx::Point initial_location(11, 12);
721 generator_->set_current_location(initial_location);
722 generator_->PressTouch();
724 // Move to another location for single tap
725 gfx::Point tap_location(22, 23);
726 generator_->MoveTouch(tap_location);
727 generator_->ReleaseTouch();
729 // Allow time to pass within the grace period of releasing before
730 // tapping again.
731 gfx::Point final_location(33, 34);
732 generator_->set_current_location(final_location);
733 simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(250));
734 generator_->PressTouch();
735 generator_->ReleaseTouch();
737 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
738 ASSERT_EQ(4U, captured_events.size());
739 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
740 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
741 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type());
742 EXPECT_EQ(tap_location, captured_events[2]->location());
743 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[3]->type());
744 EXPECT_EQ(tap_location, captured_events[3]->location());
747 // Double-tapping without coming from touch exploration (no previous touch
748 // exploration event) should not generate any events.
749 TEST_F(TouchExplorationTest, DoubleTapNoTouchExplore) {
750 SwitchTouchExplorationMode(true);
752 // Double-tap without any previous touch.
753 // Touch exploration mode has not been entered, so there is no previous
754 // touch exploration event. The double-tap should be discarded, and no events
755 // should be generated at all.
756 gfx::Point double_tap_location(33, 34);
757 generator_->set_current_location(double_tap_location);
758 generator_->PressTouch();
759 generator_->ReleaseTouch();
760 generator_->PressTouch();
761 generator_->ReleaseTouch();
763 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
764 ASSERT_EQ(0U, captured_events.size());
767 // Tapping and releasing with a second finger when in touch exploration mode
768 // should send a touch press and released to the location of the last
769 // successful touch exploration and return to touch explore.
770 TEST_F(TouchExplorationTest, SplitTap) {
771 SwitchTouchExplorationMode(true);
772 gfx::Point initial_touch_location(11, 12);
773 gfx::Point second_touch_location(33, 34);
775 // Tap and hold at one location, and get a mouse move event in touch explore.
776 EnterTouchExplorationModeAtLocation(initial_touch_location);
777 std::vector<ui::LocatedEvent*> events =
778 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
779 ASSERT_EQ(1U, events.size());
781 EXPECT_EQ(initial_touch_location, events[0]->location());
782 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
783 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
784 ClearCapturedEvents();
786 // Now tap and release at a different location. This should result in a
787 // single touch and release at the location of the first (held) tap,
788 // not at the location of the second tap and release.
789 // After the release, there is still a finger in touch explore mode.
790 ui::TouchEvent split_tap_press(
791 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
792 generator_->Dispatch(&split_tap_press);
793 ui::TouchEvent split_tap_release(
794 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
795 generator_->Dispatch(&split_tap_release);
796 EXPECT_FALSE(IsInNoFingersDownState());
798 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
799 ASSERT_EQ(2U, captured_events.size());
800 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
801 EXPECT_EQ(initial_touch_location, captured_events[0]->location());
802 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
803 EXPECT_EQ(initial_touch_location, captured_events[1]->location());
806 // If split tap is started but the touch explore finger is released first,
807 // there should still be a touch press and release sent to the location of
808 // the last successful touch exploration.
809 // Both fingers should be released after the click goes through.
810 TEST_F(TouchExplorationTest, SplitTapRelease) {
811 SwitchTouchExplorationMode(true);
813 gfx::Point initial_touch_location(11, 12);
814 gfx::Point second_touch_location(33, 34);
816 // Tap and hold at one location, and get a mouse move event in touch explore.
817 EnterTouchExplorationModeAtLocation(initial_touch_location);
819 std::vector<ui::LocatedEvent*> events =
820 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
821 ASSERT_EQ(1U, events.size());
823 ClearCapturedEvents();
825 // Now tap at a different location. Release at the first location,
826 // then release at the second. This should result in a
827 // single touch and release at the location of the first (held) tap,
828 // not at the location of the second tap and release.
829 ui::TouchEvent split_tap_press(
830 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
831 generator_->Dispatch(&split_tap_press);
832 ui::TouchEvent touch_explore_release(
833 ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
834 generator_->Dispatch(&touch_explore_release);
835 ui::TouchEvent split_tap_release(
836 ui::ET_TOUCH_RELEASED, second_touch_location , 1, Now());
837 generator_->Dispatch(&split_tap_release);
838 EXPECT_TRUE(IsInNoFingersDownState());
840 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
841 ASSERT_EQ(2U, captured_events.size());
842 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
843 EXPECT_EQ(initial_touch_location, captured_events[0]->location());
844 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
845 EXPECT_EQ(initial_touch_location, captured_events[1]->location());
848 // When in touch exploration mode, making a long press with a second finger
849 // should send a touch press and released to the location of the last
850 // successful touch exploration. There should be a delay between the
851 // touch and release events (right click).
852 TEST_F(TouchExplorationTest, SplitTapLongPress) {
853 SwitchTouchExplorationMode(true);
854 gfx::Point initial_touch_location(11, 12);
855 gfx::Point second_touch_location(33, 34);
857 // Tap and hold at one location, and get a mouse move event in touch explore.
858 EnterTouchExplorationModeAtLocation(initial_touch_location);
859 std::vector<ui::LocatedEvent*> events =
860 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
861 ASSERT_EQ(1U, events.size());
863 ClearCapturedEvents();
865 // Now tap and release at a different location. This should result in a
866 // single touch and release at the location of the first (held) tap,
867 // not at the location of the second tap and release.
868 // After the release, there is still a finger in touch explore mode.
869 ui::TouchEvent split_tap_press(
870 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
871 generator_->Dispatch(&split_tap_press);
872 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
873 ui::TouchEvent split_tap_release(
874 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
875 generator_->Dispatch(&split_tap_release);
876 EXPECT_FALSE(IsInNoFingersDownState());
878 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
879 ASSERT_EQ(2U, captured_events.size());
880 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
881 EXPECT_EQ(initial_touch_location, captured_events[0]->location());
882 base::TimeDelta pressed_time = captured_events[0]->time_stamp();
883 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
884 EXPECT_EQ(initial_touch_location, captured_events[1]->location());
885 base::TimeDelta released_time = captured_events[1]->time_stamp();
886 EXPECT_EQ(gesture_detector_config_.longpress_timeout,
887 released_time - pressed_time);
890 // If split tap is started but the touch explore finger is released first,
891 // there should still be a touch press and release sent to the location of
892 // the last successful touch exploration. If the remaining finger is held
893 // as a longpress, there should be a delay between the sent touch and release
894 // events (right click).All fingers should be released after the click
895 // goes through.
896 TEST_F(TouchExplorationTest, SplitTapReleaseLongPress) {
897 SwitchTouchExplorationMode(true);
898 gfx::Point initial_touch_location(11, 12);
899 gfx::Point second_touch_location(33, 34);
901 // Tap and hold at one location, and get a mouse move event in touch explore.
902 EnterTouchExplorationModeAtLocation(initial_touch_location);
903 std::vector<ui::LocatedEvent*> events =
904 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
905 ASSERT_EQ(1U, events.size());
906 ClearCapturedEvents();
908 // Now tap at a different location. Release at the first location,
909 // then release at the second. This should result in a
910 // single touch and release at the location of the first (held) tap,
911 // not at the location of the second tap and release.
912 // After the release, TouchToMouseMode should still be on.
913 ui::TouchEvent split_tap_press(
914 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
915 generator_->Dispatch(&split_tap_press);
916 ui::TouchEvent touch_explore_release(
917 ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
918 generator_->Dispatch(&touch_explore_release);
919 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
920 ui::TouchEvent split_tap_release(
921 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
922 generator_->Dispatch(&split_tap_release);
923 EXPECT_TRUE(IsInTouchToMouseMode());
925 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
926 ASSERT_EQ(2U, captured_events.size());
927 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
928 EXPECT_EQ(initial_touch_location, captured_events[0]->location());
929 base::TimeDelta pressed_time = captured_events[0]->time_stamp();
930 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
931 EXPECT_EQ(initial_touch_location, captured_events[1]->location());
932 base::TimeDelta released_time = captured_events[1]->time_stamp();
933 EXPECT_EQ(gesture_detector_config_.longpress_timeout,
934 released_time - pressed_time);
937 TEST_F(TouchExplorationTest, SplitTapLongPressMultiFinger) {
938 SwitchTouchExplorationMode(true);
939 gfx::Point initial_touch_location(11, 12);
940 gfx::Point second_touch_location(33, 34);
941 gfx::Point third_touch_location(16, 17);
943 // Tap and hold at one location, and get a mouse move event in touch explore.
944 EnterTouchExplorationModeAtLocation(initial_touch_location);
946 std::vector<ui::LocatedEvent*> events =
947 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
948 ASSERT_EQ(1U, events.size());
950 EXPECT_EQ(initial_touch_location, events[0]->location());
951 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
952 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
953 ClearCapturedEvents();
955 // Now tap at a different location and hold for long press.
956 ui::TouchEvent split_tap_press(
957 ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
958 generator_->Dispatch(&split_tap_press);
959 simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
961 // Placing a third finger on the screen should be discarded and not affect
962 // the events passed through.
963 ui::TouchEvent third_press(
964 ui::ET_TOUCH_PRESSED, third_touch_location, 2, Now());
965 generator_->Dispatch(&third_press);
967 // When all three fingers are released, there should be only two captured
968 // events: touch press and touch release. All fingers should then be up.
969 ui::TouchEvent touch_explore_release(
970 ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
971 generator_->Dispatch(&touch_explore_release);
972 ui::TouchEvent split_tap_release(
973 ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
974 generator_->Dispatch(&split_tap_release);
975 ui::TouchEvent third_tap_release(
976 ui::ET_TOUCH_RELEASED, third_touch_location, 2, Now());
977 generator_->Dispatch(&third_tap_release);
979 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
980 ASSERT_EQ(2U, captured_events.size());
981 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
982 EXPECT_EQ(initial_touch_location, captured_events[0]->location());
983 base::TimeDelta pressed_time = captured_events[0]->time_stamp();
984 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
985 EXPECT_EQ(initial_touch_location, captured_events[1]->location());
986 base::TimeDelta released_time = captured_events[1]->time_stamp();
987 EXPECT_EQ(gesture_detector_config_.longpress_timeout,
988 released_time - pressed_time);
989 EXPECT_TRUE(IsInNoFingersDownState());
992 } // namespace ui