Home | History | Annotate | Download | only in chromeos
      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   const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; }
     98   const size_t NumPassthroughSounds() { return num_times_passthrough_played_; }
     99   const size_t NumExitScreenSounds() { return num_times_exit_screen_played_; }
    100   const 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
   1954