Sends NetworkChangeNotifier connection type changes to Blink, to support NetInfo v3.
[chromium-blink-merge.git] / ash / autoclick / autoclick_unittest.cc
blobff387aad9f0f914de4da40db0084e41abe517795
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/autoclick/autoclick_controller.h"
6 #include "ash/shell.h"
7 #include "ash/test/ash_test_base.h"
8 #include "ui/aura/test/event_generator.h"
9 #include "ui/aura/test/test_window_delegate.h"
10 #include "ui/aura/window.h"
11 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/events/event.h"
13 #include "ui/events/event_constants.h"
14 #include "ui/events/event_handler.h"
15 #include "ui/events/keycodes/keyboard_codes.h"
17 namespace ash {
19 class MouseEventCapturer : public ui::EventHandler {
20 public:
21 MouseEventCapturer() { Reset(); }
22 virtual ~MouseEventCapturer() {}
24 void Reset() {
25 events_.clear();
28 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
29 if (!(event->flags() & ui::EF_LEFT_MOUSE_BUTTON))
30 return;
31 // Filter out extraneous mouse events like mouse entered, exited,
32 // capture changed, etc.
33 ui::EventType type = event->type();
34 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_PRESSED ||
35 type == ui::ET_MOUSE_RELEASED) {
36 events_.push_back(ui::MouseEvent(
37 event->type(),
38 event->location(),
39 event->root_location(),
40 event->flags(),
41 event->changed_button_flags()));
42 // Stop event propagation so we don't click on random stuff that
43 // might break test assumptions.
44 event->StopPropagation();
47 // If there is a possibility that we're in an infinite loop, we should
48 // exit early with a sensible error rather than letting the test time out.
49 ASSERT_LT(events_.size(), 100u);
52 const std::vector<ui::MouseEvent>& captured_events() const {
53 return events_;
56 private:
57 std::vector<ui::MouseEvent> events_;
59 DISALLOW_COPY_AND_ASSIGN(MouseEventCapturer);
62 class AutoclickTest : public test::AshTestBase {
63 public:
64 AutoclickTest() {}
65 virtual ~AutoclickTest() {}
67 virtual void SetUp() OVERRIDE {
68 test::AshTestBase::SetUp();
69 Shell::GetInstance()->AddPreTargetHandler(&mouse_event_capturer_);
70 GetAutoclickController()->SetAutoclickDelay(0);
72 // Move mouse to deterministic location at the start of each test.
73 GetEventGenerator().MoveMouseTo(100, 100);
76 virtual void TearDown() OVERRIDE {
77 Shell::GetInstance()->RemovePreTargetHandler(&mouse_event_capturer_);
78 test::AshTestBase::TearDown();
81 void MoveMouseWithFlagsTo(int x, int y, ui::EventFlags flags) {
82 GetEventGenerator().set_flags(flags);
83 GetEventGenerator().MoveMouseTo(x, y);
84 GetEventGenerator().set_flags(ui::EF_NONE);
87 const std::vector<ui::MouseEvent>& WaitForMouseEvents() {
88 mouse_event_capturer_.Reset();
89 RunAllPendingInMessageLoop();
90 return mouse_event_capturer_.captured_events();
93 AutoclickController* GetAutoclickController() {
94 return Shell::GetInstance()->autoclick_controller();
97 private:
98 MouseEventCapturer mouse_event_capturer_;
100 DISALLOW_COPY_AND_ASSIGN(AutoclickTest);
103 TEST_F(AutoclickTest, ToggleEnabled) {
104 std::vector<ui::MouseEvent> events;
106 // We should not see any events initially.
107 EXPECT_FALSE(GetAutoclickController()->IsEnabled());
108 events = WaitForMouseEvents();
109 EXPECT_EQ(0u, events.size());
111 // Enable autoclick, and we should see a mouse pressed and
112 // a mouse released event, simulating a click.
113 GetAutoclickController()->SetEnabled(true);
114 GetEventGenerator().MoveMouseTo(0, 0);
115 EXPECT_TRUE(GetAutoclickController()->IsEnabled());
116 events = WaitForMouseEvents();
117 EXPECT_EQ(2u, events.size());
118 EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
119 EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
121 // We should not get any more clicks until we move the mouse.
122 events = WaitForMouseEvents();
123 EXPECT_EQ(0u, events.size());
124 GetEventGenerator().MoveMouseTo(30, 30);
125 events = WaitForMouseEvents();
126 EXPECT_EQ(2u, events.size());
127 EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
128 EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
130 // Disable autoclick, and we should see the original behaviour.
131 GetAutoclickController()->SetEnabled(false);
132 EXPECT_FALSE(GetAutoclickController()->IsEnabled());
133 events = WaitForMouseEvents();
134 EXPECT_EQ(0u, events.size());
137 TEST_F(AutoclickTest, MouseMovement) {
138 std::vector<ui::MouseEvent> events;
139 GetAutoclickController()->SetEnabled(true);
141 gfx::Point p1(0, 0);
142 gfx::Point p2(20, 20);
143 gfx::Point p3(40, 40);
145 // Move mouse to p1.
146 GetEventGenerator().MoveMouseTo(p1);
147 events = WaitForMouseEvents();
148 EXPECT_EQ(2u, events.size());
149 EXPECT_EQ(p1.ToString(), events[0].root_location().ToString());
150 EXPECT_EQ(p1.ToString(), events[1].root_location().ToString());
152 // Move mouse to multiple locations and finally arrive at p3.
153 GetEventGenerator().MoveMouseTo(p2);
154 GetEventGenerator().MoveMouseTo(p1);
155 GetEventGenerator().MoveMouseTo(p3);
156 events = WaitForMouseEvents();
157 EXPECT_EQ(2u, events.size());
158 EXPECT_EQ(p3.ToString(), events[0].root_location().ToString());
159 EXPECT_EQ(p3.ToString(), events[1].root_location().ToString());
162 TEST_F(AutoclickTest, MovementThreshold) {
163 GetAutoclickController()->SetEnabled(true);
164 GetEventGenerator().MoveMouseTo(0, 0);
165 EXPECT_EQ(2u, WaitForMouseEvents().size());
167 // Small mouse movements should not trigger an autoclick.
168 GetEventGenerator().MoveMouseTo(1, 1);
169 EXPECT_EQ(0u, WaitForMouseEvents().size());
170 GetEventGenerator().MoveMouseTo(2, 2);
171 EXPECT_EQ(0u, WaitForMouseEvents().size());
172 GetEventGenerator().MoveMouseTo(0, 0);
173 EXPECT_EQ(0u, WaitForMouseEvents().size());
175 // A large mouse movement should trigger an autoclick.
176 GetEventGenerator().MoveMouseTo(100, 100);
177 EXPECT_EQ(2u, WaitForMouseEvents().size());
180 TEST_F(AutoclickTest, SingleKeyModifier) {
181 GetAutoclickController()->SetEnabled(true);
182 MoveMouseWithFlagsTo(20, 20, ui::EF_SHIFT_DOWN);
183 std::vector<ui::MouseEvent> events = WaitForMouseEvents();
184 EXPECT_EQ(2u, events.size());
185 EXPECT_EQ(ui::EF_SHIFT_DOWN, events[0].flags() & ui::EF_SHIFT_DOWN);
186 EXPECT_EQ(ui::EF_SHIFT_DOWN, events[1].flags() & ui::EF_SHIFT_DOWN);
189 TEST_F(AutoclickTest, MultipleKeyModifiers) {
190 GetAutoclickController()->SetEnabled(true);
191 ui::EventFlags modifier_flags = static_cast<ui::EventFlags>(
192 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
193 MoveMouseWithFlagsTo(30, 30, modifier_flags);
194 std::vector<ui::MouseEvent> events = WaitForMouseEvents();
195 EXPECT_EQ(2u, events.size());
196 EXPECT_EQ(modifier_flags, events[0].flags() & modifier_flags);
197 EXPECT_EQ(modifier_flags, events[1].flags() & modifier_flags);
200 TEST_F(AutoclickTest, KeyModifiersReleased) {
201 GetAutoclickController()->SetEnabled(true);
203 ui::EventFlags modifier_flags = static_cast<ui::EventFlags>(
204 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
205 MoveMouseWithFlagsTo(12, 12, modifier_flags);
207 // Simulate releasing key modifiers by sending key released events.
208 GetEventGenerator().ReleaseKey(ui::VKEY_CONTROL,
209 static_cast<ui::EventFlags>(ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN));
210 GetEventGenerator().ReleaseKey(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
212 std::vector<ui::MouseEvent> events;
213 events = WaitForMouseEvents();
214 EXPECT_EQ(2u, events.size());
215 EXPECT_EQ(0, events[0].flags() & ui::EF_CONTROL_DOWN);
216 EXPECT_EQ(0, events[0].flags() & ui::EF_SHIFT_DOWN);
217 EXPECT_EQ(ui::EF_ALT_DOWN, events[0].flags() & ui::EF_ALT_DOWN);
220 TEST_F(AutoclickTest, ExtendedDisplay) {
221 UpdateDisplay("1280x1024,800x600");
222 RunAllPendingInMessageLoop();
223 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
224 EXPECT_EQ(2u, root_windows.size());
226 GetAutoclickController()->SetEnabled(true);
227 std::vector<ui::MouseEvent> events;
229 // Test first root window.
230 aura::test::EventGenerator generator1(root_windows[0]);
231 generator1.MoveMouseTo(100, 200);
232 events = WaitForMouseEvents();
233 EXPECT_EQ(2u, events.size());
234 EXPECT_EQ(100, events[0].root_location().x());
235 EXPECT_EQ(200, events[0].root_location().y());
237 // Test second root window.
238 aura::test::EventGenerator generator2(root_windows[1]);
239 generator2.MoveMouseTo(300, 400);
240 events = WaitForMouseEvents();
241 EXPECT_EQ(2u, events.size());
242 EXPECT_EQ(300, events[0].root_location().x());
243 EXPECT_EQ(400, events[0].root_location().y());
245 // Test movement threshold between displays.
248 TEST_F(AutoclickTest, UserInputCancelsAutoclick) {
249 GetAutoclickController()->SetEnabled(true);
250 std::vector<ui::MouseEvent> events;
252 // Pressing a normal key should cancel the autoclick.
253 GetEventGenerator().MoveMouseTo(200, 200);
254 GetEventGenerator().PressKey(ui::VKEY_K, ui::EF_NONE);
255 GetEventGenerator().ReleaseKey(ui::VKEY_K, ui::EF_NONE);
256 events = WaitForMouseEvents();
257 EXPECT_EQ(0u, events.size());
259 // Pressing a modifier key should NOT cancel the autoclick.
260 GetEventGenerator().MoveMouseTo(100, 100);
261 GetEventGenerator().PressKey(ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
262 GetEventGenerator().ReleaseKey(ui::VKEY_SHIFT, ui::EF_NONE);
263 events = WaitForMouseEvents();
264 EXPECT_EQ(2u, events.size());
266 // Performing a gesture should cancel the autoclick.
267 GetEventGenerator().MoveMouseTo(200, 200);
268 GetEventGenerator().GestureTapDownAndUp(gfx::Point(100, 100));
269 events = WaitForMouseEvents();
270 EXPECT_EQ(0u, events.size());
272 // Test another gesture.
273 GetEventGenerator().MoveMouseTo(100, 100);
274 GetEventGenerator().GestureScrollSequence(
275 gfx::Point(100, 100),
276 gfx::Point(200, 200),
277 base::TimeDelta::FromMilliseconds(200),
279 events = WaitForMouseEvents();
280 EXPECT_EQ(0u, events.size());
282 // Test scroll events.
283 GetEventGenerator().MoveMouseTo(200, 200);
284 GetEventGenerator().ScrollSequence(
285 gfx::Point(100, 100), base::TimeDelta::FromMilliseconds(200),
286 0, 100, 3, 2);
287 events = WaitForMouseEvents();
288 EXPECT_EQ(0u, events.size());
291 TEST_F(AutoclickTest, SynthesizedMouseMovesIgnored) {
292 GetAutoclickController()->SetEnabled(true);
293 std::vector<ui::MouseEvent> events;
294 GetEventGenerator().MoveMouseTo(100, 100);
295 events = WaitForMouseEvents();
296 EXPECT_EQ(2u, events.size());
298 // Show a window and make sure the new window is under the cursor. As a
299 // result, synthesized mouse events will be dispatched to the window, but it
300 // should not trigger an autoclick.
301 aura::test::EventCountDelegate delegate;
302 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
303 &delegate, 123, gfx::Rect(50, 50, 100, 100)));
304 window->Show();
305 events = WaitForMouseEvents();
306 EXPECT_EQ(0u, events.size());
307 EXPECT_EQ("1 1 0", delegate.GetMouseMotionCountsAndReset());
310 } // namespace ash