Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / chromeos / touch_exploration_controller_unittest.cc
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.
4
5 #include "ui/chromeos/touch_exploration_controller.h"
6
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/test_cursor_client.h"
12 #include "ui/aura/window.h"
13 #include "ui/events/event.h"
14 #include "ui/events/event_utils.h"
15 #include "ui/events/gestures/gesture_provider_aura.h"
16 #include "ui/events/test/event_generator.h"
17 #include "ui/events/test/events_test_utils.h"
18 #include "ui/gfx/geometry/point.h"
19 #include "ui/gl/gl_implementation.h"
20 #include "ui/gl/gl_surface.h"
21
22 namespace ui {
23
24 namespace {
25
26 // Records all mouse, touch, gesture, and key events.
27 class EventCapturer : public ui::EventHandler {
28  public:
29   EventCapturer() {}
30   virtual ~EventCapturer() {}
31
32   void Reset() {
33     events_.clear();
34   }
35
36   virtual void OnEvent(ui::Event* event) override {
37     if (event->IsMouseEvent()) {
38       events_.push_back(
39           new ui::MouseEvent(static_cast<ui::MouseEvent&>(*event)));
40     } else if (event->IsTouchEvent()) {
41       events_.push_back(
42           new ui::TouchEvent(static_cast<ui::TouchEvent&>(*event)));
43     } else if (event->IsGestureEvent()) {
44       events_.push_back(
45           new ui::GestureEvent(static_cast<ui::GestureEvent&>(*event)));
46     } else if (event->IsKeyEvent()) {
47       events_.push_back(new ui::KeyEvent(static_cast<ui::KeyEvent&>(*event)));
48     } else {
49       return;
50     }
51     // Stop event propagation so we don't click on random stuff that
52     // might break test assumptions.
53     event->StopPropagation();
54     // If there is a possibility that we're in an infinite loop, we should
55     // exit early with a sensible error rather than letting the test time out.
56     ASSERT_LT(events_.size(), 100u);
57   }
58
59   const ScopedVector<ui::Event>& captured_events() const { return events_; }
60
61  private:
62   ScopedVector<ui::Event> events_;
63
64   DISALLOW_COPY_AND_ASSIGN(EventCapturer);
65 };
66
67 int Factorial(int n) {
68   if (n <= 0)
69     return 0;
70   if (n == 1)
71     return 1;
72   return n * Factorial(n - 1);
73 }
74
75 class MockTouchExplorationControllerDelegate
76     : public ui::TouchExplorationControllerDelegate {
77  public:
78   virtual void SetOutputLevel(int volume) override {
79     volume_changes_.push_back(volume);
80   }
81   virtual void SilenceSpokenFeedback() override {
82   }
83   virtual void PlayVolumeAdjustEarcon() override {
84     ++num_times_adjust_sound_played_;
85   }
86   virtual void PlayPassthroughEarcon() override {
87     ++num_times_passthrough_played_;
88   }
89   virtual void PlayExitScreenEarcon() override {
90     ++num_times_exit_screen_played_;
91   }
92   virtual void PlayEnterScreenEarcon() override {
93     ++num_times_enter_screen_played_;
94   }
95
96   const std::vector<float> VolumeChanges() { return volume_changes_; }
97   size_t NumAdjustSounds() { return num_times_adjust_sound_played_; }
98   size_t NumPassthroughSounds() { return num_times_passthrough_played_; }
99   size_t NumExitScreenSounds() { return num_times_exit_screen_played_; }
100   size_t NumEnterScreenSounds() {
101     return num_times_enter_screen_played_;
102   }
103
104   void ResetCountersToZero() {
105     num_times_adjust_sound_played_ = 0;
106     num_times_passthrough_played_ = 0;
107     num_times_exit_screen_played_ = 0;
108     num_times_enter_screen_played_ = 0;
109   }
110
111  private:
112   std::vector<float> volume_changes_;
113   size_t num_times_adjust_sound_played_ = 0;
114   size_t num_times_passthrough_played_ = 0;
115   size_t num_times_exit_screen_played_ = 0;
116   size_t num_times_enter_screen_played_ = 0;
117 };
118
119 }  // namespace
120
121 class TouchExplorationControllerTestApi {
122  public:
123   TouchExplorationControllerTestApi(
124       TouchExplorationController* touch_exploration_controller) {
125     touch_exploration_controller_.reset(touch_exploration_controller);
126   }
127
128   void CallTapTimerNowForTesting() {
129     DCHECK(touch_exploration_controller_->tap_timer_.IsRunning());
130     touch_exploration_controller_->tap_timer_.Stop();
131     touch_exploration_controller_->OnTapTimerFired();
132   }
133
134   void CallPassthroughTimerNowForTesting() {
135     DCHECK(touch_exploration_controller_->passthrough_timer_.IsRunning());
136     touch_exploration_controller_->passthrough_timer_.Stop();
137     touch_exploration_controller_->OnPassthroughTimerFired();
138   }
139
140   void CallTapTimerNowIfRunningForTesting() {
141     if (touch_exploration_controller_->tap_timer_.IsRunning()) {
142       touch_exploration_controller_->tap_timer_.Stop();
143       touch_exploration_controller_->OnTapTimerFired();
144     }
145   }
146
147   bool IsInNoFingersDownStateForTesting() const {
148     return touch_exploration_controller_->state_ ==
149            touch_exploration_controller_->NO_FINGERS_DOWN;
150   }
151
152   bool IsInGestureInProgressStateForTesting() const {
153     return touch_exploration_controller_->state_ ==
154            touch_exploration_controller_->GESTURE_IN_PROGRESS;
155   }
156
157   bool IsInSlideGestureStateForTesting() const {
158     return touch_exploration_controller_->state_ ==
159            touch_exploration_controller_->SLIDE_GESTURE;
160   }
161
162   bool IsInTwoFingerTapStateForTesting() const {
163     return touch_exploration_controller_->state_ ==
164            touch_exploration_controller_->TWO_FINGER_TAP;
165   }
166   bool IsInCornerPassthroughStateForTesting() const {
167     return touch_exploration_controller_->state_ ==
168            touch_exploration_controller_->CORNER_PASSTHROUGH;
169   }
170
171   gfx::Rect BoundsOfRootWindowInDIPForTesting() const {
172     return touch_exploration_controller_->root_window_->GetBoundsInScreen();
173   }
174
175   // VLOGs should be suppressed in tests that generate a lot of logs,
176   // for example permutations of nine touch events.
177   void SuppressVLOGsForTesting(bool suppress) {
178     touch_exploration_controller_->VLOG_on_ = !suppress;
179   }
180
181   float GetMaxDistanceFromEdge() const {
182     return touch_exploration_controller_->kMaxDistanceFromEdge;
183   }
184
185   float GetSlopDistanceFromEdge() const {
186     return touch_exploration_controller_->kSlopDistanceFromEdge;
187   }
188
189   void SetTickClockForTesting(base::TickClock* simulated_clock) {
190     touch_exploration_controller_->tick_clock_ = simulated_clock;
191   }
192
193  private:
194   scoped_ptr<TouchExplorationController> touch_exploration_controller_;
195
196   DISALLOW_COPY_AND_ASSIGN(TouchExplorationControllerTestApi);
197 };
198
199 class TouchExplorationTest : public aura::test::AuraTestBase {
200  public:
201   TouchExplorationTest() : simulated_clock_(new base::SimpleTestTickClock()) {
202     // Tests fail if time is ever 0.
203     simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
204   }
205   virtual ~TouchExplorationTest() {}
206
207   virtual void SetUp() override {
208     if (gfx::GetGLImplementation() == gfx::kGLImplementationNone)
209       gfx::GLSurface::InitializeOneOffForTests();
210     aura::test::AuraTestBase::SetUp();
211     cursor_client_.reset(new aura::test::TestCursorClient(root_window()));
212     root_window()->AddPreTargetHandler(&event_capturer_);
213     generator_.reset(new test::EventGenerator(root_window()));
214     // The generator takes ownership of the tick clock.
215     generator_->SetTickClock(scoped_ptr<base::TickClock>(simulated_clock_));
216     cursor_client()->ShowCursor();
217     cursor_client()->DisableMouseEvents();
218   }
219
220   virtual void TearDown() override {
221     root_window()->RemovePreTargetHandler(&event_capturer_);
222     SwitchTouchExplorationMode(false);
223     cursor_client_.reset();
224     aura::test::AuraTestBase::TearDown();
225   }
226
227  protected:
228   aura::client::CursorClient* cursor_client() { return cursor_client_.get(); }
229
230   const ScopedVector<ui::Event>& GetCapturedEvents() {
231     return event_capturer_.captured_events();
232   }
233
234   std::vector<ui::LocatedEvent*> GetCapturedLocatedEvents() {
235     const ScopedVector<ui::Event>& all_events = GetCapturedEvents();
236     std::vector<ui::LocatedEvent*> located_events;
237     for (size_t i = 0; i < all_events.size(); ++i) {
238       if (all_events[i]->IsMouseEvent() ||
239           all_events[i]->IsTouchEvent() ||
240           all_events[i]->IsGestureEvent()) {
241         located_events.push_back(static_cast<ui::LocatedEvent*>(all_events[i]));
242       }
243     }
244     return located_events;
245   }
246
247   std::vector<ui::Event*> GetCapturedEventsOfType(int type) {
248     const ScopedVector<ui::Event>& all_events = GetCapturedEvents();
249     std::vector<ui::Event*> events;
250     for (size_t i = 0; i < all_events.size(); ++i) {
251       if (type == all_events[i]->type())
252         events.push_back(all_events[i]);
253     }
254     return events;
255   }
256
257   std::vector<ui::LocatedEvent*> GetCapturedLocatedEventsOfType(int type) {
258     std::vector<ui::LocatedEvent*> located_events = GetCapturedLocatedEvents();
259     std::vector<ui::LocatedEvent*> events;
260     for (size_t i = 0; i < located_events.size(); ++i) {
261       if (type == located_events[i]->type())
262         events.push_back(located_events[i]);
263     }
264     return events;
265   }
266
267   void ClearCapturedEvents() {
268     event_capturer_.Reset();
269   }
270
271   void AdvanceSimulatedTimePastTapDelay() {
272     simulated_clock_->Advance(gesture_detector_config_.double_tap_timeout);
273     simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1));
274     touch_exploration_controller_->CallTapTimerNowForTesting();
275   }
276
277   void AdvanceSimulatedTimePastPassthroughDelay() {
278     simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
279     touch_exploration_controller_->CallPassthroughTimerNowForTesting();
280   }
281
282   void AdvanceSimulatedTimePastPotentialTapDelay() {
283     simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
284     touch_exploration_controller_->CallTapTimerNowIfRunningForTesting();
285   }
286
287   void SuppressVLOGs(bool suppress) {
288     touch_exploration_controller_->SuppressVLOGsForTesting(suppress);
289   }
290
291   void SetTickClock() {
292     touch_exploration_controller_->SetTickClockForTesting(
293         static_cast<base::TickClock*>(simulated_clock_));
294   }
295
296   void SwitchTouchExplorationMode(bool on) {
297     if (!on && touch_exploration_controller_.get()) {
298       touch_exploration_controller_.reset();
299     } else if (on && !touch_exploration_controller_.get()) {
300       touch_exploration_controller_.reset(
301           new ui::TouchExplorationControllerTestApi(
302               new TouchExplorationController(root_window(), &delegate_)));
303       cursor_client()->ShowCursor();
304       cursor_client()->DisableMouseEvents();
305     }
306   }
307
308   void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) {
309     ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, tap_location, 0, Now());
310     generator_->Dispatch(&touch_press);
311     AdvanceSimulatedTimePastTapDelay();
312     EXPECT_TRUE(IsInTouchToMouseMode());
313   }
314
315   // Checks that Corner Passthrough is working. Assumes that corner is the
316   // bottom left corner or the bottom right corner.
317   void AssertCornerPassthroughWorking(gfx::Point corner) {
318     ASSERT_EQ(0U, delegate_.NumPassthroughSounds());
319
320     ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, corner, 0, Now());
321     generator_->Dispatch(&first_press);
322
323     AdvanceSimulatedTimePastPassthroughDelay();
324     EXPECT_FALSE(IsInGestureInProgressState());
325     EXPECT_FALSE(IsInSlideGestureState());
326     EXPECT_FALSE(IsInTouchToMouseMode());
327     EXPECT_TRUE(IsInCornerPassthroughState());
328
329     gfx::Rect window = BoundsOfRootWindowInDIP();
330     // The following events should be passed through.
331     gfx::Point passthrough(window.right() / 2, window.bottom() / 2);
332     ui::TouchEvent passthrough_press(
333         ui::ET_TOUCH_PRESSED, passthrough, 1, Now());
334     ASSERT_EQ(1U, delegate_.NumPassthroughSounds());
335     generator_->Dispatch(&passthrough_press);
336     generator_->ReleaseTouchId(1);
337     generator_->PressTouchId(1);
338     EXPECT_FALSE(IsInGestureInProgressState());
339     EXPECT_FALSE(IsInSlideGestureState());
340     EXPECT_TRUE(IsInCornerPassthroughState());
341
342     std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
343     ASSERT_EQ(3U, captured_events.size());
344     EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
345     EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
346     EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type());
347     generator_->ReleaseTouchId(1);
348     ClearCapturedEvents();
349
350     generator_->ReleaseTouchId(0);
351     captured_events = GetCapturedLocatedEvents();
352     ASSERT_EQ(0U, captured_events.size());
353     EXPECT_FALSE(IsInTouchToMouseMode());
354     EXPECT_FALSE(IsInCornerPassthroughState());
355     ClearCapturedEvents();
356   }
357
358   bool IsInTouchToMouseMode() {
359     aura::client::CursorClient* cursor_client =
360         aura::client::GetCursorClient(root_window());
361     return cursor_client &&
362            cursor_client->IsMouseEventsEnabled() &&
363            !cursor_client->IsCursorVisible();
364   }
365
366   bool IsInNoFingersDownState() {
367     return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
368   }
369
370   bool IsInGestureInProgressState() {
371     return touch_exploration_controller_
372         ->IsInGestureInProgressStateForTesting();
373   }
374
375   bool IsInSlideGestureState() {
376     return touch_exploration_controller_->IsInSlideGestureStateForTesting();
377   }
378
379   bool IsInTwoFingerTapState() {
380     return touch_exploration_controller_->IsInTwoFingerTapStateForTesting();
381   }
382
383   bool IsInCornerPassthroughState() {
384     return touch_exploration_controller_
385         ->IsInCornerPassthroughStateForTesting();
386   }
387
388   gfx::Rect BoundsOfRootWindowInDIP() {
389     return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting();
390   }
391
392   float GetMaxDistanceFromEdge() const {
393     return touch_exploration_controller_->GetMaxDistanceFromEdge();
394   }
395
396   float GetSlopDistanceFromEdge() const {
397     return touch_exploration_controller_->GetSlopDistanceFromEdge();
398   }
399
400   base::TimeDelta Now() {
401     // This is the same as what EventTimeForNow() does, but here we do it
402     // with our simulated clock.
403     return base::TimeDelta::FromInternalValue(
404         simulated_clock_->NowTicks().ToInternalValue());
405   }
406
407   scoped_ptr<test::EventGenerator> generator_;
408   ui::GestureDetector::Config gesture_detector_config_;
409   // Owned by |generator_|.
410   base::SimpleTestTickClock* simulated_clock_;
411   MockTouchExplorationControllerDelegate delegate_;
412
413  private:
414   EventCapturer event_capturer_;
415   scoped_ptr<TouchExplorationControllerTestApi>
416       touch_exploration_controller_;
417   scoped_ptr<aura::test::TestCursorClient> cursor_client_;
418
419   DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
420 };
421
422 // Executes a number of assertions to confirm that |e1| and |e2| are touch
423 // events and are equal to each other.
424 void ConfirmEventsAreTouchAndEqual(ui::Event* e1, ui::Event* e2) {
425   ASSERT_TRUE(e1->IsTouchEvent());
426   ASSERT_TRUE(e2->IsTouchEvent());
427   ui::TouchEvent* touch_event1 = static_cast<ui::TouchEvent*>(e1);
428   ui::TouchEvent* touch_event2 = static_cast<ui::TouchEvent*>(e2);
429   EXPECT_EQ(touch_event1->type(), touch_event2->type());
430   EXPECT_EQ(touch_event1->location(), touch_event2->location());
431   EXPECT_EQ(touch_event1->touch_id(), touch_event2->touch_id());
432   EXPECT_EQ(touch_event1->flags(), touch_event2->flags());
433   EXPECT_EQ(touch_event1->time_stamp(), touch_event2->time_stamp());
434 }
435
436 // Executes a number of assertions to confirm that |e1| and |e2| are mouse
437 // events and are equal to each other.
438 void ConfirmEventsAreMouseAndEqual(ui::Event* e1, ui::Event* e2) {
439   ASSERT_TRUE(e1->IsMouseEvent());
440   ASSERT_TRUE(e2->IsMouseEvent());
441   ui::MouseEvent* mouse_event1 = static_cast<ui::MouseEvent*>(e1);
442   ui::MouseEvent* mouse_event2 = static_cast<ui::MouseEvent*>(e2);
443   EXPECT_EQ(mouse_event1->type(), mouse_event2->type());
444   EXPECT_EQ(mouse_event1->location(), mouse_event2->location());
445   EXPECT_EQ(mouse_event1->root_location(), mouse_event2->root_location());
446   EXPECT_EQ(mouse_event1->flags(), mouse_event2->flags());
447 }
448
449 // Executes a number of assertions to confirm that |e1| and |e2| are key events
450 // and are equal to each other.
451 void ConfirmEventsAreKeyAndEqual(ui::Event* e1, ui::Event* e2) {
452   ASSERT_TRUE(e1->IsKeyEvent());
453   ASSERT_TRUE(e2->IsKeyEvent());
454   ui::KeyEvent* key_event1 = static_cast<ui::KeyEvent*>(e1);
455   ui::KeyEvent* key_event2 = static_cast<ui::KeyEvent*>(e2);
456   EXPECT_EQ(key_event1->type(), key_event2->type());
457   EXPECT_EQ(key_event1->key_code(), key_event2->key_code());
458   EXPECT_EQ(key_event1->code(), key_event2->code());
459   EXPECT_EQ(key_event1->flags(), key_event2->flags());
460 }
461
462 #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \
463   ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2))
464
465 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \
466   ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2))
467
468 #define CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(e1, e2) \
469   ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreKeyAndEqual(e1, e2))
470
471 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit
472 // events when running these tests as part of ui_unittests. We do get them when
473 // the tests are run as part of ash unit tests.
474
475 // If a swipe has been successfully completed, then six key events will be
476 // dispatched that correspond to shift+search+direction
477 void AssertDirectionalNavigationEvents(const ScopedVector<ui::Event>& events,
478                                        ui::KeyboardCode direction) {
479   ASSERT_EQ(6U, events.size());
480   ui::KeyEvent shift_pressed(
481       ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
482   ui::KeyEvent search_pressed(
483       ui::ET_KEY_PRESSED, ui::VKEY_LWIN, ui::EF_SHIFT_DOWN);
484   ui::KeyEvent direction_pressed(
485       ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN);
486   ui::KeyEvent direction_released(
487       ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN);
488   ui::KeyEvent search_released(
489       ui::ET_KEY_RELEASED, VKEY_LWIN, ui::EF_SHIFT_DOWN);
490   ui::KeyEvent shift_released(
491       ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
492   CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&shift_pressed, events[0]);
493   CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&search_pressed, events[1]);
494   CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&direction_pressed, events[2]);
495   CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&direction_released, events[3]);
496   CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&search_released, events[4]);
497   CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(&shift_released, events[5]);
498 }
499
500 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) {
501   SwitchTouchExplorationMode(true);
502   EXPECT_FALSE(IsInTouchToMouseMode());
503   generator_->PressTouch();
504   AdvanceSimulatedTimePastTapDelay();
505   EXPECT_TRUE(IsInTouchToMouseMode());
506 }
507
508 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) {
509   int slop = gesture_detector_config_.touch_slop;
510   int half_slop = slop / 2;
511
512   SwitchTouchExplorationMode(true);
513   EXPECT_FALSE(IsInTouchToMouseMode());
514   generator_->set_current_location(gfx::Point(11, 12));
515   generator_->PressTouch();
516   generator_->MoveTouch(gfx::Point(11 + half_slop, 12));
517   EXPECT_FALSE(IsInTouchToMouseMode());
518   generator_->MoveTouch(gfx::Point(11, 12 + half_slop));
519   EXPECT_FALSE(IsInTouchToMouseMode());
520   AdvanceSimulatedTimePastTapDelay();
521   generator_->MoveTouch(gfx::Point(11 + slop + 1, 12));
522   EXPECT_TRUE(IsInTouchToMouseMode());
523 }
524
525 TEST_F(TouchExplorationTest, OneFingerTap) {
526   SwitchTouchExplorationMode(true);
527   gfx::Point location(11, 12);
528   generator_->set_current_location(location);
529   generator_->PressTouch();
530   generator_->ReleaseTouch();
531   AdvanceSimulatedTimePastTapDelay();
532
533   std::vector<ui::LocatedEvent*> events =
534       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
535   ASSERT_EQ(1U, events.size());
536
537   EXPECT_EQ(location, events[0]->location());
538   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
539   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
540   EXPECT_TRUE(IsInNoFingersDownState());
541 }
542
543 TEST_F(TouchExplorationTest, ActualMouseMovesUnaffected) {
544   SwitchTouchExplorationMode(true);
545
546   gfx::Point location_start(11, 12);
547   gfx::Point location_end(13, 14);
548   generator_->set_current_location(location_start);
549   generator_->PressTouch();
550   AdvanceSimulatedTimePastTapDelay();
551   generator_->MoveTouch(location_end);
552
553   gfx::Point location_real_mouse_move(15, 16);
554   ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
555                             location_real_mouse_move,
556                             location_real_mouse_move,
557                             0,
558                             0);
559   generator_->Dispatch(&mouse_move);
560   generator_->ReleaseTouch();
561   AdvanceSimulatedTimePastTapDelay();
562
563   std::vector<ui::LocatedEvent*> events =
564       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
565   ASSERT_EQ(4U, events.size());
566
567   EXPECT_EQ(location_start, events[0]->location());
568   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
569   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
570
571   EXPECT_EQ(location_end, events[1]->location());
572   EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
573   EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
574
575   // The real mouse move goes through.
576   EXPECT_EQ(location_real_mouse_move, events[2]->location());
577   CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(events[2], &mouse_move);
578   EXPECT_FALSE(events[2]->flags() & ui::EF_IS_SYNTHESIZED);
579   EXPECT_FALSE(events[2]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
580
581   // The touch release gets written as a mouse move.
582   EXPECT_EQ(location_end, events[3]->location());
583   EXPECT_TRUE(events[3]->flags() & ui::EF_IS_SYNTHESIZED);
584   EXPECT_TRUE(events[3]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
585   EXPECT_TRUE(IsInNoFingersDownState());
586 }
587
588 // Turn the touch exploration mode on in the middle of the touch gesture.
589 // Confirm that events from the finger which was touching when the mode was
590 // turned on don't get rewritten.
591 TEST_F(TouchExplorationTest, TurnOnMidTouch) {
592   SwitchTouchExplorationMode(false);
593   generator_->PressTouchId(1);
594   EXPECT_TRUE(cursor_client()->IsCursorVisible());
595   ClearCapturedEvents();
596
597   // Enable touch exploration mode while the first finger is touching the
598   // screen. Ensure that subsequent events from that first finger are not
599   // affected by the touch exploration mode, while the touch events from another
600   // finger get rewritten.
601   SwitchTouchExplorationMode(true);
602   ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED,
603                             gfx::Point(11, 12),
604                             1,
605                             Now());
606   generator_->Dispatch(&touch_move);
607   EXPECT_TRUE(cursor_client()->IsCursorVisible());
608   EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
609   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
610   ASSERT_EQ(1u, captured_events.size());
611   CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
612   ClearCapturedEvents();
613
614   // The press from the second finger should get rewritten.
615   generator_->PressTouchId(2);
616   AdvanceSimulatedTimePastTapDelay();
617   EXPECT_TRUE(IsInTouchToMouseMode());
618   captured_events = GetCapturedLocatedEvents();
619   std::vector<ui::LocatedEvent*>::const_iterator it;
620   for (it = captured_events.begin(); it != captured_events.end(); ++it) {
621     if ((*it)->type() == ui::ET_MOUSE_MOVED)
622       break;
623   }
624   EXPECT_NE(captured_events.end(), it);
625   ClearCapturedEvents();
626
627   // The release of the first finger shouldn't be affected.
628   ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED,
629                                gfx::Point(11, 12),
630                                1,
631                                Now());
632   generator_->Dispatch(&touch_release);
633   captured_events = GetCapturedLocatedEvents();
634   ASSERT_EQ(1u, captured_events.size());
635   CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
636   ClearCapturedEvents();
637
638   // The move and release from the second finger should get rewritten.
639   generator_->MoveTouchId(gfx::Point(13, 14), 2);
640   generator_->ReleaseTouchId(2);
641   AdvanceSimulatedTimePastTapDelay();
642   captured_events = GetCapturedLocatedEvents();
643   ASSERT_EQ(2u, captured_events.size());
644   EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
645   EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
646   EXPECT_TRUE(IsInNoFingersDownState());
647 }
648
649 // If an event is received after the double-tap timeout has elapsed, but
650 // before the timer has fired, a mouse move should still be generated.
651 TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) {
652   SwitchTouchExplorationMode(true);
653
654   // Make sure the touch is not in a corner of the screen.
655   generator_->MoveTouch(gfx::Point(100, 200));
656
657   // Send a press, then add another finger after the double-tap timeout.
658   generator_->PressTouchId(1);
659   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
660   generator_->PressTouchId(2);
661   std::vector<ui::LocatedEvent*> events =
662       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
663   ASSERT_EQ(1U, events.size());
664   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
665   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
666
667   generator_->ReleaseTouchId(2);
668   generator_->ReleaseTouchId(1);
669   AdvanceSimulatedTimePastTapDelay();
670   EXPECT_TRUE(IsInNoFingersDownState());
671 }
672
673 // If a new tap is received after the double-tap timeout has elapsed from
674 // a previous tap, but before the timer has fired, a mouse move should
675 // still be generated from the old tap.
676 TEST_F(TouchExplorationTest, TimerFiresLateAfterTap) {
677   SwitchTouchExplorationMode(true);
678
679   // Send a tap at location1.
680   gfx::Point location0(11, 12);
681   generator_->set_current_location(location0);
682   generator_->PressTouch();
683   generator_->ReleaseTouch();
684
685   // Send a tap at location2, after the double-tap timeout, but before the
686   // timer fires.
687   gfx::Point location1(33, 34);
688   generator_->set_current_location(location1);
689   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(301));
690   generator_->PressTouch();
691   generator_->ReleaseTouch();
692   AdvanceSimulatedTimePastTapDelay();
693
694   std::vector<ui::LocatedEvent*> events =
695       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
696   ASSERT_EQ(2U, events.size());
697   EXPECT_EQ(location0, events[0]->location());
698   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
699   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
700   EXPECT_EQ(location1, events[1]->location());
701   EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
702   EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
703   EXPECT_TRUE(IsInNoFingersDownState());
704 }
705
706 // Double-tapping should send a touch press and release through to the location
707 // of the last successful touch exploration.
708 TEST_F(TouchExplorationTest, DoubleTap) {
709   SwitchTouchExplorationMode(true);
710
711   // Tap at one location, and get a mouse move event.
712   gfx::Point tap_location(51, 52);
713   generator_->set_current_location(tap_location);
714   generator_->PressTouchId(1);
715   generator_->ReleaseTouchId(1);
716   AdvanceSimulatedTimePastTapDelay();
717
718   std::vector<ui::LocatedEvent*> events =
719       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
720   ASSERT_EQ(1U, events.size());
721
722   EXPECT_EQ(tap_location, events[0]->location());
723   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
724   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
725   ClearCapturedEvents();
726
727   // Now double-tap at a different location. This should result in
728   // a single touch press and release at the location of the tap,
729   // not at the location of the double-tap.
730   gfx::Point double_tap_location(33, 34);
731   generator_->set_current_location(double_tap_location);
732   generator_->PressTouch();
733   generator_->ReleaseTouch();
734   generator_->PressTouch();
735   generator_->ReleaseTouch();
736
737   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
738   ASSERT_EQ(2U, captured_events.size());
739   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
740   EXPECT_EQ(tap_location, captured_events[0]->location());
741   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
742   EXPECT_EQ(tap_location, captured_events[1]->location());
743   EXPECT_TRUE(IsInNoFingersDownState());
744 }
745
746 // Double-tapping where the user holds their finger down for the second time
747 // for a longer press should send a touch press and passthrough all further
748 // events from that finger. Other finger presses should be ignored.
749 TEST_F(TouchExplorationTest, DoubleTapPassthrough) {
750   SwitchTouchExplorationMode(true);
751
752   // Tap at one location, and get a mouse move event.
753   gfx::Point tap_location(11, 12);
754   generator_->set_current_location(tap_location);
755   generator_->PressTouch();
756   generator_->ReleaseTouch();
757   AdvanceSimulatedTimePastTapDelay();
758
759   std::vector<ui::LocatedEvent*> events =
760       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
761   ASSERT_EQ(1U, events.size());
762
763   EXPECT_EQ(tap_location, events[0]->location());
764   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
765   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
766   ClearCapturedEvents();
767
768   // Now double-tap and hold at a different location.
769   // This should result in a single touch press at the location of the tap,
770   // not at the location of the double-tap.
771   gfx::Point first_tap_location(13, 14);
772   generator_->set_current_location(first_tap_location);
773   generator_->PressTouchId(1);
774   generator_->ReleaseTouchId(1);
775   gfx::Point second_tap_location(15, 16);
776   generator_->set_current_location(second_tap_location);
777   generator_->PressTouchId(1);
778   // Advance to the finger passing through.
779   AdvanceSimulatedTimePastTapDelay();
780
781   gfx::Vector2d passthrough_offset = second_tap_location - tap_location;
782
783   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
784   ASSERT_EQ(1U, captured_events.size());
785   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
786   EXPECT_EQ(second_tap_location - passthrough_offset,
787             captured_events[0]->location());
788
789   ClearCapturedEvents();
790
791   // All events for the first finger should pass through now, displaced
792   // relative to the last touch exploration location.
793   gfx::Point first_move_location(17, 18);
794   generator_->MoveTouchId(first_move_location, 1);
795   gfx::Point second_move_location(12, 13);
796   generator_->MoveTouchId(second_move_location, 1);
797
798   captured_events = GetCapturedLocatedEvents();
799   ASSERT_EQ(2U, captured_events.size());
800   EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
801   EXPECT_EQ(first_move_location - passthrough_offset,
802             captured_events[0]->location());
803   EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[1]->type());
804   EXPECT_EQ(second_move_location - passthrough_offset,
805             captured_events[1]->location());
806
807   ClearCapturedEvents();
808
809   // Events for other fingers should do nothing.
810   generator_->PressTouchId(2);
811   generator_->PressTouchId(3);
812   generator_->MoveTouchId(gfx::Point(34, 36), 2);
813   generator_->ReleaseTouchId(2);
814   captured_events = GetCapturedLocatedEvents();
815   ASSERT_EQ(0U, captured_events.size());
816
817   // Even with finger 3 still down, events for the first finger should still
818   // pass through.
819   gfx::Point third_move_location(14, 15);
820   generator_->MoveTouchId(third_move_location, 1);
821   captured_events = GetCapturedLocatedEvents();
822   ASSERT_EQ(1U, captured_events.size());
823   EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
824   EXPECT_EQ(third_move_location - passthrough_offset,
825             captured_events[0]->location());
826
827   // No fingers down state is only reached when every finger is lifted.
828   generator_->ReleaseTouchId(1);
829   EXPECT_FALSE(IsInNoFingersDownState());
830   generator_->ReleaseTouchId(3);
831   EXPECT_TRUE(IsInNoFingersDownState());
832 }
833
834 // Double-tapping, going into passthrough, and holding for the longpress
835 // time should send a touch press and released (right click)
836 // to the location of the last successful touch exploration.
837 TEST_F(TouchExplorationTest, DoubleTapLongPress) {
838   SwitchTouchExplorationMode(true);
839   SetTickClock();
840   // Tap at one location, and get a mouse move event.
841   gfx::Point tap_location(11, 12);
842   generator_->set_current_location(tap_location);
843   generator_->PressTouch();
844   generator_->ReleaseTouch();
845   AdvanceSimulatedTimePastTapDelay();
846
847   std::vector<ui::LocatedEvent*> events =
848       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
849   ASSERT_EQ(1U, events.size());
850   EXPECT_EQ(tap_location, events[0]->location());
851   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
852   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
853   ClearCapturedEvents();
854
855   // Now double-tap and hold at a different location.
856   // This should result in a single touch long press and release
857   // at the location of the tap, not at the location of the double-tap.
858   // There should be a time delay between the touch press and release.
859   gfx::Point first_tap_location(33, 34);
860   generator_->set_current_location(first_tap_location);
861   generator_->PressTouch();
862   generator_->ReleaseTouch();
863   gfx::Point second_tap_location(23, 24);
864   generator_->set_current_location(second_tap_location);
865   generator_->PressTouch();
866   // Advance to the finger passing through, and then to the longpress timeout.
867   AdvanceSimulatedTimePastTapDelay();
868   simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
869   generator_->ReleaseTouch();
870
871   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
872   ASSERT_EQ(2U, captured_events.size());
873   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
874   EXPECT_EQ(tap_location, captured_events[0]->location());
875   base::TimeDelta pressed_time = captured_events[0]->time_stamp();
876   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
877   EXPECT_EQ(tap_location, captured_events[1]->location());
878   base::TimeDelta released_time = captured_events[1]->time_stamp();
879   EXPECT_EQ(released_time - pressed_time,
880             gesture_detector_config_.longpress_timeout);
881 }
882
883 // Single-tapping should send a touch press and release through to the location
884 // of the last successful touch exploration if the grace period has not
885 // elapsed.
886 TEST_F(TouchExplorationTest, SingleTap) {
887   SwitchTouchExplorationMode(true);
888
889   // Tap once to simulate a mouse moved event.
890   gfx::Point initial_location(11, 12);
891   generator_->set_current_location(initial_location);
892   generator_->PressTouch();
893   AdvanceSimulatedTimePastTapDelay();
894   ClearCapturedEvents();
895
896   // Move to another location for single tap
897   gfx::Point tap_location(22, 23);
898   generator_->MoveTouch(tap_location);
899   generator_->ReleaseTouch();
900
901   // Allow time to pass within the grace period of releasing before
902   // tapping again.
903   gfx::Point final_location(33, 34);
904   generator_->set_current_location(final_location);
905   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(250));
906   generator_->PressTouch();
907   generator_->ReleaseTouch();
908
909   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
910   ASSERT_EQ(4U, captured_events.size());
911   EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
912   EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
913   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type());
914   EXPECT_EQ(tap_location, captured_events[2]->location());
915   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[3]->type());
916   EXPECT_EQ(tap_location, captured_events[3]->location());
917 }
918
919 // Double-tapping without coming from touch exploration (no previous touch
920 // exploration event) should not generate any events.
921 TEST_F(TouchExplorationTest, DoubleTapNoTouchExplore) {
922   SwitchTouchExplorationMode(true);
923
924   // Double-tap without any previous touch.
925   // Touch exploration mode has not been entered, so there is no previous
926   // touch exploration event. The double-tap should be discarded, and no events
927   // should be generated at all.
928   gfx::Point double_tap_location(33, 34);
929   generator_->set_current_location(double_tap_location);
930   generator_->PressTouch();
931   generator_->ReleaseTouch();
932   generator_->PressTouch();
933   // Since the state stays in single_tap_released, we need to make sure the
934   // tap timer doesn't fire and set the state to no fingers down (since there
935   // is still a finger down).
936   AdvanceSimulatedTimePastPotentialTapDelay();
937   EXPECT_FALSE(IsInNoFingersDownState());
938   generator_->ReleaseTouch();
939   EXPECT_TRUE(IsInNoFingersDownState());
940
941   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
942   ASSERT_EQ(0U, captured_events.size());
943 }
944
945 // Tapping and releasing with a second finger when in touch exploration mode
946 // should send a touch press and released to the location of the last
947 // successful touch exploration and return to touch explore.
948 TEST_F(TouchExplorationTest, SplitTap) {
949   SwitchTouchExplorationMode(true);
950   gfx::Point initial_touch_location(11, 12);
951   gfx::Point second_touch_location(33, 34);
952
953   // Tap and hold at one location, and get a mouse move event in touch explore.
954   EnterTouchExplorationModeAtLocation(initial_touch_location);
955   std::vector<ui::LocatedEvent*> events =
956       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
957   ASSERT_EQ(1U, events.size());
958
959   EXPECT_EQ(initial_touch_location, events[0]->location());
960   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
961   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
962   ClearCapturedEvents();
963   EXPECT_TRUE(IsInTouchToMouseMode());
964
965   // Now tap and release at a different location. This should result in a
966   // single touch and release at the location of the first (held) tap,
967   // not at the location of the second tap and release.
968   // After the release, there is still a finger in touch explore mode.
969   ui::TouchEvent split_tap_press(
970       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
971   generator_->Dispatch(&split_tap_press);
972   // To simulate the behavior of the real device, we manually disable
973   // mouse events. To not rely on manually setting the state, this is also
974   // tested in touch_exploration_controller_browsertest.
975   cursor_client()->DisableMouseEvents();
976   EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
977   EXPECT_FALSE(cursor_client()->IsCursorVisible());
978   EXPECT_FALSE(IsInGestureInProgressState());
979   ui::TouchEvent split_tap_release(
980       ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
981   generator_->Dispatch(&split_tap_release);
982   // Releasing the second finger should re-enable mouse events putting us
983   // back into the touch exploration mode.
984   EXPECT_TRUE(IsInTouchToMouseMode());
985   EXPECT_FALSE(IsInNoFingersDownState());
986
987   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
988   ASSERT_EQ(2U, captured_events.size());
989   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
990   EXPECT_EQ(initial_touch_location, captured_events[0]->location());
991   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
992   EXPECT_EQ(initial_touch_location, captured_events[1]->location());
993   ClearCapturedEvents();
994
995   ui::TouchEvent touch_explore_release(
996       ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
997   generator_->Dispatch(&touch_explore_release);
998   AdvanceSimulatedTimePastTapDelay();
999   EXPECT_TRUE(IsInNoFingersDownState());
1000 }
1001
1002 // If split tap is started but the touch explore finger is released first,
1003 // there should still be a touch press and release sent to the location of
1004 // the last successful touch exploration.
1005 // Both fingers should be released after the click goes through.
1006 TEST_F(TouchExplorationTest, SplitTapRelease) {
1007   SwitchTouchExplorationMode(true);
1008
1009   gfx::Point initial_touch_location(11, 12);
1010   gfx::Point second_touch_location(33, 34);
1011
1012   // Tap and hold at one location, and get a mouse move event in touch explore.
1013   EnterTouchExplorationModeAtLocation(initial_touch_location);
1014
1015   std::vector<ui::LocatedEvent*> events =
1016       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
1017   ASSERT_EQ(1U, events.size());
1018
1019   ClearCapturedEvents();
1020
1021   // Now tap at a different location. Release at the first location,
1022   // then release at the second. This should result in a
1023   // single touch and release at the location of the first (held) tap,
1024   // not at the location of the second tap and release.
1025   ui::TouchEvent split_tap_press(
1026       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
1027   generator_->Dispatch(&split_tap_press);
1028   ui::TouchEvent touch_explore_release(
1029       ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
1030   generator_->Dispatch(&touch_explore_release);
1031   ui::TouchEvent split_tap_release(
1032       ui::ET_TOUCH_RELEASED, second_touch_location , 1, Now());
1033   generator_->Dispatch(&split_tap_release);
1034   EXPECT_TRUE(IsInNoFingersDownState());
1035
1036   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
1037   ASSERT_EQ(2U, captured_events.size());
1038   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
1039   EXPECT_EQ(initial_touch_location, captured_events[0]->location());
1040   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
1041   EXPECT_EQ(initial_touch_location, captured_events[1]->location());
1042 }
1043
1044 // When in touch exploration mode, making a long press with a second finger
1045 // should send a touch press and released to the location of the last
1046 // successful touch exploration. There should be a delay between the
1047 // touch and release events (right click).
1048 TEST_F(TouchExplorationTest, SplitTapLongPress) {
1049   SwitchTouchExplorationMode(true);
1050   gfx::Point initial_touch_location(11, 12);
1051   gfx::Point second_touch_location(33, 34);
1052
1053   // Tap and hold at one location, and get a mouse move event in touch explore.
1054   EnterTouchExplorationModeAtLocation(initial_touch_location);
1055   std::vector<ui::LocatedEvent*> events =
1056       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
1057   ASSERT_EQ(1U, events.size());
1058
1059   ClearCapturedEvents();
1060
1061   // Now tap, hold, and release at a different location. This should result
1062   // in a single touch and release (long press) at the location of the first
1063   // (held) tap, not at the location of the second tap and release.
1064   ui::TouchEvent split_tap_press(
1065       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
1066   generator_->Dispatch(&split_tap_press);
1067   // To simulate the behavior of the real device, we manually disable
1068   // mouse events, like in the SplitTap test.
1069   cursor_client()->DisableMouseEvents();
1070   EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
1071   EXPECT_FALSE(cursor_client()->IsCursorVisible());
1072   EXPECT_FALSE(IsInGestureInProgressState());
1073   simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
1074   // After the release, there is still a finger in touch exploration, and
1075   // mouse events should be enabled again.
1076   ui::TouchEvent split_tap_release(
1077       ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
1078   generator_->Dispatch(&split_tap_release);
1079   EXPECT_FALSE(IsInNoFingersDownState());
1080   EXPECT_TRUE(IsInTouchToMouseMode());
1081
1082   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
1083   ASSERT_EQ(2U, captured_events.size());
1084   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
1085   EXPECT_EQ(initial_touch_location, captured_events[0]->location());
1086   base::TimeDelta pressed_time = captured_events[0]->time_stamp();
1087   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
1088   EXPECT_EQ(initial_touch_location, captured_events[1]->location());
1089   base::TimeDelta released_time = captured_events[1]->time_stamp();
1090   EXPECT_EQ(gesture_detector_config_.longpress_timeout,
1091             released_time - pressed_time);
1092 }
1093
1094 // If split tap is started but the touch explore finger is released first,
1095 // there should still be a touch press and release sent to the location of
1096 // the last successful touch exploration. If the remaining finger is held
1097 // as a longpress, there should be a delay between the sent touch and release
1098 // events (right click).All fingers should be released after the click
1099 // goes through.
1100 TEST_F(TouchExplorationTest, SplitTapReleaseLongPress) {
1101   SwitchTouchExplorationMode(true);
1102   gfx::Point initial_touch_location(11, 12);
1103   gfx::Point second_touch_location(33, 34);
1104
1105   // Tap and hold at one location, and get a mouse move event in touch explore.
1106   EnterTouchExplorationModeAtLocation(initial_touch_location);
1107   std::vector<ui::LocatedEvent*> events =
1108       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
1109   ASSERT_EQ(1U, events.size());
1110   ClearCapturedEvents();
1111
1112   // Now tap at a different location. Release at the first location,
1113   // then release at the second. This should result in a
1114   // single touch and release at the location of the first (held) tap,
1115   // not at the location of the second tap and release.
1116   // After the release, TouchToMouseMode should still be on.
1117   ui::TouchEvent split_tap_press(
1118       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
1119   generator_->Dispatch(&split_tap_press);
1120   ui::TouchEvent touch_explore_release(
1121       ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
1122   generator_->Dispatch(&touch_explore_release);
1123   simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
1124   ui::TouchEvent split_tap_release(
1125       ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
1126   generator_->Dispatch(&split_tap_release);
1127   EXPECT_TRUE(IsInTouchToMouseMode());
1128
1129   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
1130   ASSERT_EQ(2U, captured_events.size());
1131   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
1132   EXPECT_EQ(initial_touch_location, captured_events[0]->location());
1133   base::TimeDelta pressed_time = captured_events[0]->time_stamp();
1134   EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
1135   EXPECT_EQ(initial_touch_location, captured_events[1]->location());
1136   base::TimeDelta released_time = captured_events[1]->time_stamp();
1137   EXPECT_EQ(gesture_detector_config_.longpress_timeout,
1138             released_time - pressed_time);
1139  }
1140
1141 TEST_F(TouchExplorationTest, SplitTapMultiFinger) {
1142   SwitchTouchExplorationMode(true);
1143   gfx::Point initial_touch_location(11, 12);
1144   gfx::Point second_touch_location(33, 34);
1145   gfx::Point third_touch_location(16, 17);
1146
1147   // Tap and hold at one location, and get a mouse move event in touch explore.
1148   EnterTouchExplorationModeAtLocation(initial_touch_location);
1149
1150   std::vector<ui::LocatedEvent*> events =
1151       GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
1152   ASSERT_EQ(1U, events.size());
1153
1154   EXPECT_EQ(initial_touch_location, events[0]->location());
1155   EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
1156   EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
1157   ClearCapturedEvents();
1158
1159   // Now tap at a different location and hold for long press.
1160   ui::TouchEvent split_tap_press(
1161       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
1162   generator_->Dispatch(&split_tap_press);
1163   simulated_clock_->Advance(gesture_detector_config_.longpress_timeout);
1164
1165   // Placing a third finger on the screen should cancel the initial press and
1166   // enter the wait state.
1167   ui::TouchEvent third_press(
1168       ui::ET_TOUCH_PRESSED, third_touch_location, 2, Now());
1169   generator_->Dispatch(&third_press);
1170
1171   // When all three fingers are released, the only events captured should be a
1172   // press and touch cancel. All fingers should then be up.
1173   ui::TouchEvent touch_explore_release(
1174       ui::ET_TOUCH_RELEASED, initial_touch_location, 0, Now());
1175   generator_->Dispatch(&touch_explore_release);
1176   ui::TouchEvent split_tap_release(
1177       ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
1178   generator_->Dispatch(&split_tap_release);
1179   ui::TouchEvent third_tap_release(
1180       ui::ET_TOUCH_RELEASED, third_touch_location, 2, Now());
1181   generator_->Dispatch(&third_tap_release);
1182
1183   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
1184   ASSERT_EQ(2U, captured_events.size());
1185   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
1186   EXPECT_EQ(initial_touch_location, captured_events[0]->location());
1187   EXPECT_EQ(ui::ET_TOUCH_CANCELLED, captured_events[1]->type());
1188   EXPECT_EQ(initial_touch_location, captured_events[1]->location());
1189   EXPECT_TRUE(IsInNoFingersDownState());
1190 }
1191
1192
1193 TEST_F(TouchExplorationTest, SplitTapLeaveSlop) {
1194   SwitchTouchExplorationMode(true);
1195   gfx::Point first_touch_location(11, 12);
1196   gfx::Point second_touch_location(33, 34);
1197   gfx::Point first_move_location(
1198       first_touch_location.x() + gesture_detector_config_.touch_slop * 3 + 1,
1199       first_touch_location.y());
1200   gfx::Point second_move_location(
1201       second_touch_location.x() + gesture_detector_config_.touch_slop * 3 + 1,
1202       second_touch_location.y());
1203
1204   // Tap and hold at one location, and get a mouse move event in touch explore.
1205   EnterTouchExplorationModeAtLocation(first_touch_location);
1206   ClearCapturedEvents();
1207
1208   // Now tap at a different location for split tap.
1209   ui::TouchEvent split_tap_press(
1210       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
1211   generator_->Dispatch(&split_tap_press);
1212
1213   // Move the first finger out of slop and release both fingers. The split
1214   // tap should have been cancelled, so a touch press and touch cancel event
1215   // should go through at the last touch exploration location (the first press).
1216   ui::TouchEvent first_touch_move(
1217       ui::ET_TOUCH_MOVED, first_move_location, 0, Now());
1218   generator_->Dispatch(&first_touch_move);
1219   ui::TouchEvent first_touch_release(
1220       ui::ET_TOUCH_RELEASED, first_move_location, 0, Now());
1221   generator_->Dispatch(&first_touch_release);
1222   ui::TouchEvent second_touch_release(
1223       ui::ET_TOUCH_RELEASED, second_touch_location, 1, Now());
1224   generator_->Dispatch(&second_touch_release);
1225
1226   std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
1227   ASSERT_EQ(2U, captured_events.size());
1228   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
1229   EXPECT_EQ(first_touch_location, captured_events[0]->location());
1230   EXPECT_EQ(ui::ET_TOUCH_CANCELLED, captured_events[1]->type());
1231   EXPECT_EQ(first_touch_location, captured_events[1]->location());
1232   EXPECT_TRUE(IsInNoFingersDownState());
1233
1234   // Now do the same, but moving the split tap finger out of slop
1235   EnterTouchExplorationModeAtLocation(first_touch_location);
1236   ClearCapturedEvents();
1237   ui::TouchEvent split_tap_press2(
1238       ui::ET_TOUCH_PRESSED, second_touch_location, 1, Now());
1239   generator_->Dispatch(&split_tap_press2);
1240
1241   // Move the second finger out of slop and release both fingers. The split
1242   // tap should have been cancelled, so a touch press and touch cancel event
1243   // should go through at the last touch exploration location (the first press).
1244   ui::TouchEvent second_touch_move2(
1245       ui::ET_TOUCH_MOVED, second_move_location, 1, Now());
1246   generator_->Dispatch(&second_touch_move2);
1247   ui::TouchEvent first_touch_release2(
1248       ui::ET_TOUCH_RELEASED, first_touch_location, 0, Now());
1249   generator_->Dispatch(&first_touch_release2);
1250   ui::TouchEvent second_touch_release2(
1251       ui::ET_TOUCH_RELEASED, second_move_location, 1, Now());
1252   generator_->Dispatch(&second_touch_release2);
1253
1254   captured_events = GetCapturedLocatedEvents();
1255   ASSERT_EQ(2U, captured_events.size());
1256   EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
1257   EXPECT_EQ(first_touch_location, captured_events[0]->location());
1258   EXPECT_EQ(ui::ET_TOUCH_CANCELLED, captured_events[1]->type());
1259   EXPECT_EQ(first_touch_location, captured_events[1]->location());
1260   EXPECT_TRUE(IsInNoFingersDownState());
1261 }
1262
1263 // Finger must have moved more than slop, faster than the minimum swipe
1264 // velocity, and before the tap timer fires in order to enter
1265 // GestureInProgress state. Otherwise, if the tap timer fires before the a
1266 // gesture is completed, enter touch exploration.
1267 TEST_F(TouchExplorationTest, EnterGestureInProgressState) {
1268   SwitchTouchExplorationMode(true);
1269   EXPECT_FALSE(IsInTouchToMouseMode());
1270   EXPECT_FALSE(IsInGestureInProgressState());
1271
1272   float distance = gesture_detector_config_.touch_slop + 1;
1273   ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 1), 0, Now());
1274   gfx::Point second_location(distance / 2, 1);
1275   gfx::Point third_location(distance, 1);
1276   gfx::Point touch_exploration_location(20, 21);
1277
1278   generator_->Dispatch(&first_press);
1279   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1280   // Since we are not out of the touch slop yet, we should not be in gesture in
1281   // progress.
1282   generator_->MoveTouch(second_location);
1283   EXPECT_FALSE(IsInTouchToMouseMode());
1284   EXPECT_FALSE(IsInGestureInProgressState());
1285   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1286
1287   // Once we are out of slop, we should be in GestureInProgress.
1288   generator_->MoveTouch(third_location);
1289   EXPECT_TRUE(IsInGestureInProgressState());
1290   EXPECT_FALSE(IsInTouchToMouseMode());
1291   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1292   ASSERT_EQ(0U, captured_events.size());
1293
1294   // Exit out of gesture mode once grace period is over and enter touch
1295   // exploration. There should be a move when entering touch exploration and
1296   // also for the touch move.
1297   AdvanceSimulatedTimePastTapDelay();
1298   generator_->MoveTouch(touch_exploration_location);
1299   ASSERT_EQ(2U, captured_events.size());
1300   EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
1301   EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
1302   EXPECT_TRUE(IsInTouchToMouseMode());
1303   EXPECT_FALSE(IsInGestureInProgressState());
1304 }
1305
1306 // A swipe+direction gesture should trigger a Shift+Search+Direction
1307 // keyboard event.
1308 TEST_F(TouchExplorationTest, GestureSwipe) {
1309   SwitchTouchExplorationMode(true);
1310   std::vector<ui::KeyboardCode> directions;
1311   directions.push_back(ui::VKEY_RIGHT);
1312   directions.push_back(ui::VKEY_LEFT);
1313   directions.push_back(ui::VKEY_UP);
1314   directions.push_back(ui::VKEY_DOWN);
1315
1316   // This value was taken from gesture_recognizer_unittest.cc in a swipe
1317   // detector test, since it seems to be about the right amount to get a swipe.
1318   const int kSteps = 15;
1319
1320   // There are gestures supported with up to four fingers.
1321   for (int num_fingers = 1; num_fingers <= 4; num_fingers++) {
1322     std::vector<gfx::Point> start_points;
1323     for (int j = 0; j < num_fingers; j++) {
1324       start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 200));
1325     }
1326     gfx::Point* start_points_array = &start_points[0];
1327     const float distance = gesture_detector_config_.touch_slop + 1;
1328     // Iterate through each swipe direction for this number of fingers.
1329     for (std::vector<ui::KeyboardCode>::const_iterator it = directions.begin();
1330          it != directions.end();
1331          ++it) {
1332       int move_x = 0;
1333       int move_y = 0;
1334       ui::KeyboardCode direction = *it;
1335       switch (direction) {
1336         case ui::VKEY_RIGHT:
1337           move_x = distance;
1338           break;
1339         case ui::VKEY_LEFT:
1340           move_x = 0 - distance;
1341           break;
1342         case ui::VKEY_UP:
1343           move_y = 0 - distance;
1344           break;
1345         case ui::VKEY_DOWN:
1346           move_y = distance;
1347           break;
1348         default:
1349           return;
1350       }
1351
1352       // A swipe is made when a fling starts
1353       float delta_time =
1354           distance / gesture_detector_config_.maximum_fling_velocity;
1355       // delta_time is in seconds, so we convert to ms.
1356       int delta_time_ms = floor(delta_time * 1000);
1357       generator_->GestureMultiFingerScroll(num_fingers,
1358                                            start_points_array,
1359                                            delta_time_ms,
1360                                            kSteps,
1361                                            move_x * 2,
1362                                            move_y * 2);
1363
1364       // The swipe registered and sent the appropriate key events.
1365       const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1366       if (num_fingers == 1)
1367         AssertDirectionalNavigationEvents(captured_events, direction);
1368       else {
1369         // Most of the time this is 2 right now, but two of the two finger
1370         // swipes are mapped to chromevox commands which dispatch 6 key events,
1371         // and these will probably be remapped a lot as we're developing.
1372         ASSERT_GE(captured_events.size(), 2U);
1373         std::vector<ui::Event>::size_type i;
1374         for (i = 0; i != captured_events.size(); i++) {
1375           EXPECT_TRUE(captured_events[i]->IsKeyEvent());
1376         }
1377       }
1378       EXPECT_TRUE(IsInNoFingersDownState());
1379       EXPECT_FALSE(IsInTouchToMouseMode());
1380       EXPECT_FALSE(IsInGestureInProgressState());
1381       ClearCapturedEvents();
1382     }
1383   }
1384 }
1385
1386 // Since there are so many permutations, this test is fairly slow. Therefore, it
1387 // is disabled and will be turned on to check during development.
1388
1389 TEST_F(TouchExplorationTest, DISABLED_AllFingerPermutations) {
1390   SwitchTouchExplorationMode(true);
1391   SuppressVLOGs(true);
1392   // We will test all permutations of events from three different fingers
1393   // to ensure that we return to NO_FINGERS_DOWN when fingers have been
1394   // released.
1395   ScopedVector<ui::TouchEvent> all_events;
1396   for (int touch_id = 0; touch_id < 3; touch_id++){
1397     int x = 10*touch_id + 1;
1398     int y = 10*touch_id + 2;
1399     all_events.push_back(new TouchEvent(
1400         ui::ET_TOUCH_PRESSED, gfx::Point(x++, y++), touch_id, Now()));
1401     all_events.push_back(new TouchEvent(
1402         ui::ET_TOUCH_MOVED, gfx::Point(x++, y++), touch_id, Now()));
1403     all_events.push_back(new TouchEvent(
1404         ui::ET_TOUCH_RELEASED, gfx::Point(x, y), touch_id, Now()));
1405   }
1406
1407   // I'm going to explain this algorithm, and use an example in parentheses.
1408   // The example will be all permutations of a b c d.
1409   // There are four letters and 4! = 24 permutations.
1410   const int num_events = all_events.size();
1411   const int num_permutations = Factorial(num_events);
1412
1413   for (int p = 0; p < num_permutations; p++) {
1414     std::vector<ui::TouchEvent*> queued_events = all_events.get();
1415     std::vector<bool> fingers_pressed(3, false);
1416
1417     int current_num_permutations = num_permutations;
1418     for (int events_left = num_events; events_left > 0; events_left--) {
1419       // |p| indexes to each permutation when there are num_permutations
1420       // permutations. (e.g. 0 is abcd, 1 is abdc, 2 is acbd, 3 is acdb...)
1421       // But how do we find the index for the current number of permutations?
1422       // To find the permutation within the part of the sequence we're
1423       // currently looking at, we need a number between 0 and
1424       // |current_num_permutations| - 1.
1425       // (e.g. if we already chose the first letter, there are 3! = 6
1426       // options left, so we do p % 6. So |current_permutation| would go
1427       // from 0 to 5 and then reset to 0 again, for all combinations of
1428       // whichever three letters are remaining, as we loop through the
1429       // permutations)
1430       int current_permutation = p % current_num_permutations;
1431
1432       // Since this is is the total number of permutations starting with
1433       // this event and including future events, there could be multiple
1434       // values of current_permutation that will generate the same event
1435       // in this iteration.
1436       // (e.g. If we chose 'a' but have b c d to choose from, we choose b when
1437       // |current_permutation| = 0, 1 and c when |current_permutation| = 2, 3.
1438       // Note that each letter gets two numbers, which is the next
1439       // current_num_permutations, 2! for the two letters left.)
1440
1441       // Branching out from the first event, there are num_permutations
1442       // permutations, and each value of |p| is associated with one of these
1443       // permutations. However, once the first event is chosen, there
1444       // are now |num_events| - 1 events left, so the number of permutations
1445       // for the rest of the events changes, and will always be equal to
1446       // the factorial of the events_left.
1447       // (e.g. There are 3! = 6 permutations that start with 'a', so if we
1448       // start with 'a' there will be 6 ways to then choose from b c d.)
1449       // So we now set-up for the next iteration by setting
1450       // current_num_permutations to the factorial of the next number of
1451       // events left.
1452       current_num_permutations /= events_left;
1453
1454       // To figure out what current event we want to choose, we integer
1455       // divide the current permutation by the next current_num_permutations.
1456       // (e.g. If there are 4 letters a b c d and 24 permutations, we divide
1457       // by 24/4 = 6. Values 0 to 5 when divided by 6 equals 0, so the first
1458       // 6 permutations start with 'a', and the last 6 will start with 'd'.
1459       // Note that there are 6 that start with 'a' because there are 6
1460       // permutations for the next three letters that follow 'a'.)
1461       int index = current_permutation / current_num_permutations;
1462
1463       ui::TouchEvent* next_dispatch = queued_events[index];
1464       ASSERT_TRUE(next_dispatch != NULL);
1465
1466       // |next_dispatch| has to be put in this container so that its time
1467       // stamp can be changed to this point in the test, when it is being
1468       // dispatched..
1469       EventTestApi test_dispatch(next_dispatch);
1470       test_dispatch.set_time_stamp(Now());
1471       generator_->Dispatch(next_dispatch);
1472       queued_events.erase(queued_events.begin() + index);
1473
1474       // Keep track of what fingers have been pressed, to release
1475       // only those fingers at the end, so the check for being in
1476       // no fingers down can be accurate.
1477       if (next_dispatch->type() == ET_TOUCH_PRESSED) {
1478         fingers_pressed[next_dispatch->touch_id()] = true;
1479       } else if (next_dispatch->type() == ET_TOUCH_RELEASED) {
1480         fingers_pressed[next_dispatch->touch_id()] = false;
1481       }
1482     }
1483     ASSERT_EQ(queued_events.size(), 0u);
1484
1485     // Release fingers recorded as pressed.
1486     for(int j = 0; j < int(fingers_pressed.size()); j++){
1487       if (fingers_pressed[j] == true) {
1488         generator_->ReleaseTouchId(j);
1489         fingers_pressed[j] = false;
1490       }
1491     }
1492     AdvanceSimulatedTimePastPotentialTapDelay();
1493     EXPECT_TRUE(IsInNoFingersDownState());
1494     ClearCapturedEvents();
1495   }
1496 }
1497
1498 // With the simple swipe gestures, if additional fingers are added and the tap
1499 // timer times out, then the state should change to the wait for one finger
1500 // state.
1501 TEST_F(TouchExplorationTest, GestureAddedFinger) {
1502   SwitchTouchExplorationMode(true);
1503   EXPECT_FALSE(IsInTouchToMouseMode());
1504   EXPECT_FALSE(IsInGestureInProgressState());
1505
1506   float distance = gesture_detector_config_.touch_slop + 1;
1507   ui::TouchEvent first_press(
1508       ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), 0, Now());
1509   generator_->Dispatch(&first_press);
1510   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1511   gfx::Point second_location(100 + distance, 200);
1512   generator_->MoveTouch(second_location);
1513   EXPECT_TRUE(IsInGestureInProgressState());
1514   EXPECT_FALSE(IsInTouchToMouseMode());
1515   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1516   ASSERT_EQ(0U, captured_events.size());
1517
1518   // Generate a second press, but time out past the gesture period so that
1519   // gestures are prevented from continuing to go through.
1520   ui::TouchEvent second_press(
1521       ui::ET_TOUCH_PRESSED, gfx::Point(20, 21), 1, Now());
1522   generator_->Dispatch(&second_press);
1523   AdvanceSimulatedTimePastTapDelay();
1524   EXPECT_FALSE(IsInGestureInProgressState());
1525   EXPECT_FALSE(IsInTouchToMouseMode());
1526   ASSERT_EQ(0U, captured_events.size());
1527 }
1528
1529 TEST_F(TouchExplorationTest, EnterSlideGestureState) {
1530   SwitchTouchExplorationMode(true);
1531   EXPECT_FALSE(IsInTouchToMouseMode());
1532   EXPECT_FALSE(IsInGestureInProgressState());
1533
1534   int window_right = BoundsOfRootWindowInDIP().right();
1535   float distance = gesture_detector_config_.touch_slop + 1;
1536   ui::TouchEvent first_press(
1537       ui::ET_TOUCH_PRESSED, gfx::Point(window_right, 1), 0, Now());
1538   gfx::Point second_location(window_right, 1 + distance / 2);
1539   gfx::Point third_location(window_right, 1 + distance);
1540   gfx::Point fourth_location(window_right, 35);
1541
1542   generator_->Dispatch(&first_press);
1543   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1544
1545   // Since we haven't moved past slop yet, we should not be in slide gesture.
1546   generator_->MoveTouch(second_location);
1547   EXPECT_FALSE(IsInTouchToMouseMode());
1548   EXPECT_FALSE(IsInGestureInProgressState());
1549   EXPECT_FALSE(IsInSlideGestureState());
1550   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1551
1552   // Once we are out of slop, we should be in slide gesture since we are along
1553   // the edge of the screen.
1554   generator_->MoveTouch(third_location);
1555   EXPECT_FALSE(IsInGestureInProgressState());
1556   EXPECT_TRUE(IsInSlideGestureState());
1557   EXPECT_FALSE(IsInTouchToMouseMode());
1558
1559   // Now that we are in slide gesture, we can adjust the volume.
1560   generator_->MoveTouch(fourth_location);
1561   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1562   ASSERT_EQ(0U, captured_events.size());
1563
1564   // Since we are at the right edge of the screen, but the sound timer has not
1565   // elapsed, there should have been a sound that fired and a volume
1566   // change.
1567   size_t num_adjust_sounds = delegate_.NumAdjustSounds();
1568   ASSERT_EQ(1U, num_adjust_sounds);
1569   ASSERT_EQ(1U, delegate_.VolumeChanges().size());
1570
1571   // Exit out of slide gesture once touch is lifted, but not before even if the
1572   // grace period is over.
1573   AdvanceSimulatedTimePastPotentialTapDelay();
1574   ASSERT_EQ(0U, captured_events.size());
1575   EXPECT_FALSE(IsInTouchToMouseMode());
1576   EXPECT_FALSE(IsInGestureInProgressState());
1577   EXPECT_TRUE(IsInSlideGestureState());
1578
1579   generator_->ReleaseTouch();
1580   ASSERT_EQ(0U, captured_events.size());
1581   EXPECT_FALSE(IsInTouchToMouseMode());
1582   EXPECT_FALSE(IsInGestureInProgressState());
1583   EXPECT_FALSE(IsInSlideGestureState());
1584 }
1585
1586 // If a press + move occurred outside the boundaries, but within the slop
1587 // boundaries and then moved into the boundaries of an edge, there still should
1588 // not be a slide gesture.
1589 TEST_F(TouchExplorationTest, AvoidEnteringSlideGesture) {
1590   SwitchTouchExplorationMode(true);
1591
1592   gfx::Rect window = BoundsOfRootWindowInDIP();
1593   float distance = gesture_detector_config_.touch_slop + 1;
1594   ui::TouchEvent first_press(
1595       ui::ET_TOUCH_PRESSED,
1596       gfx::Point(window.right() - GetSlopDistanceFromEdge(), 1),
1597       0,
1598       Now());
1599   gfx::Point out_of_slop(window.right() - GetSlopDistanceFromEdge() + distance,
1600                          1);
1601   gfx::Point into_boundaries(window.right() - GetMaxDistanceFromEdge() / 2, 1);
1602
1603   generator_->Dispatch(&first_press);
1604   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1605
1606   generator_->MoveTouch(out_of_slop);
1607   EXPECT_FALSE(IsInTouchToMouseMode());
1608   EXPECT_TRUE(IsInGestureInProgressState());
1609   EXPECT_FALSE(IsInSlideGestureState());
1610   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1611
1612   // Since we did not start moving while in the boundaries, we should not be in
1613   // slide gestures.
1614   generator_->MoveTouch(into_boundaries);
1615   EXPECT_TRUE(IsInGestureInProgressState());
1616   EXPECT_FALSE(IsInSlideGestureState());
1617   EXPECT_FALSE(IsInTouchToMouseMode());
1618   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1619   ASSERT_EQ(0U, captured_events.size());
1620
1621   generator_->ReleaseTouch();
1622 }
1623
1624 // If the slide gesture begins within the boundaries and then moves
1625 // SlopDistanceFromEdge there should still be a sound change. If the finger
1626 // moves into the center screen, there should no longer be a sound change but it
1627 // should still be in slide gesture. If the finger moves back into the edges
1628 // without lifting, it should start changing sound again.
1629 TEST_F(TouchExplorationTest, TestingBoundaries) {
1630   SwitchTouchExplorationMode(true);
1631
1632   gfx::Rect window = BoundsOfRootWindowInDIP();
1633   gfx::Point initial_press(window.right() - GetMaxDistanceFromEdge() / 2, 1);
1634
1635   gfx::Point center_screen(window.right() / 2, window.bottom() / 2);
1636
1637   ui::TouchEvent first_press(ui::ET_TOUCH_PRESSED, initial_press, 0, Now());
1638   generator_->Dispatch(&first_press);
1639   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1640   EXPECT_FALSE(IsInGestureInProgressState());
1641   EXPECT_FALSE(IsInSlideGestureState());
1642   EXPECT_FALSE(IsInTouchToMouseMode());
1643
1644   // Move past the touch slop to begin slide gestures.
1645   // + slop + 1 to actually leave slop.
1646   gfx::Point touch_move(
1647       initial_press.x(),
1648       initial_press.y() + gesture_detector_config_.touch_slop + 1);
1649   generator_->MoveTouch(touch_move);
1650   EXPECT_FALSE(IsInGestureInProgressState());
1651   EXPECT_TRUE(IsInSlideGestureState());
1652   EXPECT_FALSE(IsInTouchToMouseMode());
1653   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(10));
1654
1655   // Move the touch into slop boundaries. It should still be in slide gestures
1656   // and adjust the volume.
1657   gfx::Point into_slop_boundaries(
1658       window.right() - GetSlopDistanceFromEdge() / 2, 1);
1659   generator_->MoveTouch(into_slop_boundaries);
1660   EXPECT_FALSE(IsInGestureInProgressState());
1661   EXPECT_TRUE(IsInSlideGestureState());
1662   EXPECT_FALSE(IsInTouchToMouseMode());
1663
1664   // The sound is rate limiting so it only activates every 150ms.
1665   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(200));
1666
1667   size_t num_adjust_sounds = delegate_.NumAdjustSounds();
1668   ASSERT_EQ(1U, num_adjust_sounds);
1669   ASSERT_EQ(1U, delegate_.VolumeChanges().size());
1670
1671   // Move the touch into the center of the window. It should still be in slide
1672   // gestures, but there should not be anymore volume adjustments.
1673   generator_->MoveTouch(center_screen);
1674   EXPECT_FALSE(IsInGestureInProgressState());
1675   EXPECT_TRUE(IsInSlideGestureState());
1676   EXPECT_FALSE(IsInTouchToMouseMode());
1677
1678   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(200));
1679   num_adjust_sounds = delegate_.NumAdjustSounds();
1680   ASSERT_EQ(1U, num_adjust_sounds);
1681   ASSERT_EQ(1U, delegate_.VolumeChanges().size());
1682
1683   // Move the touch back into slop edge distance and volume should be changing
1684   // again, one volume change for each new move.
1685   generator_->MoveTouch(into_slop_boundaries);
1686   EXPECT_FALSE(IsInGestureInProgressState());
1687   EXPECT_TRUE(IsInSlideGestureState());
1688   EXPECT_FALSE(IsInTouchToMouseMode());
1689
1690   generator_->MoveTouch(
1691       gfx::Point(into_slop_boundaries.x() + gesture_detector_config_.touch_slop,
1692                  into_slop_boundaries.y()));
1693   simulated_clock_->Advance(base::TimeDelta::FromMilliseconds(200));
1694
1695   num_adjust_sounds = delegate_.NumAdjustSounds();
1696   ASSERT_EQ(2U, num_adjust_sounds);
1697   ASSERT_EQ(3U, delegate_.VolumeChanges().size());
1698
1699   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1700   ASSERT_EQ(0U, captured_events.size());
1701
1702   generator_->ReleaseTouch();
1703 }
1704
1705 // Even if the gesture starts within bounds, if it has not moved past slop
1706 // within the grace period, it should go to touch exploration.
1707 TEST_F(TouchExplorationTest, InBoundariesTouchExploration) {
1708   SwitchTouchExplorationMode(true);
1709
1710   gfx::Rect window = BoundsOfRootWindowInDIP();
1711   gfx::Point initial_press(window.right() - GetMaxDistanceFromEdge() / 2, 1);
1712   ui::TouchEvent first_press(
1713       ui::ET_TOUCH_PRESSED,
1714       initial_press,
1715       0,
1716       Now());
1717   generator_->Dispatch(&first_press);
1718   EXPECT_FALSE(IsInGestureInProgressState());
1719   EXPECT_FALSE(IsInSlideGestureState());
1720   EXPECT_FALSE(IsInTouchToMouseMode());
1721
1722   AdvanceSimulatedTimePastTapDelay();
1723   EXPECT_FALSE(IsInGestureInProgressState());
1724   EXPECT_FALSE(IsInSlideGestureState());
1725   EXPECT_TRUE(IsInTouchToMouseMode());
1726 }
1727
1728 // If two fingers tap the screen at the same time and release before the tap
1729 // timer runs out, a control key event should be sent to silence chromevox.
1730 TEST_F(TouchExplorationTest, TwoFingerTap) {
1731   SwitchTouchExplorationMode(true);
1732
1733   generator_->set_current_location(gfx::Point(101, 102));
1734   generator_->PressTouchId(1);
1735   EXPECT_FALSE(IsInTwoFingerTapState());
1736
1737   generator_->PressTouchId(2);
1738   EXPECT_TRUE(IsInTwoFingerTapState());
1739
1740   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1741   ASSERT_EQ(0U, captured_events.size());
1742
1743   generator_->ReleaseTouchId(1);
1744   EXPECT_TRUE(IsInTwoFingerTapState());
1745   generator_->ReleaseTouchId(2);
1746
1747   // Two key events should have been sent to silence the feedback.
1748   EXPECT_EQ(2U, captured_events.size());
1749 }
1750
1751 // If the fingers are not released before the tap timer runs out, a control
1752 // keyevent is not sent and the state will no longer be in two finger tap.
1753 TEST_F(TouchExplorationTest, TwoFingerTapAndHold) {
1754   SwitchTouchExplorationMode(true);
1755
1756   generator_->PressTouchId(1);
1757   EXPECT_FALSE(IsInTwoFingerTapState());
1758
1759   generator_->PressTouchId(2);
1760   EXPECT_TRUE(IsInTwoFingerTapState());
1761
1762   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1763   ASSERT_EQ(0U, captured_events.size());
1764
1765   AdvanceSimulatedTimePastTapDelay();
1766   // Since the tap delay has elapsed, it should no longer be in two finger tap.
1767   EXPECT_FALSE(IsInTwoFingerTapState());
1768 }
1769
1770 // The next two tests set up two finger swipes to happen. If one of the fingers
1771 // moves out of slop before the tap timer fires, a two finger tap is not made.
1772 // In this first test, the first finger placed will move out of slop.
1773 TEST_F(TouchExplorationTest, TwoFingerTapAndMoveFirstFinger) {
1774   SwitchTouchExplorationMode(true);
1775
1776   // Once one of the fingers leaves slop, it should no longer be in two finger
1777   // tap.
1778   ui::TouchEvent first_press_id_1(
1779       ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), 1, Now());
1780   ui::TouchEvent first_press_id_2(
1781       ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), 2, Now());
1782
1783   ui::TouchEvent slop_move_id_1(
1784       ui::ET_TOUCH_MOVED,
1785       gfx::Point(100 + gesture_detector_config_.touch_slop, 200),
1786       1,
1787       Now());
1788   ui::TouchEvent slop_move_id_2(
1789       ui::ET_TOUCH_MOVED,
1790       gfx::Point(110 + gesture_detector_config_.touch_slop, 200),
1791       2,
1792       Now());
1793
1794   ui::TouchEvent out_slop_id_1(
1795       ui::ET_TOUCH_MOVED,
1796       gfx::Point(100 + gesture_detector_config_.touch_slop + 1, 200),
1797       1,
1798       Now());
1799
1800   // Dispatch the inital presses.
1801   generator_->Dispatch(&first_press_id_1);
1802   EXPECT_FALSE(IsInTwoFingerTapState());
1803   generator_->Dispatch(&first_press_id_2);
1804   EXPECT_TRUE(IsInTwoFingerTapState());
1805
1806   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1807   ASSERT_EQ(0U, captured_events.size());
1808
1809   // The presses have not moved out of slop yet so it should still be in
1810   // TwoFingerTap.
1811   generator_->Dispatch(&slop_move_id_1);
1812   EXPECT_TRUE(IsInTwoFingerTapState());
1813   generator_->Dispatch(&slop_move_id_2);
1814   EXPECT_TRUE(IsInTwoFingerTapState());
1815
1816   // Once one of the fingers moves out of slop, we are no longer in
1817   // TwoFingerTap.
1818   generator_->Dispatch(&out_slop_id_1);
1819   EXPECT_FALSE(IsInTwoFingerTapState());
1820 }
1821
1822 // Similar test to the previous test except the second finger placed will be the
1823 // one to move out of slop.
1824 TEST_F(TouchExplorationTest, TwoFingerTapAndMoveSecondFinger) {
1825   SwitchTouchExplorationMode(true);
1826
1827   // Once one of the fingers leaves slop, it should no longer be in two finger
1828   // tap.
1829   ui::TouchEvent first_press_id_1(
1830       ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), 1, Now());
1831   ui::TouchEvent first_press_id_2(
1832       ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), 2, Now());
1833
1834   ui::TouchEvent out_slop_id_2(
1835       ui::ET_TOUCH_MOVED,
1836       gfx::Point(100 + gesture_detector_config_.touch_slop + 1, 200),
1837       1,
1838       Now());
1839
1840   generator_->Dispatch(&first_press_id_1);
1841   EXPECT_FALSE(IsInTwoFingerTapState());
1842
1843   generator_->Dispatch(&first_press_id_2);
1844   EXPECT_TRUE(IsInTwoFingerTapState());
1845
1846   const ScopedVector<ui::Event>& captured_events = GetCapturedEvents();
1847   ASSERT_EQ(0U, captured_events.size());
1848
1849   generator_->Dispatch(&out_slop_id_2);
1850   EXPECT_FALSE(IsInTwoFingerTapState());
1851 }
1852
1853 // Corner passthrough should turn on if the user first holds down on either the
1854 // right or left corner past a delay and then places a finger anywhere else on
1855 // the screen.
1856 TEST_F(TouchExplorationTest, ActivateLeftCornerPassthrough) {
1857   SwitchTouchExplorationMode(true);
1858
1859   gfx::Rect window = BoundsOfRootWindowInDIP();
1860   gfx::Point left_corner(10, window.bottom() - GetMaxDistanceFromEdge() / 2);
1861   AssertCornerPassthroughWorking(left_corner);
1862 }
1863
1864 TEST_F(TouchExplorationTest, ActivateRightCornerPassthrough) {
1865   SwitchTouchExplorationMode(true);
1866
1867   gfx::Rect window = BoundsOfRootWindowInDIP();
1868   gfx::Point right_corner(window.right() - GetMaxDistanceFromEdge() / 2,
1869                           window.bottom() - GetMaxDistanceFromEdge() / 2);
1870   AssertCornerPassthroughWorking(right_corner);
1871 }
1872
1873 // Earcons should play if the user slides off the screen or enters the screen
1874 // from the edge.
1875 TEST_F(TouchExplorationTest, EnterEarconPlays) {
1876   SwitchTouchExplorationMode(true);
1877
1878   gfx::Rect window = BoundsOfRootWindowInDIP();
1879
1880   gfx::Point upper_left_corner(0, 0);
1881   gfx::Point upper_right_corner(window.right(), 0);
1882   gfx::Point lower_left_corner(0, window.bottom());
1883   gfx::Point lower_right_corner(window.right(), window.bottom());
1884   gfx::Point left_edge(0, 30);
1885   gfx::Point right_edge(window.right(), 30);
1886   gfx::Point top_edge(30, 0);
1887   gfx::Point bottom_edge(30, window.bottom());
1888
1889   std::vector<gfx::Point> locations;
1890   locations.push_back(upper_left_corner);
1891   locations.push_back(upper_right_corner);
1892   locations.push_back(lower_left_corner);
1893   locations.push_back(lower_right_corner);
1894   locations.push_back(left_edge);
1895   locations.push_back(right_edge);
1896   locations.push_back(top_edge);
1897   locations.push_back(bottom_edge);
1898
1899   for (std::vector<gfx::Point>::const_iterator point = locations.begin();
1900        point != locations.end();
1901        ++point) {
1902     ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, *point, 1, Now());
1903
1904     generator_->Dispatch(&touch_event);
1905     ASSERT_EQ(1U, delegate_.NumEnterScreenSounds());
1906     generator_->ReleaseTouchId(1);
1907     delegate_.ResetCountersToZero();
1908   }
1909 }
1910
1911 TEST_F(TouchExplorationTest, ExitEarconPlays) {
1912   SwitchTouchExplorationMode(true);
1913
1914   // On the device, it cannot actually tell if the finger has left the screen or
1915   // not. If the finger has left the screen, it reads it as a release that
1916   // occurred very close to the edge of the screen even if the finger is still
1917   // technically touching the moniter. To simulate this, a release that occurs
1918   // close to the edge is dispatched.
1919   gfx::Point initial_press(100, 200);
1920   gfx::Rect window = BoundsOfRootWindowInDIP();
1921
1922   gfx::Point upper_left_corner(0, 0);
1923   gfx::Point upper_right_corner(window.right(), 0);
1924   gfx::Point lower_left_corner(0, window.bottom());
1925   gfx::Point lower_right_corner(window.right(), window.bottom());
1926   gfx::Point left_edge(0, 30);
1927   gfx::Point right_edge(window.right(), 30);
1928   gfx::Point top_edge(30, 0);
1929   gfx::Point bottom_edge(30, window.bottom());
1930
1931   std::vector<gfx::Point> locations;
1932   locations.push_back(upper_left_corner);
1933   locations.push_back(upper_right_corner);
1934   locations.push_back(lower_left_corner);
1935   locations.push_back(lower_right_corner);
1936   locations.push_back(left_edge);
1937   locations.push_back(right_edge);
1938   locations.push_back(top_edge);
1939   locations.push_back(bottom_edge);
1940
1941   for (std::vector<gfx::Point>::const_iterator point = locations.begin();
1942        point != locations.end();
1943        ++point) {
1944     generator_->PressTouch();
1945     generator_->MoveTouch(initial_press);
1946     generator_->MoveTouch(*point);
1947     generator_->ReleaseTouch();
1948     ASSERT_EQ(1U, delegate_.NumExitScreenSounds());
1949     delegate_.ResetCountersToZero();
1950   }
1951 }
1952
1953 }  // namespace ui