14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/autoclick/autoclick_controller.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/shell.h"
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/test/ash_test_base.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/aura/window.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/event.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/event_constants.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/event_handler.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace ash {
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class MouseEventCapturer : public ui::EventHandler {
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MouseEventCapturer() { Reset(); }
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~MouseEventCapturer() {}
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Reset() {
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    events_.clear();
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!(event->flags() & ui::EF_LEFT_MOUSE_BUTTON))
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Filter out extraneous mouse events like mouse entered, exited,
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // capture changed, etc.
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ui::EventType type = event->type();
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_PRESSED ||
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        type == ui::ET_MOUSE_RELEASED) {
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      events_.push_back(ui::MouseEvent(
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          event->type(),
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          event->location(),
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          event->root_location(),
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          event->flags(),
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          event->changed_button_flags()));
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Stop event propagation so we don't click on random stuff that
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // might break test assumptions.
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      event->StopPropagation();
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If there is a possibility that we're in an infinite loop, we should
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // exit early with a sensible error rather than letting the test time out.
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_LT(events_.size(), 100u);
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const std::vector<ui::MouseEvent>& captured_events() const {
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return events_;
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events_;
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MouseEventCapturer);
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class AutoclickTest : public test::AshTestBase {
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AutoclickTest() {}
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~AutoclickTest() {}
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    test::AshTestBase::SetUp();
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Shell::GetInstance()->AddPreTargetHandler(&mouse_event_capturer_);
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    GetAutoclickController()->SetAutoclickDelay(0);
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Move mouse to deterministic location at the start of each test.
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GetEventGenerator().MoveMouseTo(100, 100);
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Shell::GetInstance()->RemovePreTargetHandler(&mouse_event_capturer_);
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    test::AshTestBase::TearDown();
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void MoveMouseWithFlagsTo(int x, int y, ui::EventFlags flags) {
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GetEventGenerator().set_flags(flags);
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GetEventGenerator().MoveMouseTo(x, y);
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GetEventGenerator().set_flags(ui::EF_NONE);
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const std::vector<ui::MouseEvent>& WaitForMouseEvents() {
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    mouse_event_capturer_.Reset();
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RunAllPendingInMessageLoop();
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return mouse_event_capturer_.captured_events();
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AutoclickController* GetAutoclickController() {
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return Shell::GetInstance()->autoclick_controller();
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MouseEventCapturer mouse_event_capturer_;
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AutoclickTest);
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(AutoclickTest, ToggleEnabled) {
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events;
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We should not see any events initially.
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(GetAutoclickController()->IsEnabled());
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0u, events.size());
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Enable autoclick, and we should see a mouse pressed and
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // a mouse released event, simulating a click.
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().MoveMouseTo(0, 0);
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(GetAutoclickController()->IsEnabled());
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We should not get any more clicks until we move the mouse.
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0u, events.size());
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(30, 30);
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Disable autoclick, and we should see the original behaviour.
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(false);
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(GetAutoclickController()->IsEnabled());
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0u, events.size());
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(AutoclickTest, MouseMovement) {
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events;
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Point p1(0, 0);
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Point p2(20, 20);
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Point p3(40, 40);
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Move mouse to p1.
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().MoveMouseTo(p1);
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(p1.ToString(), events[0].root_location().ToString());
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(p1.ToString(), events[1].root_location().ToString());
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Move mouse to multiple locations and finally arrive at p3.
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().MoveMouseTo(p2);
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().MoveMouseTo(p1);
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().MoveMouseTo(p3);
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(p3.ToString(), events[0].root_location().ToString());
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(p3.ToString(), events[1].root_location().ToString());
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(AutoclickTest, MovementThreshold) {
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(0, 0);
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2u, WaitForMouseEvents().size());
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Small mouse movements should not trigger an autoclick.
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(1, 1);
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, WaitForMouseEvents().size());
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(2, 2);
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, WaitForMouseEvents().size());
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(0, 0);
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, WaitForMouseEvents().size());
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // A large mouse movement should trigger an autoclick.
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(100, 100);
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2u, WaitForMouseEvents().size());
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(AutoclickTest, SingleKeyModifier) {
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MoveMouseWithFlagsTo(20, 20, ui::EF_SHIFT_DOWN);
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events = WaitForMouseEvents();
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::EF_SHIFT_DOWN, events[0].flags() & ui::EF_SHIFT_DOWN);
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::EF_SHIFT_DOWN, events[1].flags() & ui::EF_SHIFT_DOWN);
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(AutoclickTest, MultipleKeyModifiers) {
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::EventFlags modifier_flags = static_cast<ui::EventFlags>(
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MoveMouseWithFlagsTo(30, 30, modifier_flags);
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events = WaitForMouseEvents();
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(modifier_flags, events[0].flags() & modifier_flags);
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(modifier_flags, events[1].flags() & modifier_flags);
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(AutoclickTest, KeyModifiersReleased) {
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::EventFlags modifier_flags = static_cast<ui::EventFlags>(
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MoveMouseWithFlagsTo(12, 12, modifier_flags);
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Simulate releasing key modifiers by sending key released events.
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().ReleaseKey(ui::VKEY_CONTROL,
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      static_cast<ui::EventFlags>(ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN));
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetEventGenerator().ReleaseKey(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events;
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, events[0].flags() & ui::EF_CONTROL_DOWN);
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, events[0].flags() & ui::EF_SHIFT_DOWN);
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ui::EF_ALT_DOWN, events[0].flags() & ui::EF_ALT_DOWN);
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(AutoclickTest, ExtendedDisplay) {
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateDisplay("1280x1024,800x600");
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RunAllPendingInMessageLoop();
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, root_windows.size());
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<ui::MouseEvent> events;
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Test first root window.
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator1(root_windows[0]);
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator1.MoveMouseTo(100, 200);
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(100, events[0].root_location().x());
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(200, events[0].root_location().y());
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Test second root window.
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator2(root_windows[1]);
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator2.MoveMouseTo(300, 400);
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  events = WaitForMouseEvents();
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(2u, events.size());
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(300, events[0].root_location().x());
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(400, events[0].root_location().y());
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Test movement threshold between displays.
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(AutoclickTest, UserInputCancelsAutoclick) {
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<ui::MouseEvent> events;
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Pressing a normal key should cancel the autoclick.
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(200, 200);
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().PressKey(ui::VKEY_K, ui::EF_NONE);
2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().ReleaseKey(ui::VKEY_K, ui::EF_NONE);
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  events = WaitForMouseEvents();
2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, events.size());
2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Pressing a modifier key should NOT cancel the autoclick.
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(100, 100);
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().PressKey(ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().ReleaseKey(ui::VKEY_SHIFT, ui::EF_NONE);
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  events = WaitForMouseEvents();
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2u, events.size());
2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Performing a gesture should cancel the autoclick.
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(200, 200);
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().GestureTapDownAndUp(gfx::Point(100, 100));
2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  events = WaitForMouseEvents();
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, events.size());
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Test another gesture.
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(100, 100);
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().GestureScrollSequence(
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gfx::Point(100, 100),
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gfx::Point(200, 200),
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(200),
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      3);
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  events = WaitForMouseEvents();
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, events.size());
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Test scroll events.
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(200, 200);
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetEventGenerator().ScrollSequence(
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gfx::Point(100, 100), base::TimeDelta::FromMilliseconds(200),
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      0, 100, 3, 2);
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  events = WaitForMouseEvents();
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, events.size());
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(AutoclickTest, SynthesizedMouseMovesIgnored) {
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetAutoclickController()->SetEnabled(true);
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<ui::MouseEvent> events;
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(100, 100);
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  events = WaitForMouseEvents();
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2u, events.size());
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Show a window and make sure the new window is under the cursor. As a
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // result, synthesized mouse events will be dispatched to the window, but it
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // should not trigger an autoclick.
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::test::EventCountDelegate delegate;
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &delegate, 123, gfx::Rect(50, 50, 100, 100)));
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Show();
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  events = WaitForMouseEvents();
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, events.size());
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("1 1 0", delegate.GetMouseMotionCountsAndReset());
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace ash
311